blob: 71bbb8231bfbbb960a28e5b5bb31dbfb0624c988 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sergey Kubushyne8f39122007-08-10 20:26:18 +02002/*
3 * NAND driver for TI DaVinci based boards.
4 *
5 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
6 *
7 * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
8 */
9
10/*
11 *
Miquel Raynal1f1ae152018-08-16 17:30:07 +020012 * linux/drivers/mtd/nand/raw/nand_davinci.c
Sergey Kubushyne8f39122007-08-10 20:26:18 +020013 *
14 * NAND Flash Driver
15 *
16 * Copyright (C) 2006 Texas Instruments.
17 *
18 * ----------------------------------------------------------------------------
19 *
Sergey Kubushyne8f39122007-08-10 20:26:18 +020020 * ----------------------------------------------------------------------------
21 *
22 * Overview:
23 * This is a device driver for the NAND flash device found on the
24 * DaVinci board which utilizes the Samsung k9k2g08 part.
25 *
26 Modifications:
27 ver. 1.0: Feb 2005, Vinod/Sudhakar
28 -
Sergey Kubushyne8f39122007-08-10 20:26:18 +020029 */
30
Tom Riniabb9a042024-05-18 20:20:43 -060031#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -060032#include <log.h>
Tom Rini3bde7e22021-09-22 14:50:35 -040033#include <linux/mtd/rawnand.h>
William Juul52c07962007-10-31 13:53:06 +010034#include <asm/io.h>
Sergey Kubushyne8f39122007-08-10 20:26:18 +020035#include <nand.h>
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +020036#include <dm/uclass.h>
Khoronzhuk, Ivan753a00a2014-06-07 04:22:52 +030037#include <asm/ti-common/davinci_nand.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060038#include <linux/printk.h>
Sergey Kubushyne8f39122007-08-10 20:26:18 +020039
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -040040/* Definitions for 4-bit hardware ECC */
41#define NAND_TIMEOUT 10240
42#define NAND_ECC_BUSY 0xC
43#define NAND_4BITECC_MASK 0x03FF03FF
Wolfgang Denk62fb2b42021-09-27 17:42:39 +020044#define EMIF_NANDFSR_ECC_STATE_MASK 0x00000F00
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -040045#define ECC_STATE_NO_ERR 0x0
46#define ECC_STATE_TOO_MANY_ERRS 0x1
47#define ECC_STATE_ERR_CORR_COMP_P 0x2
48#define ECC_STATE_ERR_CORR_COMP_N 0x3
49
Nick Thompson27794722009-12-16 11:15:58 +000050/*
51 * Exploit the little endianness of the ARM to do multi-byte transfers
52 * per device read. This can perform over twice as quickly as individual
53 * byte transfers when buffer alignment is conducive.
54 *
55 * NOTE: This only works if the NAND is not connected to the 2 LSBs of
56 * the address bus. On Davinci EVM platforms this has always been true.
57 */
58static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
59{
Scott Wood17fed142016-05-30 13:57:56 -050060 struct nand_chip *chip = mtd_to_nand(mtd);
Nick Thompson27794722009-12-16 11:15:58 +000061 const u32 *nand = chip->IO_ADDR_R;
62
63 /* Make sure that buf is 32 bit aligned */
64 if (((int)buf & 0x3) != 0) {
65 if (((int)buf & 0x1) != 0) {
66 if (len) {
67 *buf = readb(nand);
68 buf += 1;
69 len--;
70 }
71 }
72
73 if (((int)buf & 0x3) != 0) {
74 if (len >= 2) {
75 *(u16 *)buf = readw(nand);
76 buf += 2;
77 len -= 2;
78 }
79 }
80 }
81
82 /* copy aligned data */
83 while (len >= 4) {
Cyril Chemparathyc4e72242010-03-17 10:03:10 -040084 *(u32 *)buf = __raw_readl(nand);
Nick Thompson27794722009-12-16 11:15:58 +000085 buf += 4;
86 len -= 4;
87 }
88
89 /* mop up any remaining bytes */
90 if (len) {
91 if (len >= 2) {
92 *(u16 *)buf = readw(nand);
93 buf += 2;
94 len -= 2;
95 }
96
97 if (len)
98 *buf = readb(nand);
99 }
100}
101
102static void nand_davinci_write_buf(struct mtd_info *mtd, const uint8_t *buf,
103 int len)
104{
Scott Wood17fed142016-05-30 13:57:56 -0500105 struct nand_chip *chip = mtd_to_nand(mtd);
Nick Thompson27794722009-12-16 11:15:58 +0000106 const u32 *nand = chip->IO_ADDR_W;
107
108 /* Make sure that buf is 32 bit aligned */
109 if (((int)buf & 0x3) != 0) {
110 if (((int)buf & 0x1) != 0) {
111 if (len) {
112 writeb(*buf, nand);
113 buf += 1;
114 len--;
115 }
116 }
117
118 if (((int)buf & 0x3) != 0) {
119 if (len >= 2) {
120 writew(*(u16 *)buf, nand);
121 buf += 2;
122 len -= 2;
123 }
124 }
125 }
126
127 /* copy aligned data */
128 while (len >= 4) {
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400129 __raw_writel(*(u32 *)buf, nand);
Nick Thompson27794722009-12-16 11:15:58 +0000130 buf += 4;
131 len -= 4;
132 }
133
134 /* mop up any remaining bytes */
135 if (len) {
136 if (len >= 2) {
137 writew(*(u16 *)buf, nand);
138 buf += 2;
139 len -= 2;
140 }
141
142 if (len)
143 writeb(*buf, nand);
144 }
145}
146
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400147static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
148 unsigned int ctrl)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200149{
Scott Wood17fed142016-05-30 13:57:56 -0500150 struct nand_chip *this = mtd_to_nand(mtd);
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200151 u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
152
William Juul52c07962007-10-31 13:53:06 +0100153 if (ctrl & NAND_CTRL_CHANGE) {
Nick Thompson27794722009-12-16 11:15:58 +0000154 IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
155
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400156 if (ctrl & NAND_CLE)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200157 IO_ADDR_W |= MASK_CLE;
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400158 if (ctrl & NAND_ALE)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200159 IO_ADDR_W |= MASK_ALE;
William Juul52c07962007-10-31 13:53:06 +0100160 this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200161 }
162
William Juul9e9c2c12007-11-09 13:32:30 +0100163 if (cmd != NAND_CMD_NONE)
Nick Thompson27794722009-12-16 11:15:58 +0000164 writeb(cmd, IO_ADDR_W);
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200165}
166
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200167#ifdef CONFIG_SYS_NAND_HW_ECC
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200168
Laurence Withers0357a762011-09-26 16:02:30 +0000169static u_int32_t nand_davinci_readecc(struct mtd_info *mtd)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200170{
Laurence Withers0357a762011-09-26 16:02:30 +0000171 u_int32_t ecc = 0;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200172
Laurence Withers0357a762011-09-26 16:02:30 +0000173 ecc = __raw_readl(&(davinci_emif_regs->nandfecc[
Tom Rinib4213492022-11-12 17:36:51 -0500174 CFG_SYS_NAND_CS - 2]));
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200175
Laurence Withers0357a762011-09-26 16:02:30 +0000176 return ecc;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200177}
178
Laurence Withers0357a762011-09-26 16:02:30 +0000179static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200180{
Laurence Withers0357a762011-09-26 16:02:30 +0000181 u_int32_t val;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200182
Laurence Withers0357a762011-09-26 16:02:30 +0000183 /* reading the ECC result register resets the ECC calculation */
184 nand_davinci_readecc(mtd);
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200185
Laurence Withers0357a762011-09-26 16:02:30 +0000186 val = __raw_readl(&davinci_emif_regs->nandfcr);
Tom Rinib4213492022-11-12 17:36:51 -0500187 val |= DAVINCI_NANDFCR_NAND_ENABLE(CFG_SYS_NAND_CS);
188 val |= DAVINCI_NANDFCR_1BIT_ECC_START(CFG_SYS_NAND_CS);
Laurence Withers0357a762011-09-26 16:02:30 +0000189 __raw_writel(val, &davinci_emif_regs->nandfcr);
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200190}
191
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400192static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
193 u_char *ecc_code)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200194{
195 u_int32_t tmp;
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400196
Laurence Withers0357a762011-09-26 16:02:30 +0000197 tmp = nand_davinci_readecc(mtd);
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400198
199 /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
200 * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
201 tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
202
203 /* Invert so that erased block ECC is correct */
204 tmp = ~tmp;
205
206 *ecc_code++ = tmp;
207 *ecc_code++ = tmp >> 8;
208 *ecc_code++ = tmp >> 16;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200209
David Brownell962d4c12009-04-28 13:19:53 -0700210 /* NOTE: the above code matches mainline Linux:
211 * .PQR.stu ==> ~PQRstu
212 *
213 * MontaVista/TI kernels encode those bytes differently, use
214 * complicated (and allegedly sometimes-wrong) correction code,
215 * and usually shipped with U-Boot that uses software ECC:
216 * .PQR.stu ==> PsQRtu
217 *
218 * If you need MV/TI compatible NAND I/O in U-Boot, it should
219 * be possible to (a) change the mangling above, (b) reverse
220 * that mangling in nand_davinci_correct_data() below.
221 */
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200222
David Brownell962d4c12009-04-28 13:19:53 -0700223 return 0;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200224}
225
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400226static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
227 u_char *read_ecc, u_char *calc_ecc)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200228{
Scott Wood17fed142016-05-30 13:57:56 -0500229 struct nand_chip *this = mtd_to_nand(mtd);
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400230 u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
231 (read_ecc[2] << 16);
232 u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
233 (calc_ecc[2] << 16);
234 u_int32_t diff = ecc_calc ^ ecc_nand;
235
236 if (diff) {
237 if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
238 /* Correctable error */
239 if ((diff >> (12 + 3)) < this->ecc.size) {
240 uint8_t find_bit = 1 << ((diff >> 12) & 7);
241 uint32_t find_byte = diff >> (12 + 3);
242
243 dat[find_byte] ^= find_bit;
Masahiro Yamadaf8a5d512017-10-18 00:10:48 +0900244 pr_debug("Correcting single "
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400245 "bit ECC error at offset: %d, bit: "
246 "%d\n", find_byte, find_bit);
247 return 1;
248 } else {
Scott Wood52ab7ce2016-05-30 13:57:58 -0500249 return -EBADMSG;
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400250 }
251 } else if (!(diff & (diff - 1))) {
252 /* Single bit ECC error in the ECC itself,
253 nothing to fix */
Masahiro Yamadaf8a5d512017-10-18 00:10:48 +0900254 pr_debug("Single bit ECC error in " "ECC.\n");
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400255 return 1;
256 } else {
257 /* Uncorrectable error */
Masahiro Yamadaf8a5d512017-10-18 00:10:48 +0900258 pr_debug("ECC UNCORRECTED_ERROR 1\n");
Scott Wood52ab7ce2016-05-30 13:57:58 -0500259 return -EBADMSG;
Hugo Villeneuve73dc0e42008-08-30 17:06:55 -0400260 }
261 }
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400262 return 0;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200263}
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200264#endif /* CONFIG_SYS_NAND_HW_ECC */
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200265
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400266#ifdef CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
267static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = {
Sandeep Paulrajd3482862009-11-19 23:04:42 -0500268#if defined(CONFIG_SYS_NAND_PAGE_2K)
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400269 .eccbytes = 40,
Heiko Schocher56596e12013-09-06 05:21:23 +0200270#ifdef CONFIG_NAND_6BYTES_OOB_FREE_10BYTES_ECC
271 .eccpos = {
272 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
273 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
274 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
275 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
276 },
277 .oobfree = {
278 {2, 4}, {16, 6}, {32, 6}, {48, 6},
279 },
280#else
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400281 .eccpos = {
282 24, 25, 26, 27, 28,
283 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
284 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
285 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
286 59, 60, 61, 62, 63,
287 },
288 .oobfree = {
289 {.offset = 2, .length = 22, },
290 },
Heiko Schocher56596e12013-09-06 05:21:23 +0200291#endif /* #ifdef CONFIG_NAND_6BYTES_OOB_FREE_10BYTES_ECC */
Sandeep Paulrajd3482862009-11-19 23:04:42 -0500292#elif defined(CONFIG_SYS_NAND_PAGE_4K)
293 .eccbytes = 80,
294 .eccpos = {
295 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
296 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
297 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
298 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
299 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
300 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
301 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
302 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
303 },
304 .oobfree = {
305 {.offset = 2, .length = 46, },
306 },
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400307#endif
308};
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400309
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300310#if defined CONFIG_KEYSTONE_RBL_NAND
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300311static struct nand_ecclayout nand_keystone_rbl_4bit_layout_oobfirst = {
Khoronzhuk, Ivan9016c6f2014-09-02 00:20:02 +0300312#if defined(CONFIG_SYS_NAND_PAGE_2K)
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300313 .eccbytes = 40,
314 .eccpos = {
315 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
316 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
317 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
318 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
319 },
320 .oobfree = {
321 {.offset = 2, .length = 4, },
322 {.offset = 16, .length = 6, },
323 {.offset = 32, .length = 6, },
324 {.offset = 48, .length = 6, },
325 },
326#elif defined(CONFIG_SYS_NAND_PAGE_4K)
327 .eccbytes = 80,
328 .eccpos = {
329 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
330 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
331 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
332 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
333 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
334 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
335 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
336 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
337 },
338 .oobfree = {
339 {.offset = 2, .length = 4, },
340 {.offset = 16, .length = 6, },
341 {.offset = 32, .length = 6, },
342 {.offset = 48, .length = 6, },
343 {.offset = 64, .length = 6, },
344 {.offset = 80, .length = 6, },
345 {.offset = 96, .length = 6, },
346 {.offset = 112, .length = 6, },
347 },
348#endif
349};
350
351#ifdef CONFIG_SYS_NAND_PAGE_2K
Tom Rinidada0e32021-09-12 20:32:24 -0400352#define KEYSTONE_NAND_MAX_RBL_PAGE (0x100000 >> 11)
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300353#elif defined(CONFIG_SYS_NAND_PAGE_4K)
Tom Rinidada0e32021-09-12 20:32:24 -0400354#define KEYSTONE_NAND_MAX_RBL_PAGE (0x100000 >> 12)
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300355#endif
356
357/**
358 * nand_davinci_write_page - write one page
359 * @mtd: MTD device structure
360 * @chip: NAND chip descriptor
361 * @buf: the data to write
362 * @oob_required: must write chip->oob_poi to OOB
363 * @page: page number to write
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300364 * @raw: use _raw version of write_page
365 */
366static int nand_davinci_write_page(struct mtd_info *mtd, struct nand_chip *chip,
Khoronzhuk, Ivand5c65802014-09-06 22:17:07 +0300367 uint32_t offset, int data_len,
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300368 const uint8_t *buf, int oob_required,
Boris Brezillonb9bf43c2017-11-22 02:38:24 +0900369 int page, int raw)
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300370{
371 int status;
372 int ret = 0;
373 struct nand_ecclayout *saved_ecc_layout;
374
375 /* save current ECC layout and assign Keystone RBL ECC layout */
Tom Rinidada0e32021-09-12 20:32:24 -0400376 if (page < KEYSTONE_NAND_MAX_RBL_PAGE) {
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300377 saved_ecc_layout = chip->ecc.layout;
378 chip->ecc.layout = &nand_keystone_rbl_4bit_layout_oobfirst;
379 mtd->oobavail = chip->ecc.layout->oobavail;
380 }
381
382 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
383
Scott Wood46e13102016-05-30 13:57:57 -0500384 if (unlikely(raw)) {
385 status = chip->ecc.write_page_raw(mtd, chip, buf,
386 oob_required, page);
387 } else {
388 status = chip->ecc.write_page(mtd, chip, buf,
389 oob_required, page);
390 }
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300391
392 if (status < 0) {
393 ret = status;
394 goto err;
395 }
396
397 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
398 status = chip->waitfunc(mtd, chip);
399
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300400 if (status & NAND_STATUS_FAIL) {
401 ret = -EIO;
402 goto err;
403 }
404
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300405err:
406 /* restore ECC layout */
Tom Rinidada0e32021-09-12 20:32:24 -0400407 if (page < KEYSTONE_NAND_MAX_RBL_PAGE) {
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300408 chip->ecc.layout = saved_ecc_layout;
409 mtd->oobavail = saved_ecc_layout->oobavail;
410 }
411
412 return ret;
413}
414
415/**
416 * nand_davinci_read_page_hwecc - hardware ECC based page read function
417 * @mtd: mtd info structure
418 * @chip: nand chip info structure
419 * @buf: buffer to store read data
420 * @oob_required: caller requires OOB data read to chip->oob_poi
421 * @page: page number to read
422 *
423 * Not for syndrome calculating ECC controllers which need a special oob layout.
424 */
425static int nand_davinci_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
426 uint8_t *buf, int oob_required, int page)
427{
428 int i, eccsize = chip->ecc.size;
429 int eccbytes = chip->ecc.bytes;
430 int eccsteps = chip->ecc.steps;
431 uint32_t *eccpos;
432 uint8_t *p = buf;
433 uint8_t *ecc_code = chip->buffers->ecccode;
434 uint8_t *ecc_calc = chip->buffers->ecccalc;
435 struct nand_ecclayout *saved_ecc_layout = chip->ecc.layout;
436
437 /* save current ECC layout and assign Keystone RBL ECC layout */
Tom Rinidada0e32021-09-12 20:32:24 -0400438 if (page < KEYSTONE_NAND_MAX_RBL_PAGE) {
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300439 chip->ecc.layout = &nand_keystone_rbl_4bit_layout_oobfirst;
440 mtd->oobavail = chip->ecc.layout->oobavail;
441 }
442
443 eccpos = chip->ecc.layout->eccpos;
444
445 /* Read the OOB area first */
446 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
447 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
448 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
449
450 for (i = 0; i < chip->ecc.total; i++)
451 ecc_code[i] = chip->oob_poi[eccpos[i]];
452
453 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
454 int stat;
455
456 chip->ecc.hwctl(mtd, NAND_ECC_READ);
457 chip->read_buf(mtd, p, eccsize);
458 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
459
460 stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
461 if (stat < 0)
462 mtd->ecc_stats.failed++;
463 else
464 mtd->ecc_stats.corrected += stat;
465 }
466
467 /* restore ECC layout */
Tom Rinidada0e32021-09-12 20:32:24 -0400468 if (page < KEYSTONE_NAND_MAX_RBL_PAGE) {
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300469 chip->ecc.layout = saved_ecc_layout;
470 mtd->oobavail = saved_ecc_layout->oobavail;
471 }
472
473 return 0;
474}
475#endif /* CONFIG_KEYSTONE_RBL_NAND */
476
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400477static void nand_davinci_4bit_enable_hwecc(struct mtd_info *mtd, int mode)
478{
479 u32 val;
480
481 switch (mode) {
482 case NAND_ECC_WRITE:
483 case NAND_ECC_READ:
484 /*
485 * Start a new ECC calculation for reading or writing 512 bytes
486 * of data.
487 */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400488 val = __raw_readl(&davinci_emif_regs->nandfcr);
Nick Thompson789c8872009-12-12 12:12:26 -0500489 val &= ~DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK;
Tom Rinib4213492022-11-12 17:36:51 -0500490 val |= DAVINCI_NANDFCR_NAND_ENABLE(CFG_SYS_NAND_CS);
491 val |= DAVINCI_NANDFCR_4BIT_ECC_SEL(CFG_SYS_NAND_CS);
Nick Thompson789c8872009-12-12 12:12:26 -0500492 val |= DAVINCI_NANDFCR_4BIT_ECC_START;
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400493 __raw_writel(val, &davinci_emif_regs->nandfcr);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400494 break;
495 case NAND_ECC_READSYN:
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400496 val = __raw_readl(&davinci_emif_regs->nand4bitecc[0]);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400497 break;
498 default:
499 break;
500 }
501}
502
503static u32 nand_davinci_4bit_readecc(struct mtd_info *mtd, unsigned int ecc[4])
504{
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400505 int i;
506
507 for (i = 0; i < 4; i++) {
508 ecc[i] = __raw_readl(&davinci_emif_regs->nand4bitecc[i]) &
509 NAND_4BITECC_MASK;
510 }
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400511
512 return 0;
513}
514
515static int nand_davinci_4bit_calculate_ecc(struct mtd_info *mtd,
516 const uint8_t *dat,
517 uint8_t *ecc_code)
518{
Nick Thompson27794722009-12-16 11:15:58 +0000519 unsigned int hw_4ecc[4];
520 unsigned int i;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400521
522 nand_davinci_4bit_readecc(mtd, hw_4ecc);
523
524 /*Convert 10 bit ecc value to 8 bit */
Nick Thompson27794722009-12-16 11:15:58 +0000525 for (i = 0; i < 2; i++) {
526 unsigned int hw_ecc_low = hw_4ecc[i * 2];
527 unsigned int hw_ecc_hi = hw_4ecc[(i * 2) + 1];
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400528
529 /* Take first 8 bits from val1 (count1=0) or val5 (count1=1) */
Nick Thompson27794722009-12-16 11:15:58 +0000530 *ecc_code++ = hw_ecc_low & 0xFF;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400531
532 /*
533 * Take 2 bits as LSB bits from val1 (count1=0) or val5
534 * (count1=1) and 6 bits from val2 (count1=0) or
535 * val5 (count1=1)
536 */
Nick Thompson27794722009-12-16 11:15:58 +0000537 *ecc_code++ =
538 ((hw_ecc_low >> 8) & 0x3) | ((hw_ecc_low >> 14) & 0xFC);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400539
540 /*
541 * Take 4 bits from val2 (count1=0) or val5 (count1=1) and
542 * 4 bits from val3 (count1=0) or val6 (count1=1)
543 */
Nick Thompson27794722009-12-16 11:15:58 +0000544 *ecc_code++ =
545 ((hw_ecc_low >> 22) & 0xF) | ((hw_ecc_hi << 4) & 0xF0);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400546
547 /*
548 * Take 6 bits from val3(count1=0) or val6 (count1=1) and
549 * 2 bits from val4 (count1=0) or val7 (count1=1)
550 */
Nick Thompson27794722009-12-16 11:15:58 +0000551 *ecc_code++ =
552 ((hw_ecc_hi >> 4) & 0x3F) | ((hw_ecc_hi >> 10) & 0xC0);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400553
554 /* Take 8 bits from val4 (count1=0) or val7 (count1=1) */
Nick Thompson27794722009-12-16 11:15:58 +0000555 *ecc_code++ = (hw_ecc_hi >> 18) & 0xFF;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400556 }
Nick Thompson27794722009-12-16 11:15:58 +0000557
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400558 return 0;
559}
560
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400561static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat,
562 uint8_t *read_ecc, uint8_t *calc_ecc)
563{
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400564 int i;
Nick Thompson27794722009-12-16 11:15:58 +0000565 unsigned int hw_4ecc[4];
566 unsigned int iserror;
567 unsigned short *ecc16;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400568 unsigned int numerrors, erroraddress, errorvalue;
569 u32 val;
570
571 /*
572 * Check for an ECC where all bytes are 0xFF. If this is the case, we
573 * will assume we are looking at an erased page and we should ignore
574 * the ECC.
575 */
576 for (i = 0; i < 10; i++) {
577 if (read_ecc[i] != 0xFF)
578 break;
579 }
580 if (i == 10)
581 return 0;
582
583 /* Convert 8 bit in to 10 bit */
Nick Thompson27794722009-12-16 11:15:58 +0000584 ecc16 = (unsigned short *)&read_ecc[0];
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400585
Nick Thompson27794722009-12-16 11:15:58 +0000586 /*
587 * Write the parity values in the NAND Flash 4-bit ECC Load register.
588 * Write each parity value one at a time starting from 4bit_ecc_val8
589 * to 4bit_ecc_val1.
590 */
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400591
Nick Thompson27794722009-12-16 11:15:58 +0000592 /*Take 2 bits from 8th byte and 8 bits from 9th byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400593 __raw_writel(((ecc16[4]) >> 6) & 0x3FF,
594 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400595
Nick Thompson27794722009-12-16 11:15:58 +0000596 /* Take 4 bits from 7th byte and 6 bits from 8th byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400597 __raw_writel((((ecc16[3]) >> 12) & 0xF) | ((((ecc16[4])) << 4) & 0x3F0),
598 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400599
Nick Thompson27794722009-12-16 11:15:58 +0000600 /* Take 6 bits from 6th byte and 4 bits from 7th byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400601 __raw_writel((ecc16[3] >> 2) & 0x3FF,
602 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400603
604 /* Take 8 bits from 5th byte and 2 bits from 6th byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400605 __raw_writel(((ecc16[2]) >> 8) | ((((ecc16[3])) << 8) & 0x300),
606 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400607
Nick Thompson27794722009-12-16 11:15:58 +0000608 /*Take 2 bits from 3rd byte and 8 bits from 4th byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400609 __raw_writel((((ecc16[1]) >> 14) & 0x3) | ((((ecc16[2])) << 2) & 0x3FC),
610 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400611
Nick Thompson27794722009-12-16 11:15:58 +0000612 /* Take 4 bits form 2nd bytes and 6 bits from 3rd bytes */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400613 __raw_writel(((ecc16[1]) >> 4) & 0x3FF,
614 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400615
Nick Thompson27794722009-12-16 11:15:58 +0000616 /* Take 6 bits from 1st byte and 4 bits from 2nd byte */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400617 __raw_writel((((ecc16[0]) >> 10) & 0x3F) | (((ecc16[1]) << 6) & 0x3C0),
618 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400619
Nick Thompson27794722009-12-16 11:15:58 +0000620 /* Take 10 bits from 0th and 1st bytes */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400621 __raw_writel((ecc16[0]) & 0x3FF,
622 &davinci_emif_regs->nand4biteccload);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400623
624 /*
625 * Perform a dummy read to the EMIF Revision Code and Status register.
626 * This is required to ensure time for syndrome calculation after
627 * writing the ECC values in previous step.
628 */
629
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400630 val = __raw_readl(&davinci_emif_regs->nandfsr);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400631
632 /*
633 * Read the syndrome from the NAND Flash 4-Bit ECC 1-4 registers.
634 * A syndrome value of 0 means no bit errors. If the syndrome is
635 * non-zero then go further otherwise return.
636 */
637 nand_davinci_4bit_readecc(mtd, hw_4ecc);
638
Nick Thompson27794722009-12-16 11:15:58 +0000639 if (!(hw_4ecc[0] | hw_4ecc[1] | hw_4ecc[2] | hw_4ecc[3]))
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400640 return 0;
641
642 /*
643 * Clear any previous address calculation by doing a dummy read of an
644 * error address register.
645 */
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400646 val = __raw_readl(&davinci_emif_regs->nanderradd1);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400647
648 /*
649 * Set the addr_calc_st bit(bit no 13) in the NAND Flash Control
650 * register to 1.
651 */
Ben Gardinerdfd19ea2010-10-14 17:26:17 -0400652 __raw_writel(DAVINCI_NANDFCR_4BIT_CALC_START,
653 &davinci_emif_regs->nandfcr);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400654
655 /*
Wolfram Sang328d0552010-09-09 13:54:41 +0200656 * Wait for the corr_state field (bits 8 to 11) in the
657 * NAND Flash Status register to be not equal to 0x0, 0x1, 0x2, or 0x3.
658 * Otherwise ECC calculation has not even begun and the next loop might
659 * fail because of a false positive!
660 */
661 i = NAND_TIMEOUT;
662 do {
663 val = __raw_readl(&davinci_emif_regs->nandfsr);
664 val &= 0xc00;
665 i--;
666 } while ((i > 0) && !val);
667
668 /*
669 * Wait for the corr_state field (bits 8 to 11) in the
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400670 * NAND Flash Status register to be equal to 0x0, 0x1, 0x2, or 0x3.
671 */
672 i = NAND_TIMEOUT;
673 do {
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400674 val = __raw_readl(&davinci_emif_regs->nandfsr);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400675 val &= 0xc00;
676 i--;
677 } while ((i > 0) && val);
678
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400679 iserror = __raw_readl(&davinci_emif_regs->nandfsr);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400680 iserror &= EMIF_NANDFSR_ECC_STATE_MASK;
681 iserror = iserror >> 8;
682
683 /*
684 * ECC_STATE_TOO_MANY_ERRS (0x1) means errors cannot be
685 * corrected (five or more errors). The number of errors
686 * calculated (err_num field) differs from the number of errors
687 * searched. ECC_STATE_ERR_CORR_COMP_P (0x2) means error
688 * correction complete (errors on bit 8 or 9).
689 * ECC_STATE_ERR_CORR_COMP_N (0x3) means error correction
690 * complete (error exists).
691 */
692
693 if (iserror == ECC_STATE_NO_ERR) {
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400694 val = __raw_readl(&davinci_emif_regs->nanderrval1);
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400695 return 0;
696 } else if (iserror == ECC_STATE_TOO_MANY_ERRS) {
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400697 val = __raw_readl(&davinci_emif_regs->nanderrval1);
Scott Wood52ab7ce2016-05-30 13:57:58 -0500698 return -EBADMSG;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400699 }
700
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400701 numerrors = ((__raw_readl(&davinci_emif_regs->nandfsr) >> 16)
702 & 0x3) + 1;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400703
704 /* Read the error address, error value and correct */
705 for (i = 0; i < numerrors; i++) {
706 if (i > 1) {
707 erroraddress =
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400708 ((__raw_readl(&davinci_emif_regs->nanderradd2) >>
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400709 (16 * (i & 1))) & 0x3FF);
710 erroraddress = ((512 + 7) - erroraddress);
711 errorvalue =
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400712 ((__raw_readl(&davinci_emif_regs->nanderrval2) >>
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400713 (16 * (i & 1))) & 0xFF);
714 } else {
715 erroraddress =
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400716 ((__raw_readl(&davinci_emif_regs->nanderradd1) >>
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400717 (16 * (i & 1))) & 0x3FF);
718 erroraddress = ((512 + 7) - erroraddress);
719 errorvalue =
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400720 ((__raw_readl(&davinci_emif_regs->nanderrval1) >>
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400721 (16 * (i & 1))) & 0xFF);
722 }
723 /* xor the corrupt data with error value */
724 if (erroraddress < 512)
725 dat[erroraddress] ^= errorvalue;
726 }
727
728 return numerrors;
729}
Scott Woodce630312009-09-28 16:33:18 -0500730#endif /* CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST */
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400731
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200732static int nand_davinci_dev_ready(struct mtd_info *mtd)
733{
Cyril Chemparathyc4e72242010-03-17 10:03:10 -0400734 return __raw_readl(&davinci_emif_regs->nandfsr) & 0x1;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200735}
736
Bartosz Golaszewski2d4e3302019-07-29 08:58:02 +0200737static void davinci_nand_init(struct nand_chip *nand)
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200738{
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300739#if defined CONFIG_KEYSTONE_RBL_NAND
740 int i;
741 struct nand_ecclayout *layout;
742
743 layout = &nand_keystone_rbl_4bit_layout_oobfirst;
744 layout->oobavail = 0;
Heinrich Schuchardt397b0622019-07-30 23:29:21 +0200745 for (i = 0; i < ARRAY_SIZE(layout->oobfree) &&
746 layout->oobfree[i].length; i++)
Khoronzhuk, Ivan2f64e472014-07-04 15:03:25 +0300747 layout->oobavail += layout->oobfree[i].length;
748
749 nand->write_page = nand_davinci_write_page;
750 nand->ecc.read_page = nand_davinci_read_page_hwecc;
751#endif
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200752 nand->chip_delay = 0;
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200753#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
Sergey Lapin3a38a552013-01-14 03:46:50 +0000754 nand->bbt_options |= NAND_BBT_USE_FLASH;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200755#endif
Karicheri, Muralidharanc1dc61b2014-04-04 13:16:50 -0400756#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
757 nand->options |= NAND_NO_SUBPAGE_WRITE;
758#endif
Fabien Parentddc00942016-11-29 14:31:29 +0100759#ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT
760 nand->options |= NAND_BUSWIDTH_16;
761#endif
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200762#ifdef CONFIG_SYS_NAND_HW_ECC
William Juul9e9c2c12007-11-09 13:32:30 +0100763 nand->ecc.mode = NAND_ECC_HW;
William Juul9e9c2c12007-11-09 13:32:30 +0100764 nand->ecc.size = 512;
765 nand->ecc.bytes = 3;
Sergey Lapin3a38a552013-01-14 03:46:50 +0000766 nand->ecc.strength = 1;
William Juul52c07962007-10-31 13:53:06 +0100767 nand->ecc.calculate = nand_davinci_calculate_ecc;
768 nand->ecc.correct = nand_davinci_correct_data;
William Juulb76ec382007-11-08 10:39:53 +0100769 nand->ecc.hwctl = nand_davinci_enable_hwecc;
Tom Rinid1286e12022-11-12 17:36:45 -0500770#elif defined(CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST)
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400771 nand->ecc.mode = NAND_ECC_HW_OOB_FIRST;
772 nand->ecc.size = 512;
773 nand->ecc.bytes = 10;
Sergey Lapin3a38a552013-01-14 03:46:50 +0000774 nand->ecc.strength = 4;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400775 nand->ecc.calculate = nand_davinci_4bit_calculate_ecc;
776 nand->ecc.correct = nand_davinci_4bit_correct_data;
777 nand->ecc.hwctl = nand_davinci_4bit_enable_hwecc;
778 nand->ecc.layout = &nand_davinci_4bit_layout_oobfirst;
Tom Rinid1286e12022-11-12 17:36:45 -0500779#elif defined(CONFIG_SYS_NAND_SOFT_ECC)
780 nand->ecc.mode = NAND_ECC_SOFT;
Sandeep Paulrajbfeb0fd2009-08-18 10:10:42 -0400781#endif
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200782 /* Set address of hardware control function */
William Juul52c07962007-10-31 13:53:06 +0100783 nand->cmd_ctrl = nand_davinci_hwcontrol;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200784
Nick Thompson27794722009-12-16 11:15:58 +0000785 nand->read_buf = nand_davinci_read_buf;
786 nand->write_buf = nand_davinci_write_buf;
787
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200788 nand->dev_ready = nand_davinci_dev_ready;
David Brownellf4b0b9d2009-05-10 15:43:01 -0700789}
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200790
Tom Rini98372452021-12-12 22:12:36 -0500791#if CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT)
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200792static int davinci_nand_probe(struct udevice *dev)
793{
794 struct nand_chip *nand = dev_get_priv(dev);
795 struct mtd_info *mtd = nand_to_mtd(nand);
796 int ret;
797
Tom Rinib4213492022-11-12 17:36:51 -0500798 nand->IO_ADDR_R = (void __iomem *)CFG_SYS_NAND_BASE;
799 nand->IO_ADDR_W = (void __iomem *)CFG_SYS_NAND_BASE;
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200800
801 davinci_nand_init(nand);
802
803 ret = nand_scan(mtd, CONFIG_SYS_NAND_MAX_CHIPS);
804 if (ret)
805 return ret;
806
807 return nand_register(0, mtd);
808}
809
810static const struct udevice_id davinci_nand_ids[] = {
811 { .compatible = "ti,davinci-nand" },
812 { }
813};
814
815U_BOOT_DRIVER(davinci_nand) = {
816 .name = "davinci-nand",
817 .id = UCLASS_MTD,
818 .of_match = davinci_nand_ids,
819 .probe = davinci_nand_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700820 .priv_auto = sizeof(struct nand_chip),
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200821};
822
823void board_nand_init(void)
824{
825 struct udevice *dev;
826 int ret;
David Brownellf4b0b9d2009-05-10 15:43:01 -0700827
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200828 ret = uclass_get_device_by_driver(UCLASS_MTD,
Simon Glass65130cd2020-12-28 20:34:56 -0700829 DM_DRIVER_GET(davinci_nand), &dev);
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200830 if (ret && ret != -ENODEV)
831 pr_err("Failed to initialize %s: %d\n", dev->name, ret);
832}
833#else
834int board_nand_init(struct nand_chip *chip) __attribute__((weak));
David Brownellf4b0b9d2009-05-10 15:43:01 -0700835int board_nand_init(struct nand_chip *chip)
836{
837 davinci_nand_init(chip);
838 return 0;
Sergey Kubushyne8f39122007-08-10 20:26:18 +0200839}
Bartosz Golaszewski8a14dfe2019-07-29 08:58:03 +0200840#endif /* CONFIG_SYS_NAND_SELF_INIT */