xref: /rk3399_rockchip-uboot/drivers/mtd/nand/raw/rockchip_nand_spl.c (revision b5f6b28fa3454b1189d8fefe01a26dd09f2e3f1e)
1 /*
2  * Copyright (c) 2017 Yifeng Zhao <yifeng.zhao@rock-chips.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <fdtdec.h>
9 #include <fdt_support.h>
10 #include <inttypes.h>
11 #include <nand.h>
12 #include <linux/kernel.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/nand.h>
15 #include <linux/mtd/partitions.h>
16 #include <linux/io.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 
20 #define NANDC_V6_BOOTROM_ECC	24
21 #define NANDC_V6_NUM_BANKS	4
22 #define NANDC_V6_DEF_TIMEOUT	20000
23 #define NANDC_V6_READ		0
24 #define NANDC_V6_WRITE		1
25 
26 #define	NANDC_REG_V6_FMCTL	0x00
27 #define	NANDC_REG_V6_FMWAIT	0x04
28 #define	NANDC_REG_V6_FLCTL	0x08
29 #define	NANDC_REG_V6_BCHCTL	0x0c
30 #define	NANDC_REG_V6_DMA_CFG	0x10
31 #define	NANDC_REG_V6_DMA_BUF0	0x14
32 #define	NANDC_REG_V6_DMA_BUF1	0x18
33 #define	NANDC_REG_V6_DMA_ST	0x1C
34 #define	NANDC_REG_V6_BCHST	0x20
35 #define	NANDC_REG_V6_RANDMZ	0x150
36 #define	NANDC_REG_V6_VER	0x160
37 #define	NANDC_REG_V6_INTEN	0x16C
38 #define	NANDC_REG_V6_INTCLR	0x170
39 #define	NANDC_REG_V6_INTST	0x174
40 #define	NANDC_REG_V6_SPARE0	0x200
41 #define	NANDC_REG_V6_SPARE1	0x230
42 #define	NANDC_REG_V6_BANK0	0x800
43 #define	NANDC_REG_V6_SRAM0	0x1000
44 #define	NANDC_REG_V6_SRAM_SIZE	0x400
45 
46 #define NANDC_REG_V6_DATA	0x00
47 #define NANDC_REG_V6_ADDR	0x04
48 #define NANDC_REG_V6_CMD	0x08
49 
50 /* FMCTL */
51 #define NANDC_V6_FM_WP		BIT(8)
52 #define NANDC_V6_FM_CE_SEL_M	0xFF
53 #define NANDC_V6_FM_CE_SEL(x)	(1 << (x))
54 #define NANDC_V6_FM_FREADY	BIT(9)
55 
56 /* FLCTL */
57 #define NANDC_V6_FL_RST		BIT(0)
58 #define NANDC_V6_FL_DIR_S	0x1
59 #define NANDC_V6_FL_XFER_START	BIT(2)
60 #define NANDC_V6_FL_XFER_EN	BIT(3)
61 #define NANDC_V6_FL_ST_BUF_S	0x4
62 #define NANDC_V6_FL_XFER_COUNT	BIT(5)
63 #define NANDC_V6_FL_ACORRECT	BIT(10)
64 #define NANDC_V6_FL_XFER_READY	BIT(20)
65 
66 /* BCHCTL */
67 #define NAND_V6_BCH_REGION_S	0x5
68 #define NAND_V6_BCH_REGION_M	0x7
69 
70 /* BCHST */
71 #define NANDC_V6_BCH0_ST_ERR	BIT(2)
72 #define NANDC_V6_BCH1_ST_ERR	BIT(15)
73 #define NANDC_V6_ECC_ERR_CNT0(x) ((((x & (0x1F << 3)) >> 3) \
74 				| ((x & (1 << 27)) >> 22)) & 0x3F)
75 #define NANDC_V6_ECC_ERR_CNT1(x) ((((x & (0x1F << 16)) >> 16) \
76 				| ((x & (1 << 29)) >> 24)) & 0x3F)
77 
78 struct rk_nand {
79 	void __iomem *regs;
80 	u8 chipnr;
81 	u8 id[5];
82 	u8 *databuf;
83 };
84 
85 struct rk_nand *g_rk_nand;
86 
87 static void nandc_init(struct rk_nand *rknand)
88 {
89 	writel(0x1081, rknand->regs + NANDC_REG_V6_FMWAIT);
90 }
91 
92 static void rockchip_nand_wait_dev_ready(void __iomem *regs)
93 {
94 	u32 reg;
95 	u32 timeout = NANDC_V6_DEF_TIMEOUT;
96 
97 	while (timeout--) {
98 		udelay(1);
99 		reg = readl(regs + NANDC_REG_V6_FMCTL);
100 
101 		if ((reg & NANDC_V6_FM_FREADY))
102 			break;
103 	}
104 }
105 
106 static void rockchip_nand_select_chip(void __iomem *regs, int chipnr)
107 {
108 	u32 reg;
109 
110 	reg = readl(regs + NANDC_REG_V6_FMCTL);
111 	reg &= ~NANDC_V6_FM_CE_SEL_M;
112 	if (chipnr != -1)
113 		reg |= 1 << chipnr;
114 	writel(reg, regs + NANDC_REG_V6_FMCTL);
115 }
116 
117 static void rockchip_nand_read_page(void __iomem *regs,
118 				    int page, int col)
119 {
120 	void __iomem *bank_base = regs + NANDC_REG_V6_BANK0;
121 
122 	writeb(0x00, bank_base + NANDC_REG_V6_CMD);
123 	writeb(col, bank_base + NANDC_REG_V6_ADDR);
124 	writeb(col >> 8, bank_base + NANDC_REG_V6_ADDR);
125 	writeb(page, bank_base + NANDC_REG_V6_ADDR);
126 	writeb(page >> 8, bank_base + NANDC_REG_V6_ADDR);
127 	writeb(page >> 16, bank_base + NANDC_REG_V6_ADDR);
128 	writeb(0x30, bank_base + NANDC_REG_V6_CMD);
129 }
130 
131 static void rockchip_nand_pio_xfer_start(struct rk_nand *rknand,
132 					 u8 dir,
133 					 u8 st_buf)
134 {
135 	u32 reg;
136 
137 	reg = readl(rknand->regs + NANDC_REG_V6_BCHCTL);
138 	reg = (reg & (~(NAND_V6_BCH_REGION_M << NAND_V6_BCH_REGION_S)));
139 	writel(reg, rknand->regs + NANDC_REG_V6_BCHCTL);
140 
141 	reg = (dir << NANDC_V6_FL_DIR_S) | (st_buf << NANDC_V6_FL_ST_BUF_S) |
142 		  NANDC_V6_FL_XFER_EN | NANDC_V6_FL_XFER_COUNT |
143 		  NANDC_V6_FL_ACORRECT;
144 	writel(reg, rknand->regs + NANDC_REG_V6_FLCTL);
145 
146 	reg |= NANDC_V6_FL_XFER_START;
147 	writel(reg, rknand->regs + NANDC_REG_V6_FLCTL);
148 }
149 
150 static int rockchip_nand_wait_pio_xfer_done(struct rk_nand *rknand)
151 {
152 	int timeout = NANDC_V6_DEF_TIMEOUT;
153 	int reg;
154 
155 	while (timeout--) {
156 		reg = readl(rknand->regs + NANDC_REG_V6_FLCTL);
157 
158 		if ((reg & NANDC_V6_FL_XFER_READY) != 0)
159 			break;
160 
161 		udelay(1);
162 	}
163 
164 	if (timeout == 0)
165 		return -1;
166 
167 	return 0;
168 }
169 
170 static int nandc_read_page(unsigned int page, uint8_t *buf)
171 {
172 	void __iomem *sram_base = g_rk_nand->regs + NANDC_REG_V6_SRAM0;
173 	unsigned int max_bitflips = 0;
174 	int ret, step, bch_st, ecc_step;
175 
176 	ecc_step = CONFIG_SYS_NAND_PAGE_SIZE / 1024;
177 	rockchip_nand_select_chip(g_rk_nand->regs, 0);
178 	rockchip_nand_read_page(g_rk_nand->regs, page, 0);
179 	rockchip_nand_wait_dev_ready(g_rk_nand->regs);
180 	rockchip_nand_pio_xfer_start(g_rk_nand, NANDC_V6_READ, 0);
181 
182 	for (step = 0; step < ecc_step; step++) {
183 		int data_off = step * 1024;
184 		u8 *data = buf + data_off;
185 
186 		ret = rockchip_nand_wait_pio_xfer_done(g_rk_nand);
187 		if (ret)
188 			return ret;
189 
190 		bch_st = readl(g_rk_nand->regs + NANDC_REG_V6_BCHST);
191 
192 		if (bch_st & NANDC_V6_BCH0_ST_ERR) {
193 			max_bitflips = -1;
194 		} else {
195 			ret = NANDC_V6_ECC_ERR_CNT0(bch_st);
196 			max_bitflips = max_t(unsigned int, max_bitflips, ret);
197 		}
198 
199 		if ((step + 1) < ecc_step)
200 			rockchip_nand_pio_xfer_start(g_rk_nand, NANDC_V6_READ,
201 						     (step + 1) & 0x1);
202 
203 		memcpy_fromio(data, sram_base + NANDC_REG_V6_SRAM_SIZE *
204 			      (step & 1), 1024);
205 	}
206 	rockchip_nand_select_chip(g_rk_nand->regs, -1);
207 
208 	return max_bitflips;
209 }
210 
211 static int is_badblock(unsigned int page)
212 {
213 	int res = 0, i;
214 	u16 bad = 0xff;
215 	void __iomem *regs = g_rk_nand->regs;
216 	void __iomem *bank_base = regs + NANDC_REG_V6_BANK0;
217 
218 	if (nandc_read_page(page, g_rk_nand->databuf) == -1) {
219 		rockchip_nand_select_chip(regs, 0);
220 		rockchip_nand_read_page(regs, page,
221 					CONFIG_SYS_NAND_PAGE_SIZE);
222 		rockchip_nand_wait_dev_ready(regs);
223 		for (i = 0; i < 8; i++) {
224 			bad = readb(bank_base);
225 			if (bad)
226 				break;
227 		}
228 		if (i >= 8)
229 			res = 1;
230 		rockchip_nand_select_chip(regs, 0);
231 	}
232 	if (res)
233 		printf("%s 0x%x %x %x\n", __func__, page, res, bad);
234 	return res;
235 }
236 
237 static void read_flash_id(struct rk_nand *rknand, uint8_t *id)
238 {
239 	void __iomem *bank_base = rknand->regs + NANDC_REG_V6_BANK0;
240 
241 	rockchip_nand_wait_dev_ready(g_rk_nand->regs);
242 	writeb(0x90, bank_base + NANDC_REG_V6_CMD);
243 	writeb(0x00, bank_base + NANDC_REG_V6_ADDR);
244 	udelay(1);
245 	id[0] = readb(bank_base);
246 	id[1] = readb(bank_base);
247 	id[2] = readb(bank_base);
248 	id[3] = readb(bank_base);
249 	id[4] = readb(bank_base);
250 	rockchip_nand_select_chip(rknand->regs, -1);
251 	printf("%s %x %x %x %x %x\n", __func__, id[0], id[1], id[2], id[3],
252 	       id[4]);
253 }
254 
255 void board_nand_init(void)
256 {
257 	const void *blob = gd->fdt_blob;
258 	static int initialized;
259 	fdt_addr_t regs;
260 	int node;
261 
262 	if (initialized)
263 		return;
264 
265 	initialized = 1;
266 
267 	if (g_rk_nand)
268 		return;
269 
270 	node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_NANDC);
271 
272 	if (node < 0) {
273 		printf("Nand node not found\n");
274 		goto err;
275 	}
276 
277 	if (!fdtdec_get_is_enabled(blob, node)) {
278 		debug("Nand disabled in device tree\n");
279 		goto err;
280 	}
281 
282 	regs = fdt_get_base_address(blob, node);
283 	if (regs == FDT_ADDR_T_NONE) {
284 		debug("Nand address not found\n");
285 		goto err;
286 	}
287 
288 	g_rk_nand = kzalloc(sizeof(*g_rk_nand), GFP_KERNEL);
289 	g_rk_nand->regs = (void *)regs;
290 	g_rk_nand->databuf = kzalloc(CONFIG_SYS_NAND_PAGE_SIZE, GFP_KERNEL);
291 	nandc_init(g_rk_nand);
292 	read_flash_id(g_rk_nand, g_rk_nand->id);
293 	if (g_rk_nand->id[0] != 0xFF && g_rk_nand->id[1] != 0xFF &&
294 	    g_rk_nand->id[0] != 0x00 && g_rk_nand->id[1] != 0x00)
295 		g_rk_nand->chipnr = 1;
296 	return;
297 err:
298 	kfree(g_rk_nand);
299 }
300 
301 int nand_spl_load_image(u32 offs, u32 size, void *buf)
302 {
303 	int i;
304 	unsigned int page;
305 	unsigned int maxpages = CONFIG_SYS_NAND_SIZE /
306 				CONFIG_SYS_NAND_PAGE_SIZE;
307 
308 	/* Convert to page number */
309 	page = offs / CONFIG_SYS_NAND_PAGE_SIZE;
310 	i = 0;
311 
312 	size = roundup(size, CONFIG_SYS_NAND_PAGE_SIZE);
313 	while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) {
314 		/*
315 		 * Check if we have crossed a block boundary, and if so
316 		 * check for bad block.
317 		 */
318 		if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) {
319 			/*
320 			 * Yes, new block. See if this block is good. If not,
321 			 * loop until we find a good block.
322 			 */
323 			while (is_badblock(page)) {
324 				page = page + CONFIG_SYS_NAND_PAGE_COUNT;
325 				/* Check i we've reached the end of flash. */
326 				if (page >= maxpages)
327 					return -EIO;
328 			}
329 		}
330 
331 		if (nandc_read_page(page, buf) < 0)
332 			return -EIO;
333 
334 		page++;
335 		i++;
336 		buf = buf + CONFIG_SYS_NAND_PAGE_SIZE;
337 	}
338 	return 0;
339 }
340 
341 void nand_init(void)
342 {
343 	board_nand_init();
344 }
345 
346 int rk_nand_init(void)
347 {
348 	board_nand_init();
349 	if (g_rk_nand && g_rk_nand->chipnr)
350 		return 0;
351 	else
352 		return -ENODEV;
353 }
354 
355 void nand_deselect(void) {}
356