xref: /OK3568_Linux_fs/kernel/drivers/rkflash/nandc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */
4 
5 #include <linux/delay.h>
6 #include <linux/kernel.h>
7 
8 #include "flash.h"
9 #include "flash_com.h"
10 #include "nandc.h"
11 #include "rk_sftl.h"
12 
13 #define     CPU_DELAY_NS(n)	ndelay(n)
14 
15 #define	    NANDC_MASTER_EN
16 
17 void __iomem *nandc_base;
18 static u8 g_nandc_ver;
19 
20 static u32 g_nandc_ecc_bits;
21 #ifdef NANDC_MASTER_EN
22 static struct MASTER_INFO_T master;
23 static u32 *g_master_temp_buf;
24 #endif
25 
nandc_get_version(void)26 u8 nandc_get_version(void)
27 {
28 	return g_nandc_ver;
29 }
30 
nandc_init(void __iomem * nandc_addr)31 void nandc_init(void __iomem *nandc_addr)
32 {
33 	union FM_CTL_T ctl_reg;
34 
35 	nandc_base = nandc_addr;
36 
37 	ctl_reg.d32 = 0;
38 	g_nandc_ver = 6;
39 	if (nandc_readl(NANDC_V9_NANDC_VER) == RK3326_NANDC_VER)
40 		g_nandc_ver = 9;
41 	if (g_nandc_ver == 9) {
42 		ctl_reg.V9.wp = 1;
43 		ctl_reg.V9.sif_read_delay = 2;
44 		nandc_writel(ctl_reg.d32, NANDC_V9_FMCTL);
45 		nandc_writel(0, NANDC_V9_RANDMZ_CFG);
46 		nandc_writel(0x1041, NANDC_V9_FMWAIT);
47 	} else {
48 		ctl_reg.V6.wp = 1;
49 		nandc_writel(ctl_reg.d32, NANDC_FMCTL);
50 		nandc_writel(0, NANDC_RANDMZ_CFG);
51 		nandc_writel(0x1061, NANDC_FMWAIT);
52 	}
53 	nandc_time_cfg(40);
54 
55 #ifdef NANDC_MASTER_EN
56 	if (!g_master_temp_buf)
57 		g_master_temp_buf = (u32 *)ftl_malloc(MAX_FLASH_PAGE_SIZE +
58 					      MAX_FLASH_PAGE_SIZE / 8);
59 	master.page_buf = &g_master_temp_buf[0];
60 	master.spare_buf = &g_master_temp_buf[MAX_FLASH_PAGE_SIZE / 4];
61 	master.mapped = 0;
62 #endif
63 }
64 
nandc_flash_cs(u8 chip_sel)65 void nandc_flash_cs(u8 chip_sel)
66 {
67 	union FM_CTL_T tmp;
68 
69 	tmp.d32 = nandc_readl(NANDC_FMCTL);
70 	tmp.V6.cs = 0x01 << chip_sel;
71 	nandc_writel(tmp.d32, NANDC_FMCTL);
72 }
73 
nandc_flash_de_cs(u8 chip_sel)74 void nandc_flash_de_cs(u8 chip_sel)
75 {
76 	union FM_CTL_T tmp;
77 
78 	tmp.d32 = nandc_readl(NANDC_FMCTL);
79 	tmp.V6.cs = 0;
80 	tmp.V6.flash_abort_clear = 0;
81 	nandc_writel(tmp.d32, NANDC_FMCTL);
82 }
83 
nandc_delayns(u32 count)84 u32 nandc_delayns(u32 count)
85 {
86 	CPU_DELAY_NS(count);
87 	return 0;
88 }
89 
nandc_wait_flash_ready(u8 chip_sel)90 u32 nandc_wait_flash_ready(u8 chip_sel)
91 {
92 	union FM_CTL_T tmp;
93 	u32 status;
94 	u32 i;
95 
96 	status = 0;
97 	for (i = 0; i < 100000; i++) {
98 		nandc_delayns(100);
99 		tmp.d32 = nandc_readl(NANDC_FMCTL);
100 		if (tmp.V6.rdy != 0)
101 			break;
102 	}
103 
104 	if (i >= 100000)
105 		status = -1;
106 	return status;
107 }
108 
nandc_randmz_sel(u8 chip_sel,u32 randmz_seed)109 void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed)
110 {
111 	nandc_writel(randmz_seed, NANDC_RANDMZ_CFG);
112 }
113 
nandc_time_cfg(u32 ns)114 void nandc_time_cfg(u32 ns)
115 {
116 	if (g_nandc_ver == 9) {
117 		if (ns < 36)
118 			nandc_writel(0x1041, NANDC_V9_FMWAIT);
119 		else if (ns >= 100)
120 			nandc_writel(0x2082, NANDC_V9_FMWAIT);
121 		else
122 			nandc_writel(0x1061, NANDC_V9_FMWAIT);
123 	} else {
124 		if (ns < 36)
125 			nandc_writel(0x1061, NANDC_FMWAIT);
126 		else if (ns >= 100)
127 			nandc_writel(0x2082, NANDC_FMWAIT);
128 		else
129 			nandc_writel(0x1081, NANDC_FMWAIT);
130 	}
131 }
132 
nandc_bch_sel(u8 bits)133 void nandc_bch_sel(u8 bits)
134 {
135 	union BCH_CTL_T tmp;
136 	union FL_CTL_T fl_reg;
137 	u8 bch_config;
138 
139 	fl_reg.d32 = 0;
140 	fl_reg.V6.rst = 1;
141 	g_nandc_ecc_bits = bits;
142 	if (g_nandc_ver == 9) {
143 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
144 		if (bits == 70)
145 			bch_config = 0;
146 		else if (bits == 60)
147 			bch_config = 3;
148 		else if (bits == 40)
149 			bch_config = 2;
150 		else
151 			bch_config = 1;
152 		tmp.d32 = 0;
153 		tmp.V9.bchmode = bch_config;
154 		tmp.V9.bchrst = 1;
155 		nandc_writel(tmp.d32, NANDC_V9_BCHCTL);
156 	} else {
157 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
158 		tmp.d32 = 0;
159 		tmp.V6.addr = 0x10;
160 		tmp.V6.bch_mode1 = 0;
161 		if (bits == 16) {
162 			tmp.V6.bch_mode = 0;
163 		} else if (bits == 24) {
164 			tmp.V6.bch_mode = 1;
165 		} else {
166 			tmp.V6.bch_mode1 = 1;
167 			tmp.V6.bch_mode = 1;
168 			if (bits == 40)
169 				tmp.V6.bch_mode = 0;
170 		}
171 		tmp.V6.rst = 1;
172 		nandc_writel(tmp.d32, NANDC_BCHCTL);
173 	}
174 }
175 
176 /*
177  *Nandc xfer data transmission
178  *1. set bch register except nandc version equals 9
179  *2. set internal transfer control register
180  *3. set bus transfer
181  *	a. target memory data address
182  *	b. ahb setting
183  *4. configure register orderly and start transmission
184  */
nandc_xfer_start(u8 dir,u8 n_sec,u32 * data,u32 * spare)185 static void nandc_xfer_start(u8 dir, u8 n_sec, u32 *data, u32 *spare)
186 {
187 	union BCH_CTL_T bch_reg;
188 	union FL_CTL_T fl_reg;
189 	u32 i;
190 	union MTRANS_CFG_T master_reg;
191 	u16 *p_spare_tmp = (u16 *)spare;
192 
193 	fl_reg.d32 = 0;
194 	if (g_nandc_ver == 9) {
195 		fl_reg.V9.flash_rdn = dir;
196 		fl_reg.V9.bypass = 1;
197 		fl_reg.V9.tr_count = 1;
198 		fl_reg.V9.async_tog_mix = 1;
199 		fl_reg.V9.cor_able = 1;
200 		fl_reg.V9.st_addr = 0;
201 		fl_reg.V9.page_num = (n_sec + 1) / 2;
202 		/* dma start transfer data do care flash rdy */
203 		fl_reg.V9.flash_st_mod = 1;
204 
205 		if (dir != 0) {
206 			for (i = 0; i < n_sec / 2; i++) {
207 				if (spare) {
208 					master.spare_buf[i] =
209 						(p_spare_tmp[0]) |
210 						((u32)p_spare_tmp[1] << 16);
211 					p_spare_tmp += 2;
212 				} else {
213 					master.spare_buf[i] = 0xffffffff;
214 				}
215 			}
216 		} else {
217 			master.spare_buf[0] = 1;
218 		}
219 		master.page_vir = (u32 *)((data == (u32 *)NULL) ?
220 					  master.page_buf :
221 					  (u32 *)data);
222 		master.spare_vir = (u32 *)master.spare_buf;
223 		master.page_phy =
224 		(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
225 				    fl_reg.V6.page_num * 1024,
226 				    dir);
227 		master.spare_phy =
228 		(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
229 				    fl_reg.V6.page_num * 64,
230 				    dir);
231 		master.mapped = 1;
232 		nandc_writel(master.page_phy, NANDC_V9_MTRANS_SADDR0);
233 		nandc_writel(master.spare_phy, NANDC_V9_MTRANS_SADDR1);
234 
235 		master_reg.d32 =  nandc_readl(NANDC_V9_MTRANS_CFG);
236 		master_reg.V9.incr_num = 16;
237 		master_reg.V9.burst = 7;
238 		master_reg.V9.hsize = 2;
239 		master_reg.V9.bus_mode = 1;
240 		master_reg.V9.ahb_wr = !dir;
241 		master_reg.V9.ahb_wr_st = 1;
242 		master_reg.V9.redundance_size = 0;
243 
244 		nandc_writel(master_reg.d32, NANDC_V9_MTRANS_CFG);
245 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
246 		fl_reg.V9.flash_st = 1;
247 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
248 	} else {
249 		bch_reg.d32 = nandc_readl(NANDC_BCHCTL);
250 		bch_reg.V6.addr = 0x10;
251 		bch_reg.V6.power_down = 0;
252 		bch_reg.V6.region = 0;
253 
254 		fl_reg.V6.rdn = dir;
255 		fl_reg.V6.dma = 1;
256 		fl_reg.V6.tr_count = 1;
257 		fl_reg.V6.async_tog_mix = 1;
258 		fl_reg.V6.cor_en = 1;
259 		fl_reg.V6.st_addr = 0;
260 
261 		master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
262 		master_reg.V6.bus_mode = 0;
263 		if (dir != 0) {
264 			u32 spare_sz = 64;
265 
266 			for (i = 0; i < n_sec / 2; i++) {
267 				if (spare) {
268 					master.spare_buf[i * spare_sz / 4] =
269 					(p_spare_tmp[0]) |
270 					((u32)p_spare_tmp[1] << 16);
271 					p_spare_tmp += 2;
272 				} else {
273 					master.spare_buf[i * spare_sz / 4] =
274 					0xffffffff;
275 				}
276 			}
277 		}
278 		fl_reg.V6.page_num = (n_sec + 1) / 2;
279 		master.page_vir = (u32 *)((data == (u32 *)NULL) ?
280 					  master.page_buf :
281 					  (u32 *)data);
282 		master.spare_vir = (u32 *)master.spare_buf;
283 		master.page_phy =
284 			(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
285 						    fl_reg.V6.page_num * 1024,
286 						    dir);
287 		master.spare_phy =
288 			(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
289 						    fl_reg.V6.page_num * 64,
290 						    dir);
291 		master.mapped = 1;
292 		nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0);
293 		nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1);
294 		master_reg.d32 = 0;
295 		master_reg.V6.incr_num = 16;
296 		master_reg.V6.burst = 7;
297 		master_reg.V6.hsize = 2;
298 		master_reg.V6.bus_mode = 1;
299 		master_reg.V6.ahb_wr = !dir;
300 		master_reg.V6.ahb_wr_st = 1;
301 
302 		nandc_writel(master_reg.d32, NANDC_MTRANS_CFG);
303 		nandc_writel(bch_reg.d32, NANDC_BCHCTL);
304 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
305 		fl_reg.V6.start = 1;
306 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
307 	}
308 }
309 
310 /*
311  * Wait for the end of data transmission
312  */
nandc_xfer_done(void)313 static void nandc_xfer_done(void)
314 {
315 	union FL_CTL_T fl_reg;
316 	union MTRANS_CFG_T master_reg;
317 
318 	if (g_nandc_ver == 9) {
319 		union MTRANS_STAT_T stat_reg;
320 
321 		master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG);
322 		if (master_reg.V9.ahb_wr != 0) {
323 			do {
324 				fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
325 				stat_reg.d32 = nandc_readl(NANDC_V9_MTRANS_STAT);
326 				usleep_range(20, 30);
327 			} while (stat_reg.V9.mtrans_cnt < fl_reg.V9.page_num ||
328 				 fl_reg.V9.tr_rdy == 0);
329 			udelay(5);
330 			if (master.mapped) {
331 				rknandc_dma_unmap_single((u64)master.page_phy,
332 					fl_reg.V9.page_num * 1024,
333 					0);
334 				rknandc_dma_unmap_single((u64)master.spare_phy,
335 					fl_reg.V9.page_num * 64,
336 					0);
337 			}
338 		} else {
339 			do {
340 				fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
341 				usleep_range(20, 30);
342 			} while (fl_reg.V9.tr_rdy == 0);
343 			if (master.mapped) {
344 				rknandc_dma_unmap_single((u64)master.page_phy,
345 					fl_reg.V9.page_num * 1024,
346 					1);
347 				rknandc_dma_unmap_single((u64)master.spare_phy,
348 					fl_reg.V9.page_num * 64,
349 					1);
350 			}
351 		}
352 	} else {
353 		master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
354 		if (master_reg.V6.bus_mode != 0) {
355 			union MTRANS_STAT_T stat_reg;
356 
357 		if (master_reg.V6.ahb_wr != 0) {
358 			do {
359 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
360 				stat_reg.d32 = nandc_readl(NANDC_MTRANS_STAT);
361 				usleep_range(20, 30);
362 			} while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num ||
363 				 !fl_reg.V6.tr_rdy);
364 
365 			if (master.mapped) {
366 				rknandc_dma_unmap_single(
367 					(unsigned long)(master.page_phy),
368 					fl_reg.V6.page_num * 1024,
369 					0);
370 				rknandc_dma_unmap_single(
371 					(unsigned long)(master.spare_phy),
372 					fl_reg.V6.page_num * 64,
373 					0);
374 			}
375 		} else {
376 			do {
377 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
378 				usleep_range(20, 30);
379 			} while (!fl_reg.V6.tr_rdy);
380 			if (master.mapped) {
381 				rknandc_dma_unmap_single(
382 					(unsigned long)(master.page_phy),
383 					fl_reg.V6.page_num * 1024, 1);
384 				rknandc_dma_unmap_single(
385 					(unsigned long)(master.spare_phy),
386 					fl_reg.V6.page_num * 64, 1);
387 			}
388 		}
389 		master.mapped = 0;
390 		} else {
391 			do {
392 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
393 			} while ((!fl_reg.V6.tr_rdy));
394 		}
395 	}
396 }
397 
nandc_xfer_data(u8 chip_sel,u8 dir,u8 n_sec,u32 * p_data,u32 * p_spare)398 u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 n_sec,
399 		    u32 *p_data, u32 *p_spare)
400 {
401 	u32 status = NAND_STS_OK;
402 	u32 i;
403 	u32 spare[16];
404 	union BCH_ST_T bch_st_reg;
405 
406 	if (dir == NANDC_WRITE && !p_spare) {
407 		p_spare = (u32 *)spare;
408 		memset(spare, 0xFF, sizeof(spare));
409 	}
410 	nandc_xfer_start(dir, n_sec, p_data, p_spare);
411 	nandc_xfer_done();
412 	if (dir == NANDC_READ) {
413 		if (g_nandc_ver == 9) {
414 			for (i = 0; i < n_sec / 4; i++) {
415 				bch_st_reg.d32 = nandc_readl(NANDC_V9_BCHST(i));
416 				if (n_sec > 2) {
417 					if (bch_st_reg.V9.fail0 || bch_st_reg.V9.fail1) {
418 						status = NAND_STS_ECC_ERR;
419 					} else {
420 						u32 tmp = max((u32)bch_st_reg.V9.err_bits0,
421 							      (u32)bch_st_reg.V9.err_bits1);
422 						status = max(tmp, status);
423 					}
424 				} else {
425 					if (bch_st_reg.V9.fail0)
426 						status = NAND_STS_ECC_ERR;
427 					else
428 						status = bch_st_reg.V9.err_bits0;
429 				}
430 			}
431 			if (p_spare) {
432 				for (i = 0; i < n_sec / 2; i++)
433 					p_spare[i] = master.spare_buf[i];
434 			}
435 		} else {
436 			for (i = 0; i < n_sec / 4 ; i++) {
437 				bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i));
438 				if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) {
439 					status = NAND_STS_ECC_ERR;
440 				} else {
441 					u32 tmp = 0;
442 
443 					tmp =
444 					max(bch_st_reg.V6.err_bits0 |
445 					    ((u32)bch_st_reg.V6.err_bits0_5 << 5),
446 					    bch_st_reg.V6.err_bits1 |
447 					    ((u32)bch_st_reg.V6.err_bits1_5 << 5));
448 					status = max(tmp, status);
449 				}
450 			}
451 			if (p_spare) {
452 				u32 spare_sz = 64;
453 				u32 temp_data;
454 				u8 *p_spare_temp = (u8 *)p_spare;
455 
456 				for (i = 0; i < n_sec / 2; i++) {
457 					temp_data = master.spare_buf[i * spare_sz / 4];
458 					*p_spare_temp++ = (u8)temp_data;
459 					*p_spare_temp++ = (u8)(temp_data >> 8);
460 					*p_spare_temp++ = (u8)(temp_data >> 16);
461 					*p_spare_temp++ = (u8)(temp_data >> 24);
462 				}
463 			}
464 			nandc_writel(0, NANDC_MTRANS_CFG);
465 		}
466 	}
467 	return status;
468 }
469 
nandc_clean_irq(void)470 void nandc_clean_irq(void)
471 {
472 }
473