xref: /OK3568_Linux_fs/u-boot/drivers/rkflash/rkflash_api.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 
10 #include "rkflash_api.h"
11 #include "rkflash_blk.h"
12 #include "rkflash_debug.h"
13 
14 #ifdef CONFIG_RKSFC_NOR
15 
16 #define IDB_ALIGN_64			128	/* 64 KB */
17 #define IDB_ALIGN_32			64	/* 32 KB */
18 
P_RC4(u8 * buf,u16 len)19 static void P_RC4(u8 *buf, u16 len)
20 {
21 	u8 S[256], K[256], temp;
22 	u16 i, j, t, x;
23 	u8 key[16] = {124, 78, 3, 4, 85, 5, 9, 7,
24 		      45, 44, 123, 56, 23, 13, 23, 17};
25 
26 	j = 0;
27 	for (i = 0; i < 256; i++) {
28 		S[i] = (u8)i;
29 		j &= 0x0f;
30 		K[i] = key[j];
31 		j++;
32 	}
33 
34 	j = 0;
35 	for (i = 0; i < 256; i++) {
36 		j = (j + S[i] + K[i]) % 256;
37 		temp = S[i];
38 		S[i] = S[j];
39 		S[j] = temp;
40 	}
41 
42 	i = 0;
43 	j = 0;
44 	for (x = 0; x < len; x++) {
45 		i = (i + 1) % 256;
46 		j = (j + S[i]) % 256;
47 		temp = S[i];
48 		S[i] = S[j];
49 		S[j] = temp;
50 		t = (S[i] + (S[j] % 256)) % 256;
51 		buf[x] = buf[x] ^ S[t];
52 	}
53 }
54 
rksfc_nor_init(struct udevice * udev)55 int rksfc_nor_init(struct udevice *udev)
56 {
57 	struct rkflash_info *priv = dev_get_priv(udev);
58 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
59 	struct snor_info_packet *packet;
60 	struct id_block_tag *idb_tag;
61 	int ret;
62 
63 	ret = snor_init(p_dev);
64 	if (ret == SFC_OK && p_dev->read_lines == DATA_LINES_X1) {
65 		idb_tag = kzalloc(NOR_SECS_PAGE * 512, GFP_KERNEL);
66 		if (!idb_tag)
67 			return SFC_OK;
68 
69 		if (sfc_get_version() >= SFC_VER_4)
70 			snor_read(p_dev, IDB_ALIGN_32, NOR_SECS_PAGE,
71 				  idb_tag);
72 		else
73 			snor_read(p_dev, IDB_ALIGN_64, NOR_SECS_PAGE,
74 				  idb_tag);
75 		packet = (struct snor_info_packet *)&idb_tag->dev_param[0];
76 		if (idb_tag->id == IDB_BLOCK_TAG_ID) {
77 			P_RC4((u8 *)idb_tag, sizeof(struct id_block_tag));
78 			snor_reinit_from_table_packet(p_dev, packet);
79 			rkflash_print_error("snor reinit, ret= %d\n", ret);
80 		}
81 		kfree(idb_tag);
82 	}
83 
84 	return ret;
85 }
86 
rksfc_nor_get_capacity(struct udevice * udev)87 u32 rksfc_nor_get_capacity(struct udevice *udev)
88 {
89 	struct rkflash_info *priv = dev_get_priv(udev);
90 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
91 
92 	return snor_get_capacity(p_dev);
93 }
94 
rksfc_nor_read(struct udevice * udev,u32 sec,u32 n_sec,void * p_data)95 int rksfc_nor_read(struct udevice *udev, u32 sec, u32 n_sec, void *p_data)
96 {
97 	u32 ret;
98 	u32 offset, count = 0;
99 	char *buf = (char *)p_data;
100 	struct rkflash_info *priv = dev_get_priv(udev);
101 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
102 
103 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
104 	    sec > FLASH_VENDOR_PART_END) {
105 		ret = snor_read(p_dev, sec, n_sec, p_data);
106 		if (ret != n_sec)
107 			return ret;
108 	} else {
109 		memset(p_data, 0, 512 * n_sec);
110 		if (sec < FLASH_VENDOR_PART_START) {
111 			count = FLASH_VENDOR_PART_START - sec;
112 			buf = (char *)p_data;
113 			ret = snor_read(p_dev, sec, count, buf);
114 			if (ret != count)
115 				return ret;
116 		}
117 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
118 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
119 			offset = FLASH_VENDOR_PART_END - sec + 1;
120 			buf = (char *)p_data + offset * 512;
121 			ret = snor_read(p_dev,
122 					FLASH_VENDOR_PART_END + 1,
123 					count, buf);
124 			if (ret != count)
125 				return ret;
126 		}
127 	}
128 
129 	return n_sec;
130 }
131 
132 /* Workaround for GPT not aligned program */
rksfc_nor_simply_over_write(struct udevice * udev,u32 sec,u32 n_sec,const void * p_data)133 int rksfc_nor_simply_over_write(struct udevice *udev,
134 				u32 sec,
135 				u32 n_sec,
136 				const void *p_data)
137 {
138 	struct rkflash_info *priv = dev_get_priv(udev);
139 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
140 	u8 *pbuf_temp;
141 	u32 addr_aligned, offset, remain;
142 
143 	addr_aligned = sec / NOR_SECS_PAGE * NOR_SECS_PAGE;
144 	offset = sec - addr_aligned;
145 	remain = (offset + n_sec + NOR_SECS_PAGE - 1) / NOR_SECS_PAGE * NOR_SECS_PAGE;
146 
147 	pbuf_temp = malloc(remain * 512);
148 	snor_read(p_dev, addr_aligned, remain, pbuf_temp);
149 	memcpy(pbuf_temp + offset * 512, p_data, n_sec * 512);
150 	snor_write(p_dev, addr_aligned, remain, pbuf_temp);
151 	free(pbuf_temp);
152 
153 	return n_sec;
154 }
155 
rksfc_nor_write(struct udevice * udev,u32 sec,u32 n_sec,const void * p_data)156 int rksfc_nor_write(struct udevice *udev,
157 		    u32 sec,
158 		    u32 n_sec,
159 		    const void *p_data)
160 {
161 	u32 ret;
162 	u32 offset, count = 0;
163 	char *buf = (char *)p_data;
164 	struct rkflash_info *priv = dev_get_priv(udev);
165 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
166 	u32 sfc_nor_density = rksfc_nor_get_capacity(udev);
167 
168 	if (sec >= (sfc_nor_density - 33))
169 		return rksfc_nor_simply_over_write(udev, sec, n_sec, p_data);
170 
171 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
172 	    sec > FLASH_VENDOR_PART_END) {
173 		ret = snor_write(p_dev, sec, n_sec, (void *)p_data);
174 		if (ret != n_sec)
175 			return ret;
176 	} else {
177 		if (sec < FLASH_VENDOR_PART_START) {
178 			count = FLASH_VENDOR_PART_START - sec;
179 			buf = (char *)p_data;
180 			ret = snor_write(p_dev, sec, count, buf);
181 			if (ret != count)
182 				return ret;
183 		}
184 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
185 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
186 			offset = FLASH_VENDOR_PART_END - sec + 1;
187 			buf = (char *)p_data + offset * 512;
188 			ret = snor_write(p_dev,
189 					 FLASH_VENDOR_PART_END + 1,
190 					 count, buf);
191 			if (ret != count)
192 				return ret;
193 		}
194 	}
195 
196 	return n_sec;
197 }
198 
rksfc_nor_vendor_read(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)199 int rksfc_nor_vendor_read(struct blk_desc *dev_desc,
200 			  u32 sec,
201 			  u32 n_sec,
202 			  void *p_data)
203 {
204 	struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent);
205 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
206 
207 	return snor_read(p_dev, sec, n_sec, p_data);
208 }
209 
rksfc_nor_vendor_write(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)210 int rksfc_nor_vendor_write(struct blk_desc *dev_desc,
211 			   u32 sec,
212 			   u32 n_sec,
213 			   void *p_data)
214 {
215 	struct rkflash_info *priv = dev_get_priv(dev_desc->bdev->parent);
216 	struct SFNOR_DEV *p_dev = (struct SFNOR_DEV *)&priv->flash_dev_info;
217 
218 	return snor_write(p_dev, sec, n_sec, p_data);
219 }
220 
221 #endif
222 
223 #ifdef CONFIG_RKSFC_NAND
rksfc_nand_init(struct udevice * udev)224 int rksfc_nand_init(struct udevice *udev)
225 {
226 	int ret;
227 
228 	ret = sfc_nand_init();
229 	if (ret) {
230 		return ret;
231 	} else {
232 		sfc_nand_ftl_ops_init();
233 
234 		return sftl_init();
235 	}
236 }
237 
rksfc_nand_read(struct udevice * udev,u32 index,u32 count,void * buf)238 int rksfc_nand_read(struct udevice *udev, u32 index, u32 count, void *buf)
239 {
240 	int ret;
241 
242 	ret = sftl_read(index, count, (u8 *)buf);
243 	if (!ret)
244 		return count;
245 	else
246 		return -EIO;
247 }
248 
rksfc_nand_write(struct udevice * udev,u32 index,u32 count,const void * buf)249 int rksfc_nand_write(struct udevice *udev,
250 		     u32 index,
251 		     u32 count,
252 		     const void *buf)
253 {
254 	int ret;
255 
256 	ret = sftl_write(index, count, (u8 *)buf);
257 	if (!ret)
258 		return count;
259 	else
260 		return -EIO;
261 }
262 
rksfc_nand_get_density(struct udevice * udev)263 u32 rksfc_nand_get_density(struct udevice *udev)
264 {
265 	return sftl_get_density();
266 }
267 
rksfc_nand_vendor_read(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)268 int rksfc_nand_vendor_read(struct blk_desc *dev_desc,
269 			   u32 sec,
270 			   u32 n_sec,
271 			   void *p_data)
272 {
273 	int ret;
274 
275 	ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data);
276 	if (!ret)
277 		return n_sec;
278 	else
279 		return -EIO;
280 }
281 
rksfc_nand_vendor_write(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)282 int rksfc_nand_vendor_write(struct blk_desc *dev_desc,
283 			    u32 sec,
284 			    u32 n_sec,
285 			    void *p_data)
286 {
287 	int ret;
288 
289 	ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data);
290 	if (!ret)
291 		return n_sec;
292 	else
293 		return -EIO;
294 }
295 
296 #endif
297 
298 #ifdef CONFIG_RKNANDC_NAND
rknand_flash_init(struct udevice * udev)299 int rknand_flash_init(struct udevice *udev)
300 {
301 	return sftl_init();
302 }
303 
rknand_flash_read(struct udevice * udev,u32 index,u32 count,void * buf)304 int rknand_flash_read(struct udevice *udev, u32 index, u32 count, void *buf)
305 {
306 	int ret;
307 
308 	ret = sftl_read(index, count, (u8 *)buf);
309 	if (!ret)
310 		return count;
311 	else
312 		return -EIO;
313 }
314 
rknand_flash_write(struct udevice * udev,u32 index,u32 count,const void * buf)315 int rknand_flash_write(struct udevice *udev,
316 		       u32 index,
317 		       u32 count,
318 		       const void *buf)
319 {
320 	int ret;
321 
322 	ret = sftl_write(index, count, (u8 *)buf);
323 	if (!ret)
324 		return count;
325 	else
326 		return -EIO;
327 }
328 
rknand_flash_get_density(struct udevice * udev)329 u32 rknand_flash_get_density(struct udevice *udev)
330 {
331 	return sftl_get_density();
332 }
333 
rknand_flash_vendor_read(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)334 int rknand_flash_vendor_read(struct blk_desc *dev_desc,
335 			     u32 sec,
336 			     u32 n_sec,
337 			     void *p_data)
338 {
339 	int ret;
340 
341 	ret = sftl_vendor_read(sec, n_sec, (u8 *)p_data);
342 	if (!ret)
343 		return n_sec;
344 	else
345 		return -EIO;
346 }
347 
rknand_flash_vendor_write(struct blk_desc * dev_desc,u32 sec,u32 n_sec,void * p_data)348 int rknand_flash_vendor_write(struct blk_desc *dev_desc,
349 			      u32 sec,
350 			      u32 n_sec,
351 			      void *p_data)
352 {
353 	int ret;
354 
355 	ret = sftl_vendor_write(sec, n_sec, (u8 *)p_data);
356 	if (!ret)
357 		return n_sec;
358 	else
359 		return -EIO;
360 }
361 
362 #endif
363