1*cfcc706cSMiquel Raynal /*
2*cfcc706cSMiquel Raynal * Copyright (c) 2011 The Chromium OS Authors.
3*cfcc706cSMiquel Raynal * (C) Copyright 2011 NVIDIA Corporation <www.nvidia.com>
4*cfcc706cSMiquel Raynal * (C) Copyright 2006 Detlev Zundel, dzu@denx.de
5*cfcc706cSMiquel Raynal * (C) Copyright 2006 DENX Software Engineering
6*cfcc706cSMiquel Raynal *
7*cfcc706cSMiquel Raynal * SPDX-License-Identifier: GPL-2.0+
8*cfcc706cSMiquel Raynal */
9*cfcc706cSMiquel Raynal
10*cfcc706cSMiquel Raynal #include <common.h>
11*cfcc706cSMiquel Raynal #include <asm/io.h>
12*cfcc706cSMiquel Raynal #include <memalign.h>
13*cfcc706cSMiquel Raynal #include <nand.h>
14*cfcc706cSMiquel Raynal #include <asm/arch/clock.h>
15*cfcc706cSMiquel Raynal #include <asm/arch/funcmux.h>
16*cfcc706cSMiquel Raynal #include <asm/arch-tegra/clk_rst.h>
17*cfcc706cSMiquel Raynal #include <linux/errno.h>
18*cfcc706cSMiquel Raynal #include <asm/gpio.h>
19*cfcc706cSMiquel Raynal #include <fdtdec.h>
20*cfcc706cSMiquel Raynal #include <bouncebuf.h>
21*cfcc706cSMiquel Raynal #include <dm.h>
22*cfcc706cSMiquel Raynal #include "tegra_nand.h"
23*cfcc706cSMiquel Raynal
24*cfcc706cSMiquel Raynal DECLARE_GLOBAL_DATA_PTR;
25*cfcc706cSMiquel Raynal
26*cfcc706cSMiquel Raynal #define NAND_CMD_TIMEOUT_MS 10
27*cfcc706cSMiquel Raynal
28*cfcc706cSMiquel Raynal #define SKIPPED_SPARE_BYTES 4
29*cfcc706cSMiquel Raynal
30*cfcc706cSMiquel Raynal /* ECC bytes to be generated for tag data */
31*cfcc706cSMiquel Raynal #define TAG_ECC_BYTES 4
32*cfcc706cSMiquel Raynal
33*cfcc706cSMiquel Raynal static const struct udevice_id tegra_nand_dt_ids[] = {
34*cfcc706cSMiquel Raynal {
35*cfcc706cSMiquel Raynal .compatible = "nvidia,tegra20-nand",
36*cfcc706cSMiquel Raynal },
37*cfcc706cSMiquel Raynal { /* sentinel */ }
38*cfcc706cSMiquel Raynal };
39*cfcc706cSMiquel Raynal
40*cfcc706cSMiquel Raynal /* 64 byte oob block info for large page (== 2KB) device
41*cfcc706cSMiquel Raynal *
42*cfcc706cSMiquel Raynal * OOB flash layout for Tegra with Reed-Solomon 4 symbol correct ECC:
43*cfcc706cSMiquel Raynal * Skipped bytes(4)
44*cfcc706cSMiquel Raynal * Main area Ecc(36)
45*cfcc706cSMiquel Raynal * Tag data(20)
46*cfcc706cSMiquel Raynal * Tag data Ecc(4)
47*cfcc706cSMiquel Raynal *
48*cfcc706cSMiquel Raynal * Yaffs2 will use 16 tag bytes.
49*cfcc706cSMiquel Raynal */
50*cfcc706cSMiquel Raynal static struct nand_ecclayout eccoob = {
51*cfcc706cSMiquel Raynal .eccbytes = 36,
52*cfcc706cSMiquel Raynal .eccpos = {
53*cfcc706cSMiquel Raynal 4, 5, 6, 7, 8, 9, 10, 11, 12,
54*cfcc706cSMiquel Raynal 13, 14, 15, 16, 17, 18, 19, 20, 21,
55*cfcc706cSMiquel Raynal 22, 23, 24, 25, 26, 27, 28, 29, 30,
56*cfcc706cSMiquel Raynal 31, 32, 33, 34, 35, 36, 37, 38, 39,
57*cfcc706cSMiquel Raynal },
58*cfcc706cSMiquel Raynal .oobavail = 20,
59*cfcc706cSMiquel Raynal .oobfree = {
60*cfcc706cSMiquel Raynal {
61*cfcc706cSMiquel Raynal .offset = 40,
62*cfcc706cSMiquel Raynal .length = 20,
63*cfcc706cSMiquel Raynal },
64*cfcc706cSMiquel Raynal }
65*cfcc706cSMiquel Raynal };
66*cfcc706cSMiquel Raynal
67*cfcc706cSMiquel Raynal enum {
68*cfcc706cSMiquel Raynal ECC_OK,
69*cfcc706cSMiquel Raynal ECC_TAG_ERROR = 1 << 0,
70*cfcc706cSMiquel Raynal ECC_DATA_ERROR = 1 << 1
71*cfcc706cSMiquel Raynal };
72*cfcc706cSMiquel Raynal
73*cfcc706cSMiquel Raynal /* Timing parameters */
74*cfcc706cSMiquel Raynal enum {
75*cfcc706cSMiquel Raynal FDT_NAND_MAX_TRP_TREA,
76*cfcc706cSMiquel Raynal FDT_NAND_TWB,
77*cfcc706cSMiquel Raynal FDT_NAND_MAX_TCR_TAR_TRR,
78*cfcc706cSMiquel Raynal FDT_NAND_TWHR,
79*cfcc706cSMiquel Raynal FDT_NAND_MAX_TCS_TCH_TALS_TALH,
80*cfcc706cSMiquel Raynal FDT_NAND_TWH,
81*cfcc706cSMiquel Raynal FDT_NAND_TWP,
82*cfcc706cSMiquel Raynal FDT_NAND_TRH,
83*cfcc706cSMiquel Raynal FDT_NAND_TADL,
84*cfcc706cSMiquel Raynal
85*cfcc706cSMiquel Raynal FDT_NAND_TIMING_COUNT
86*cfcc706cSMiquel Raynal };
87*cfcc706cSMiquel Raynal
88*cfcc706cSMiquel Raynal /* Information about an attached NAND chip */
89*cfcc706cSMiquel Raynal struct fdt_nand {
90*cfcc706cSMiquel Raynal struct nand_ctlr *reg;
91*cfcc706cSMiquel Raynal int enabled; /* 1 to enable, 0 to disable */
92*cfcc706cSMiquel Raynal struct gpio_desc wp_gpio; /* write-protect GPIO */
93*cfcc706cSMiquel Raynal s32 width; /* bit width, normally 8 */
94*cfcc706cSMiquel Raynal u32 timing[FDT_NAND_TIMING_COUNT];
95*cfcc706cSMiquel Raynal };
96*cfcc706cSMiquel Raynal
97*cfcc706cSMiquel Raynal struct nand_drv {
98*cfcc706cSMiquel Raynal struct nand_ctlr *reg;
99*cfcc706cSMiquel Raynal struct fdt_nand config;
100*cfcc706cSMiquel Raynal };
101*cfcc706cSMiquel Raynal
102*cfcc706cSMiquel Raynal struct tegra_nand_info {
103*cfcc706cSMiquel Raynal struct udevice *dev;
104*cfcc706cSMiquel Raynal struct nand_drv nand_ctrl;
105*cfcc706cSMiquel Raynal struct nand_chip nand_chip;
106*cfcc706cSMiquel Raynal };
107*cfcc706cSMiquel Raynal
108*cfcc706cSMiquel Raynal /**
109*cfcc706cSMiquel Raynal * Wait for command completion
110*cfcc706cSMiquel Raynal *
111*cfcc706cSMiquel Raynal * @param reg nand_ctlr structure
112*cfcc706cSMiquel Raynal * @return
113*cfcc706cSMiquel Raynal * 1 - Command completed
114*cfcc706cSMiquel Raynal * 0 - Timeout
115*cfcc706cSMiquel Raynal */
nand_waitfor_cmd_completion(struct nand_ctlr * reg)116*cfcc706cSMiquel Raynal static int nand_waitfor_cmd_completion(struct nand_ctlr *reg)
117*cfcc706cSMiquel Raynal {
118*cfcc706cSMiquel Raynal u32 reg_val;
119*cfcc706cSMiquel Raynal int running;
120*cfcc706cSMiquel Raynal int i;
121*cfcc706cSMiquel Raynal
122*cfcc706cSMiquel Raynal for (i = 0; i < NAND_CMD_TIMEOUT_MS * 1000; i++) {
123*cfcc706cSMiquel Raynal if ((readl(®->command) & CMD_GO) ||
124*cfcc706cSMiquel Raynal !(readl(®->status) & STATUS_RBSY0) ||
125*cfcc706cSMiquel Raynal !(readl(®->isr) & ISR_IS_CMD_DONE)) {
126*cfcc706cSMiquel Raynal udelay(1);
127*cfcc706cSMiquel Raynal continue;
128*cfcc706cSMiquel Raynal }
129*cfcc706cSMiquel Raynal reg_val = readl(®->dma_mst_ctrl);
130*cfcc706cSMiquel Raynal /*
131*cfcc706cSMiquel Raynal * If DMA_MST_CTRL_EN_A_ENABLE or DMA_MST_CTRL_EN_B_ENABLE
132*cfcc706cSMiquel Raynal * is set, that means DMA engine is running.
133*cfcc706cSMiquel Raynal *
134*cfcc706cSMiquel Raynal * Then we have to wait until DMA_MST_CTRL_IS_DMA_DONE
135*cfcc706cSMiquel Raynal * is cleared, indicating DMA transfer completion.
136*cfcc706cSMiquel Raynal */
137*cfcc706cSMiquel Raynal running = reg_val & (DMA_MST_CTRL_EN_A_ENABLE |
138*cfcc706cSMiquel Raynal DMA_MST_CTRL_EN_B_ENABLE);
139*cfcc706cSMiquel Raynal if (!running || (reg_val & DMA_MST_CTRL_IS_DMA_DONE))
140*cfcc706cSMiquel Raynal return 1;
141*cfcc706cSMiquel Raynal udelay(1);
142*cfcc706cSMiquel Raynal }
143*cfcc706cSMiquel Raynal return 0;
144*cfcc706cSMiquel Raynal }
145*cfcc706cSMiquel Raynal
146*cfcc706cSMiquel Raynal /**
147*cfcc706cSMiquel Raynal * Read one byte from the chip
148*cfcc706cSMiquel Raynal *
149*cfcc706cSMiquel Raynal * @param mtd MTD device structure
150*cfcc706cSMiquel Raynal * @return data byte
151*cfcc706cSMiquel Raynal *
152*cfcc706cSMiquel Raynal * Read function for 8bit bus-width
153*cfcc706cSMiquel Raynal */
read_byte(struct mtd_info * mtd)154*cfcc706cSMiquel Raynal static uint8_t read_byte(struct mtd_info *mtd)
155*cfcc706cSMiquel Raynal {
156*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
157*cfcc706cSMiquel Raynal struct nand_drv *info;
158*cfcc706cSMiquel Raynal
159*cfcc706cSMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip);
160*cfcc706cSMiquel Raynal
161*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_PIO | CMD_RX | CMD_CE0 | CMD_A_VALID,
162*cfcc706cSMiquel Raynal &info->reg->command);
163*cfcc706cSMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg))
164*cfcc706cSMiquel Raynal printf("Command timeout\n");
165*cfcc706cSMiquel Raynal
166*cfcc706cSMiquel Raynal return (uint8_t)readl(&info->reg->resp);
167*cfcc706cSMiquel Raynal }
168*cfcc706cSMiquel Raynal
169*cfcc706cSMiquel Raynal /**
170*cfcc706cSMiquel Raynal * Read len bytes from the chip into a buffer
171*cfcc706cSMiquel Raynal *
172*cfcc706cSMiquel Raynal * @param mtd MTD device structure
173*cfcc706cSMiquel Raynal * @param buf buffer to store data to
174*cfcc706cSMiquel Raynal * @param len number of bytes to read
175*cfcc706cSMiquel Raynal *
176*cfcc706cSMiquel Raynal * Read function for 8bit bus-width
177*cfcc706cSMiquel Raynal */
read_buf(struct mtd_info * mtd,uint8_t * buf,int len)178*cfcc706cSMiquel Raynal static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
179*cfcc706cSMiquel Raynal {
180*cfcc706cSMiquel Raynal int i, s;
181*cfcc706cSMiquel Raynal unsigned int reg;
182*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
183*cfcc706cSMiquel Raynal struct nand_drv *info = (struct nand_drv *)nand_get_controller_data(chip);
184*cfcc706cSMiquel Raynal
185*cfcc706cSMiquel Raynal for (i = 0; i < len; i += 4) {
186*cfcc706cSMiquel Raynal s = (len - i) > 4 ? 4 : len - i;
187*cfcc706cSMiquel Raynal writel(CMD_PIO | CMD_RX | CMD_A_VALID | CMD_CE0 |
188*cfcc706cSMiquel Raynal ((s - 1) << CMD_TRANS_SIZE_SHIFT) | CMD_GO,
189*cfcc706cSMiquel Raynal &info->reg->command);
190*cfcc706cSMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg))
191*cfcc706cSMiquel Raynal puts("Command timeout during read_buf\n");
192*cfcc706cSMiquel Raynal reg = readl(&info->reg->resp);
193*cfcc706cSMiquel Raynal memcpy(buf + i, ®, s);
194*cfcc706cSMiquel Raynal }
195*cfcc706cSMiquel Raynal }
196*cfcc706cSMiquel Raynal
197*cfcc706cSMiquel Raynal /**
198*cfcc706cSMiquel Raynal * Check NAND status to see if it is ready or not
199*cfcc706cSMiquel Raynal *
200*cfcc706cSMiquel Raynal * @param mtd MTD device structure
201*cfcc706cSMiquel Raynal * @return
202*cfcc706cSMiquel Raynal * 1 - ready
203*cfcc706cSMiquel Raynal * 0 - not ready
204*cfcc706cSMiquel Raynal */
nand_dev_ready(struct mtd_info * mtd)205*cfcc706cSMiquel Raynal static int nand_dev_ready(struct mtd_info *mtd)
206*cfcc706cSMiquel Raynal {
207*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
208*cfcc706cSMiquel Raynal int reg_val;
209*cfcc706cSMiquel Raynal struct nand_drv *info;
210*cfcc706cSMiquel Raynal
211*cfcc706cSMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip);
212*cfcc706cSMiquel Raynal
213*cfcc706cSMiquel Raynal reg_val = readl(&info->reg->status);
214*cfcc706cSMiquel Raynal if (reg_val & STATUS_RBSY0)
215*cfcc706cSMiquel Raynal return 1;
216*cfcc706cSMiquel Raynal else
217*cfcc706cSMiquel Raynal return 0;
218*cfcc706cSMiquel Raynal }
219*cfcc706cSMiquel Raynal
220*cfcc706cSMiquel Raynal /* Dummy implementation: we don't support multiple chips */
nand_select_chip(struct mtd_info * mtd,int chipnr)221*cfcc706cSMiquel Raynal static void nand_select_chip(struct mtd_info *mtd, int chipnr)
222*cfcc706cSMiquel Raynal {
223*cfcc706cSMiquel Raynal switch (chipnr) {
224*cfcc706cSMiquel Raynal case -1:
225*cfcc706cSMiquel Raynal case 0:
226*cfcc706cSMiquel Raynal break;
227*cfcc706cSMiquel Raynal
228*cfcc706cSMiquel Raynal default:
229*cfcc706cSMiquel Raynal BUG();
230*cfcc706cSMiquel Raynal }
231*cfcc706cSMiquel Raynal }
232*cfcc706cSMiquel Raynal
233*cfcc706cSMiquel Raynal /**
234*cfcc706cSMiquel Raynal * Clear all interrupt status bits
235*cfcc706cSMiquel Raynal *
236*cfcc706cSMiquel Raynal * @param reg nand_ctlr structure
237*cfcc706cSMiquel Raynal */
nand_clear_interrupt_status(struct nand_ctlr * reg)238*cfcc706cSMiquel Raynal static void nand_clear_interrupt_status(struct nand_ctlr *reg)
239*cfcc706cSMiquel Raynal {
240*cfcc706cSMiquel Raynal u32 reg_val;
241*cfcc706cSMiquel Raynal
242*cfcc706cSMiquel Raynal /* Clear interrupt status */
243*cfcc706cSMiquel Raynal reg_val = readl(®->isr);
244*cfcc706cSMiquel Raynal writel(reg_val, ®->isr);
245*cfcc706cSMiquel Raynal }
246*cfcc706cSMiquel Raynal
247*cfcc706cSMiquel Raynal /**
248*cfcc706cSMiquel Raynal * Send command to NAND device
249*cfcc706cSMiquel Raynal *
250*cfcc706cSMiquel Raynal * @param mtd MTD device structure
251*cfcc706cSMiquel Raynal * @param command the command to be sent
252*cfcc706cSMiquel Raynal * @param column the column address for this command, -1 if none
253*cfcc706cSMiquel Raynal * @param page_addr the page address for this command, -1 if none
254*cfcc706cSMiquel Raynal */
nand_command(struct mtd_info * mtd,unsigned int command,int column,int page_addr)255*cfcc706cSMiquel Raynal static void nand_command(struct mtd_info *mtd, unsigned int command,
256*cfcc706cSMiquel Raynal int column, int page_addr)
257*cfcc706cSMiquel Raynal {
258*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
259*cfcc706cSMiquel Raynal struct nand_drv *info;
260*cfcc706cSMiquel Raynal
261*cfcc706cSMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip);
262*cfcc706cSMiquel Raynal
263*cfcc706cSMiquel Raynal /*
264*cfcc706cSMiquel Raynal * Write out the command to the device.
265*cfcc706cSMiquel Raynal *
266*cfcc706cSMiquel Raynal * Only command NAND_CMD_RESET or NAND_CMD_READID will come
267*cfcc706cSMiquel Raynal * here before mtd->writesize is initialized.
268*cfcc706cSMiquel Raynal */
269*cfcc706cSMiquel Raynal
270*cfcc706cSMiquel Raynal /* Emulate NAND_CMD_READOOB */
271*cfcc706cSMiquel Raynal if (command == NAND_CMD_READOOB) {
272*cfcc706cSMiquel Raynal assert(mtd->writesize != 0);
273*cfcc706cSMiquel Raynal column += mtd->writesize;
274*cfcc706cSMiquel Raynal command = NAND_CMD_READ0;
275*cfcc706cSMiquel Raynal }
276*cfcc706cSMiquel Raynal
277*cfcc706cSMiquel Raynal /* Adjust columns for 16 bit bus-width */
278*cfcc706cSMiquel Raynal if (column != -1 && (chip->options & NAND_BUSWIDTH_16))
279*cfcc706cSMiquel Raynal column >>= 1;
280*cfcc706cSMiquel Raynal
281*cfcc706cSMiquel Raynal nand_clear_interrupt_status(info->reg);
282*cfcc706cSMiquel Raynal
283*cfcc706cSMiquel Raynal /* Stop DMA engine, clear DMA completion status */
284*cfcc706cSMiquel Raynal writel(DMA_MST_CTRL_EN_A_DISABLE
285*cfcc706cSMiquel Raynal | DMA_MST_CTRL_EN_B_DISABLE
286*cfcc706cSMiquel Raynal | DMA_MST_CTRL_IS_DMA_DONE,
287*cfcc706cSMiquel Raynal &info->reg->dma_mst_ctrl);
288*cfcc706cSMiquel Raynal
289*cfcc706cSMiquel Raynal /*
290*cfcc706cSMiquel Raynal * Program and erase have their own busy handlers
291*cfcc706cSMiquel Raynal * status and sequential in needs no delay
292*cfcc706cSMiquel Raynal */
293*cfcc706cSMiquel Raynal switch (command) {
294*cfcc706cSMiquel Raynal case NAND_CMD_READID:
295*cfcc706cSMiquel Raynal writel(NAND_CMD_READID, &info->reg->cmd_reg1);
296*cfcc706cSMiquel Raynal writel(column & 0xFF, &info->reg->addr_reg1);
297*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0,
298*cfcc706cSMiquel Raynal &info->reg->command);
299*cfcc706cSMiquel Raynal break;
300*cfcc706cSMiquel Raynal case NAND_CMD_PARAM:
301*cfcc706cSMiquel Raynal writel(NAND_CMD_PARAM, &info->reg->cmd_reg1);
302*cfcc706cSMiquel Raynal writel(column & 0xFF, &info->reg->addr_reg1);
303*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0,
304*cfcc706cSMiquel Raynal &info->reg->command);
305*cfcc706cSMiquel Raynal break;
306*cfcc706cSMiquel Raynal case NAND_CMD_READ0:
307*cfcc706cSMiquel Raynal writel(NAND_CMD_READ0, &info->reg->cmd_reg1);
308*cfcc706cSMiquel Raynal writel(NAND_CMD_READSTART, &info->reg->cmd_reg2);
309*cfcc706cSMiquel Raynal writel((page_addr << 16) | (column & 0xFFFF),
310*cfcc706cSMiquel Raynal &info->reg->addr_reg1);
311*cfcc706cSMiquel Raynal writel(page_addr >> 16, &info->reg->addr_reg2);
312*cfcc706cSMiquel Raynal return;
313*cfcc706cSMiquel Raynal case NAND_CMD_SEQIN:
314*cfcc706cSMiquel Raynal writel(NAND_CMD_SEQIN, &info->reg->cmd_reg1);
315*cfcc706cSMiquel Raynal writel(NAND_CMD_PAGEPROG, &info->reg->cmd_reg2);
316*cfcc706cSMiquel Raynal writel((page_addr << 16) | (column & 0xFFFF),
317*cfcc706cSMiquel Raynal &info->reg->addr_reg1);
318*cfcc706cSMiquel Raynal writel(page_addr >> 16,
319*cfcc706cSMiquel Raynal &info->reg->addr_reg2);
320*cfcc706cSMiquel Raynal return;
321*cfcc706cSMiquel Raynal case NAND_CMD_PAGEPROG:
322*cfcc706cSMiquel Raynal return;
323*cfcc706cSMiquel Raynal case NAND_CMD_ERASE1:
324*cfcc706cSMiquel Raynal writel(NAND_CMD_ERASE1, &info->reg->cmd_reg1);
325*cfcc706cSMiquel Raynal writel(NAND_CMD_ERASE2, &info->reg->cmd_reg2);
326*cfcc706cSMiquel Raynal writel(page_addr, &info->reg->addr_reg1);
327*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_ALE |
328*cfcc706cSMiquel Raynal CMD_SEC_CMD | CMD_CE0 | CMD_ALE_BYTES3,
329*cfcc706cSMiquel Raynal &info->reg->command);
330*cfcc706cSMiquel Raynal break;
331*cfcc706cSMiquel Raynal case NAND_CMD_ERASE2:
332*cfcc706cSMiquel Raynal return;
333*cfcc706cSMiquel Raynal case NAND_CMD_STATUS:
334*cfcc706cSMiquel Raynal writel(NAND_CMD_STATUS, &info->reg->cmd_reg1);
335*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_PIO | CMD_RX
336*cfcc706cSMiquel Raynal | ((1 - 0) << CMD_TRANS_SIZE_SHIFT)
337*cfcc706cSMiquel Raynal | CMD_CE0,
338*cfcc706cSMiquel Raynal &info->reg->command);
339*cfcc706cSMiquel Raynal break;
340*cfcc706cSMiquel Raynal case NAND_CMD_RESET:
341*cfcc706cSMiquel Raynal writel(NAND_CMD_RESET, &info->reg->cmd_reg1);
342*cfcc706cSMiquel Raynal writel(CMD_GO | CMD_CLE | CMD_CE0,
343*cfcc706cSMiquel Raynal &info->reg->command);
344*cfcc706cSMiquel Raynal break;
345*cfcc706cSMiquel Raynal case NAND_CMD_RNDOUT:
346*cfcc706cSMiquel Raynal default:
347*cfcc706cSMiquel Raynal printf("%s: Unsupported command %d\n", __func__, command);
348*cfcc706cSMiquel Raynal return;
349*cfcc706cSMiquel Raynal }
350*cfcc706cSMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg))
351*cfcc706cSMiquel Raynal printf("Command 0x%02X timeout\n", command);
352*cfcc706cSMiquel Raynal }
353*cfcc706cSMiquel Raynal
354*cfcc706cSMiquel Raynal /**
355*cfcc706cSMiquel Raynal * Check whether the pointed buffer are all 0xff (blank).
356*cfcc706cSMiquel Raynal *
357*cfcc706cSMiquel Raynal * @param buf data buffer for blank check
358*cfcc706cSMiquel Raynal * @param len length of the buffer in byte
359*cfcc706cSMiquel Raynal * @return
360*cfcc706cSMiquel Raynal * 1 - blank
361*cfcc706cSMiquel Raynal * 0 - non-blank
362*cfcc706cSMiquel Raynal */
blank_check(u8 * buf,int len)363*cfcc706cSMiquel Raynal static int blank_check(u8 *buf, int len)
364*cfcc706cSMiquel Raynal {
365*cfcc706cSMiquel Raynal int i;
366*cfcc706cSMiquel Raynal
367*cfcc706cSMiquel Raynal for (i = 0; i < len; i++)
368*cfcc706cSMiquel Raynal if (buf[i] != 0xFF)
369*cfcc706cSMiquel Raynal return 0;
370*cfcc706cSMiquel Raynal return 1;
371*cfcc706cSMiquel Raynal }
372*cfcc706cSMiquel Raynal
373*cfcc706cSMiquel Raynal /**
374*cfcc706cSMiquel Raynal * After a DMA transfer for read, we call this function to see whether there
375*cfcc706cSMiquel Raynal * is any uncorrectable error on the pointed data buffer or oob buffer.
376*cfcc706cSMiquel Raynal *
377*cfcc706cSMiquel Raynal * @param reg nand_ctlr structure
378*cfcc706cSMiquel Raynal * @param databuf data buffer
379*cfcc706cSMiquel Raynal * @param a_len data buffer length
380*cfcc706cSMiquel Raynal * @param oobbuf oob buffer
381*cfcc706cSMiquel Raynal * @param b_len oob buffer length
382*cfcc706cSMiquel Raynal * @return
383*cfcc706cSMiquel Raynal * ECC_OK - no ECC error or correctable ECC error
384*cfcc706cSMiquel Raynal * ECC_TAG_ERROR - uncorrectable tag ECC error
385*cfcc706cSMiquel Raynal * ECC_DATA_ERROR - uncorrectable data ECC error
386*cfcc706cSMiquel Raynal * ECC_DATA_ERROR + ECC_TAG_ERROR - uncorrectable data+tag ECC error
387*cfcc706cSMiquel Raynal */
check_ecc_error(struct nand_ctlr * reg,u8 * databuf,int a_len,u8 * oobbuf,int b_len)388*cfcc706cSMiquel Raynal static int check_ecc_error(struct nand_ctlr *reg, u8 *databuf,
389*cfcc706cSMiquel Raynal int a_len, u8 *oobbuf, int b_len)
390*cfcc706cSMiquel Raynal {
391*cfcc706cSMiquel Raynal int return_val = ECC_OK;
392*cfcc706cSMiquel Raynal u32 reg_val;
393*cfcc706cSMiquel Raynal
394*cfcc706cSMiquel Raynal if (!(readl(®->isr) & ISR_IS_ECC_ERR))
395*cfcc706cSMiquel Raynal return ECC_OK;
396*cfcc706cSMiquel Raynal
397*cfcc706cSMiquel Raynal /*
398*cfcc706cSMiquel Raynal * Area A is used for the data block (databuf). Area B is used for
399*cfcc706cSMiquel Raynal * the spare block (oobbuf)
400*cfcc706cSMiquel Raynal */
401*cfcc706cSMiquel Raynal reg_val = readl(®->dec_status);
402*cfcc706cSMiquel Raynal if ((reg_val & DEC_STATUS_A_ECC_FAIL) && databuf) {
403*cfcc706cSMiquel Raynal reg_val = readl(®->bch_dec_status_buf);
404*cfcc706cSMiquel Raynal /*
405*cfcc706cSMiquel Raynal * If uncorrectable error occurs on data area, then see whether
406*cfcc706cSMiquel Raynal * they are all FF. If all are FF, it's a blank page.
407*cfcc706cSMiquel Raynal * Not error.
408*cfcc706cSMiquel Raynal */
409*cfcc706cSMiquel Raynal if ((reg_val & BCH_DEC_STATUS_FAIL_SEC_FLAG_MASK) &&
410*cfcc706cSMiquel Raynal !blank_check(databuf, a_len))
411*cfcc706cSMiquel Raynal return_val |= ECC_DATA_ERROR;
412*cfcc706cSMiquel Raynal }
413*cfcc706cSMiquel Raynal
414*cfcc706cSMiquel Raynal if ((reg_val & DEC_STATUS_B_ECC_FAIL) && oobbuf) {
415*cfcc706cSMiquel Raynal reg_val = readl(®->bch_dec_status_buf);
416*cfcc706cSMiquel Raynal /*
417*cfcc706cSMiquel Raynal * If uncorrectable error occurs on tag area, then see whether
418*cfcc706cSMiquel Raynal * they are all FF. If all are FF, it's a blank page.
419*cfcc706cSMiquel Raynal * Not error.
420*cfcc706cSMiquel Raynal */
421*cfcc706cSMiquel Raynal if ((reg_val & BCH_DEC_STATUS_FAIL_TAG_MASK) &&
422*cfcc706cSMiquel Raynal !blank_check(oobbuf, b_len))
423*cfcc706cSMiquel Raynal return_val |= ECC_TAG_ERROR;
424*cfcc706cSMiquel Raynal }
425*cfcc706cSMiquel Raynal
426*cfcc706cSMiquel Raynal return return_val;
427*cfcc706cSMiquel Raynal }
428*cfcc706cSMiquel Raynal
429*cfcc706cSMiquel Raynal /**
430*cfcc706cSMiquel Raynal * Set GO bit to send command to device
431*cfcc706cSMiquel Raynal *
432*cfcc706cSMiquel Raynal * @param reg nand_ctlr structure
433*cfcc706cSMiquel Raynal */
start_command(struct nand_ctlr * reg)434*cfcc706cSMiquel Raynal static void start_command(struct nand_ctlr *reg)
435*cfcc706cSMiquel Raynal {
436*cfcc706cSMiquel Raynal u32 reg_val;
437*cfcc706cSMiquel Raynal
438*cfcc706cSMiquel Raynal reg_val = readl(®->command);
439*cfcc706cSMiquel Raynal reg_val |= CMD_GO;
440*cfcc706cSMiquel Raynal writel(reg_val, ®->command);
441*cfcc706cSMiquel Raynal }
442*cfcc706cSMiquel Raynal
443*cfcc706cSMiquel Raynal /**
444*cfcc706cSMiquel Raynal * Clear command GO bit, DMA GO bit, and DMA completion status
445*cfcc706cSMiquel Raynal *
446*cfcc706cSMiquel Raynal * @param reg nand_ctlr structure
447*cfcc706cSMiquel Raynal */
stop_command(struct nand_ctlr * reg)448*cfcc706cSMiquel Raynal static void stop_command(struct nand_ctlr *reg)
449*cfcc706cSMiquel Raynal {
450*cfcc706cSMiquel Raynal /* Stop command */
451*cfcc706cSMiquel Raynal writel(0, ®->command);
452*cfcc706cSMiquel Raynal
453*cfcc706cSMiquel Raynal /* Stop DMA engine and clear DMA completion status */
454*cfcc706cSMiquel Raynal writel(DMA_MST_CTRL_GO_DISABLE
455*cfcc706cSMiquel Raynal | DMA_MST_CTRL_IS_DMA_DONE,
456*cfcc706cSMiquel Raynal ®->dma_mst_ctrl);
457*cfcc706cSMiquel Raynal }
458*cfcc706cSMiquel Raynal
459*cfcc706cSMiquel Raynal /**
460*cfcc706cSMiquel Raynal * Set up NAND bus width and page size
461*cfcc706cSMiquel Raynal *
462*cfcc706cSMiquel Raynal * @param info nand_info structure
463*cfcc706cSMiquel Raynal * @param *reg_val address of reg_val
464*cfcc706cSMiquel Raynal * @return 0 if ok, -1 on error
465*cfcc706cSMiquel Raynal */
set_bus_width_page_size(struct mtd_info * our_mtd,struct fdt_nand * config,u32 * reg_val)466*cfcc706cSMiquel Raynal static int set_bus_width_page_size(struct mtd_info *our_mtd,
467*cfcc706cSMiquel Raynal struct fdt_nand *config, u32 *reg_val)
468*cfcc706cSMiquel Raynal {
469*cfcc706cSMiquel Raynal if (config->width == 8)
470*cfcc706cSMiquel Raynal *reg_val = CFG_BUS_WIDTH_8BIT;
471*cfcc706cSMiquel Raynal else if (config->width == 16)
472*cfcc706cSMiquel Raynal *reg_val = CFG_BUS_WIDTH_16BIT;
473*cfcc706cSMiquel Raynal else {
474*cfcc706cSMiquel Raynal debug("%s: Unsupported bus width %d\n", __func__,
475*cfcc706cSMiquel Raynal config->width);
476*cfcc706cSMiquel Raynal return -1;
477*cfcc706cSMiquel Raynal }
478*cfcc706cSMiquel Raynal
479*cfcc706cSMiquel Raynal if (our_mtd->writesize == 512)
480*cfcc706cSMiquel Raynal *reg_val |= CFG_PAGE_SIZE_512;
481*cfcc706cSMiquel Raynal else if (our_mtd->writesize == 2048)
482*cfcc706cSMiquel Raynal *reg_val |= CFG_PAGE_SIZE_2048;
483*cfcc706cSMiquel Raynal else if (our_mtd->writesize == 4096)
484*cfcc706cSMiquel Raynal *reg_val |= CFG_PAGE_SIZE_4096;
485*cfcc706cSMiquel Raynal else {
486*cfcc706cSMiquel Raynal debug("%s: Unsupported page size %d\n", __func__,
487*cfcc706cSMiquel Raynal our_mtd->writesize);
488*cfcc706cSMiquel Raynal return -1;
489*cfcc706cSMiquel Raynal }
490*cfcc706cSMiquel Raynal
491*cfcc706cSMiquel Raynal return 0;
492*cfcc706cSMiquel Raynal }
493*cfcc706cSMiquel Raynal
494*cfcc706cSMiquel Raynal /**
495*cfcc706cSMiquel Raynal * Page read/write function
496*cfcc706cSMiquel Raynal *
497*cfcc706cSMiquel Raynal * @param mtd mtd info structure
498*cfcc706cSMiquel Raynal * @param chip nand chip info structure
499*cfcc706cSMiquel Raynal * @param buf data buffer
500*cfcc706cSMiquel Raynal * @param page page number
501*cfcc706cSMiquel Raynal * @param with_ecc 1 to enable ECC, 0 to disable ECC
502*cfcc706cSMiquel Raynal * @param is_writing 0 for read, 1 for write
503*cfcc706cSMiquel Raynal * @return 0 when successfully completed
504*cfcc706cSMiquel Raynal * -EIO when command timeout
505*cfcc706cSMiquel Raynal */
nand_rw_page(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int page,int with_ecc,int is_writing)506*cfcc706cSMiquel Raynal static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip,
507*cfcc706cSMiquel Raynal uint8_t *buf, int page, int with_ecc, int is_writing)
508*cfcc706cSMiquel Raynal {
509*cfcc706cSMiquel Raynal u32 reg_val;
510*cfcc706cSMiquel Raynal int tag_size;
511*cfcc706cSMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree;
512*cfcc706cSMiquel Raynal /* 4*128=512 (byte) is the value that our HW can support. */
513*cfcc706cSMiquel Raynal ALLOC_CACHE_ALIGN_BUFFER(u32, tag_buf, 128);
514*cfcc706cSMiquel Raynal char *tag_ptr;
515*cfcc706cSMiquel Raynal struct nand_drv *info;
516*cfcc706cSMiquel Raynal struct fdt_nand *config;
517*cfcc706cSMiquel Raynal unsigned int bbflags;
518*cfcc706cSMiquel Raynal struct bounce_buffer bbstate, bbstate_oob;
519*cfcc706cSMiquel Raynal
520*cfcc706cSMiquel Raynal if ((uintptr_t)buf & 0x03) {
521*cfcc706cSMiquel Raynal printf("buf %p has to be 4-byte aligned\n", buf);
522*cfcc706cSMiquel Raynal return -EINVAL;
523*cfcc706cSMiquel Raynal }
524*cfcc706cSMiquel Raynal
525*cfcc706cSMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip);
526*cfcc706cSMiquel Raynal config = &info->config;
527*cfcc706cSMiquel Raynal if (set_bus_width_page_size(mtd, config, ®_val))
528*cfcc706cSMiquel Raynal return -EINVAL;
529*cfcc706cSMiquel Raynal
530*cfcc706cSMiquel Raynal /* Need to be 4-byte aligned */
531*cfcc706cSMiquel Raynal tag_ptr = (char *)tag_buf;
532*cfcc706cSMiquel Raynal
533*cfcc706cSMiquel Raynal stop_command(info->reg);
534*cfcc706cSMiquel Raynal
535*cfcc706cSMiquel Raynal if (is_writing)
536*cfcc706cSMiquel Raynal bbflags = GEN_BB_READ;
537*cfcc706cSMiquel Raynal else
538*cfcc706cSMiquel Raynal bbflags = GEN_BB_WRITE;
539*cfcc706cSMiquel Raynal
540*cfcc706cSMiquel Raynal bounce_buffer_start(&bbstate, (void *)buf, 1 << chip->page_shift,
541*cfcc706cSMiquel Raynal bbflags);
542*cfcc706cSMiquel Raynal writel((1 << chip->page_shift) - 1, &info->reg->dma_cfg_a);
543*cfcc706cSMiquel Raynal writel(virt_to_phys(bbstate.bounce_buffer), &info->reg->data_block_ptr);
544*cfcc706cSMiquel Raynal
545*cfcc706cSMiquel Raynal /* Set ECC selection, configure ECC settings */
546*cfcc706cSMiquel Raynal if (with_ecc) {
547*cfcc706cSMiquel Raynal if (is_writing)
548*cfcc706cSMiquel Raynal memcpy(tag_ptr, chip->oob_poi + free->offset,
549*cfcc706cSMiquel Raynal chip->ecc.layout->oobavail + TAG_ECC_BYTES);
550*cfcc706cSMiquel Raynal tag_size = chip->ecc.layout->oobavail + TAG_ECC_BYTES;
551*cfcc706cSMiquel Raynal reg_val |= (CFG_SKIP_SPARE_SEL_4
552*cfcc706cSMiquel Raynal | CFG_SKIP_SPARE_ENABLE
553*cfcc706cSMiquel Raynal | CFG_HW_ECC_CORRECTION_ENABLE
554*cfcc706cSMiquel Raynal | CFG_ECC_EN_TAG_DISABLE
555*cfcc706cSMiquel Raynal | CFG_HW_ECC_SEL_RS
556*cfcc706cSMiquel Raynal | CFG_HW_ECC_ENABLE
557*cfcc706cSMiquel Raynal | CFG_TVAL4
558*cfcc706cSMiquel Raynal | (tag_size - 1));
559*cfcc706cSMiquel Raynal
560*cfcc706cSMiquel Raynal if (!is_writing)
561*cfcc706cSMiquel Raynal tag_size += SKIPPED_SPARE_BYTES;
562*cfcc706cSMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)tag_ptr, tag_size,
563*cfcc706cSMiquel Raynal bbflags);
564*cfcc706cSMiquel Raynal } else {
565*cfcc706cSMiquel Raynal tag_size = mtd->oobsize;
566*cfcc706cSMiquel Raynal reg_val |= (CFG_SKIP_SPARE_DISABLE
567*cfcc706cSMiquel Raynal | CFG_HW_ECC_CORRECTION_DISABLE
568*cfcc706cSMiquel Raynal | CFG_ECC_EN_TAG_DISABLE
569*cfcc706cSMiquel Raynal | CFG_HW_ECC_DISABLE
570*cfcc706cSMiquel Raynal | (tag_size - 1));
571*cfcc706cSMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi,
572*cfcc706cSMiquel Raynal tag_size, bbflags);
573*cfcc706cSMiquel Raynal }
574*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->config);
575*cfcc706cSMiquel Raynal writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr);
576*cfcc706cSMiquel Raynal writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config);
577*cfcc706cSMiquel Raynal writel(tag_size - 1, &info->reg->dma_cfg_b);
578*cfcc706cSMiquel Raynal
579*cfcc706cSMiquel Raynal nand_clear_interrupt_status(info->reg);
580*cfcc706cSMiquel Raynal
581*cfcc706cSMiquel Raynal reg_val = CMD_CLE | CMD_ALE
582*cfcc706cSMiquel Raynal | CMD_SEC_CMD
583*cfcc706cSMiquel Raynal | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT)
584*cfcc706cSMiquel Raynal | CMD_A_VALID
585*cfcc706cSMiquel Raynal | CMD_B_VALID
586*cfcc706cSMiquel Raynal | (CMD_TRANS_SIZE_PAGE << CMD_TRANS_SIZE_SHIFT)
587*cfcc706cSMiquel Raynal | CMD_CE0;
588*cfcc706cSMiquel Raynal if (!is_writing)
589*cfcc706cSMiquel Raynal reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX);
590*cfcc706cSMiquel Raynal else
591*cfcc706cSMiquel Raynal reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX);
592*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->command);
593*cfcc706cSMiquel Raynal
594*cfcc706cSMiquel Raynal /* Setup DMA engine */
595*cfcc706cSMiquel Raynal reg_val = DMA_MST_CTRL_GO_ENABLE
596*cfcc706cSMiquel Raynal | DMA_MST_CTRL_BURST_8WORDS
597*cfcc706cSMiquel Raynal | DMA_MST_CTRL_EN_A_ENABLE
598*cfcc706cSMiquel Raynal | DMA_MST_CTRL_EN_B_ENABLE;
599*cfcc706cSMiquel Raynal
600*cfcc706cSMiquel Raynal if (!is_writing)
601*cfcc706cSMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_READ;
602*cfcc706cSMiquel Raynal else
603*cfcc706cSMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_WRITE;
604*cfcc706cSMiquel Raynal
605*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->dma_mst_ctrl);
606*cfcc706cSMiquel Raynal
607*cfcc706cSMiquel Raynal start_command(info->reg);
608*cfcc706cSMiquel Raynal
609*cfcc706cSMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) {
610*cfcc706cSMiquel Raynal if (!is_writing)
611*cfcc706cSMiquel Raynal printf("Read Page 0x%X timeout ", page);
612*cfcc706cSMiquel Raynal else
613*cfcc706cSMiquel Raynal printf("Write Page 0x%X timeout ", page);
614*cfcc706cSMiquel Raynal if (with_ecc)
615*cfcc706cSMiquel Raynal printf("with ECC");
616*cfcc706cSMiquel Raynal else
617*cfcc706cSMiquel Raynal printf("without ECC");
618*cfcc706cSMiquel Raynal printf("\n");
619*cfcc706cSMiquel Raynal return -EIO;
620*cfcc706cSMiquel Raynal }
621*cfcc706cSMiquel Raynal
622*cfcc706cSMiquel Raynal bounce_buffer_stop(&bbstate_oob);
623*cfcc706cSMiquel Raynal bounce_buffer_stop(&bbstate);
624*cfcc706cSMiquel Raynal
625*cfcc706cSMiquel Raynal if (with_ecc && !is_writing) {
626*cfcc706cSMiquel Raynal memcpy(chip->oob_poi, tag_ptr,
627*cfcc706cSMiquel Raynal SKIPPED_SPARE_BYTES);
628*cfcc706cSMiquel Raynal memcpy(chip->oob_poi + free->offset,
629*cfcc706cSMiquel Raynal tag_ptr + SKIPPED_SPARE_BYTES,
630*cfcc706cSMiquel Raynal chip->ecc.layout->oobavail);
631*cfcc706cSMiquel Raynal reg_val = (u32)check_ecc_error(info->reg, (u8 *)buf,
632*cfcc706cSMiquel Raynal 1 << chip->page_shift,
633*cfcc706cSMiquel Raynal (u8 *)(tag_ptr + SKIPPED_SPARE_BYTES),
634*cfcc706cSMiquel Raynal chip->ecc.layout->oobavail);
635*cfcc706cSMiquel Raynal if (reg_val & ECC_TAG_ERROR)
636*cfcc706cSMiquel Raynal printf("Read Page 0x%X tag ECC error\n", page);
637*cfcc706cSMiquel Raynal if (reg_val & ECC_DATA_ERROR)
638*cfcc706cSMiquel Raynal printf("Read Page 0x%X data ECC error\n",
639*cfcc706cSMiquel Raynal page);
640*cfcc706cSMiquel Raynal if (reg_val & (ECC_DATA_ERROR | ECC_TAG_ERROR))
641*cfcc706cSMiquel Raynal return -EIO;
642*cfcc706cSMiquel Raynal }
643*cfcc706cSMiquel Raynal return 0;
644*cfcc706cSMiquel Raynal }
645*cfcc706cSMiquel Raynal
646*cfcc706cSMiquel Raynal /**
647*cfcc706cSMiquel Raynal * Hardware ecc based page read function
648*cfcc706cSMiquel Raynal *
649*cfcc706cSMiquel Raynal * @param mtd mtd info structure
650*cfcc706cSMiquel Raynal * @param chip nand chip info structure
651*cfcc706cSMiquel Raynal * @param buf buffer to store read data
652*cfcc706cSMiquel Raynal * @param page page number to read
653*cfcc706cSMiquel Raynal * @return 0 when successfully completed
654*cfcc706cSMiquel Raynal * -EIO when command timeout
655*cfcc706cSMiquel Raynal */
nand_read_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)656*cfcc706cSMiquel Raynal static int nand_read_page_hwecc(struct mtd_info *mtd,
657*cfcc706cSMiquel Raynal struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
658*cfcc706cSMiquel Raynal {
659*cfcc706cSMiquel Raynal return nand_rw_page(mtd, chip, buf, page, 1, 0);
660*cfcc706cSMiquel Raynal }
661*cfcc706cSMiquel Raynal
662*cfcc706cSMiquel Raynal /**
663*cfcc706cSMiquel Raynal * Hardware ecc based page write function
664*cfcc706cSMiquel Raynal *
665*cfcc706cSMiquel Raynal * @param mtd mtd info structure
666*cfcc706cSMiquel Raynal * @param chip nand chip info structure
667*cfcc706cSMiquel Raynal * @param buf data buffer
668*cfcc706cSMiquel Raynal */
nand_write_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)669*cfcc706cSMiquel Raynal static int nand_write_page_hwecc(struct mtd_info *mtd,
670*cfcc706cSMiquel Raynal struct nand_chip *chip, const uint8_t *buf, int oob_required,
671*cfcc706cSMiquel Raynal int page)
672*cfcc706cSMiquel Raynal {
673*cfcc706cSMiquel Raynal nand_rw_page(mtd, chip, (uint8_t *)buf, page, 1, 1);
674*cfcc706cSMiquel Raynal return 0;
675*cfcc706cSMiquel Raynal }
676*cfcc706cSMiquel Raynal
677*cfcc706cSMiquel Raynal
678*cfcc706cSMiquel Raynal /**
679*cfcc706cSMiquel Raynal * Read raw page data without ecc
680*cfcc706cSMiquel Raynal *
681*cfcc706cSMiquel Raynal * @param mtd mtd info structure
682*cfcc706cSMiquel Raynal * @param chip nand chip info structure
683*cfcc706cSMiquel Raynal * @param buf buffer to store read data
684*cfcc706cSMiquel Raynal * @param page page number to read
685*cfcc706cSMiquel Raynal * @return 0 when successfully completed
686*cfcc706cSMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned
687*cfcc706cSMiquel Raynal * -EIO when command timeout
688*cfcc706cSMiquel Raynal */
nand_read_page_raw(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)689*cfcc706cSMiquel Raynal static int nand_read_page_raw(struct mtd_info *mtd,
690*cfcc706cSMiquel Raynal struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
691*cfcc706cSMiquel Raynal {
692*cfcc706cSMiquel Raynal return nand_rw_page(mtd, chip, buf, page, 0, 0);
693*cfcc706cSMiquel Raynal }
694*cfcc706cSMiquel Raynal
695*cfcc706cSMiquel Raynal /**
696*cfcc706cSMiquel Raynal * Raw page write function
697*cfcc706cSMiquel Raynal *
698*cfcc706cSMiquel Raynal * @param mtd mtd info structure
699*cfcc706cSMiquel Raynal * @param chip nand chip info structure
700*cfcc706cSMiquel Raynal * @param buf data buffer
701*cfcc706cSMiquel Raynal */
nand_write_page_raw(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)702*cfcc706cSMiquel Raynal static int nand_write_page_raw(struct mtd_info *mtd,
703*cfcc706cSMiquel Raynal struct nand_chip *chip, const uint8_t *buf,
704*cfcc706cSMiquel Raynal int oob_required, int page)
705*cfcc706cSMiquel Raynal {
706*cfcc706cSMiquel Raynal nand_rw_page(mtd, chip, (uint8_t *)buf, page, 0, 1);
707*cfcc706cSMiquel Raynal return 0;
708*cfcc706cSMiquel Raynal }
709*cfcc706cSMiquel Raynal
710*cfcc706cSMiquel Raynal /**
711*cfcc706cSMiquel Raynal * OOB data read/write function
712*cfcc706cSMiquel Raynal *
713*cfcc706cSMiquel Raynal * @param mtd mtd info structure
714*cfcc706cSMiquel Raynal * @param chip nand chip info structure
715*cfcc706cSMiquel Raynal * @param page page number to read
716*cfcc706cSMiquel Raynal * @param with_ecc 1 to enable ECC, 0 to disable ECC
717*cfcc706cSMiquel Raynal * @param is_writing 0 for read, 1 for write
718*cfcc706cSMiquel Raynal * @return 0 when successfully completed
719*cfcc706cSMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned
720*cfcc706cSMiquel Raynal * -EIO when command timeout
721*cfcc706cSMiquel Raynal */
nand_rw_oob(struct mtd_info * mtd,struct nand_chip * chip,int page,int with_ecc,int is_writing)722*cfcc706cSMiquel Raynal static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip,
723*cfcc706cSMiquel Raynal int page, int with_ecc, int is_writing)
724*cfcc706cSMiquel Raynal {
725*cfcc706cSMiquel Raynal u32 reg_val;
726*cfcc706cSMiquel Raynal int tag_size;
727*cfcc706cSMiquel Raynal struct nand_oobfree *free = chip->ecc.layout->oobfree;
728*cfcc706cSMiquel Raynal struct nand_drv *info;
729*cfcc706cSMiquel Raynal unsigned int bbflags;
730*cfcc706cSMiquel Raynal struct bounce_buffer bbstate_oob;
731*cfcc706cSMiquel Raynal
732*cfcc706cSMiquel Raynal if (((int)chip->oob_poi) & 0x03)
733*cfcc706cSMiquel Raynal return -EINVAL;
734*cfcc706cSMiquel Raynal info = (struct nand_drv *)nand_get_controller_data(chip);
735*cfcc706cSMiquel Raynal if (set_bus_width_page_size(mtd, &info->config, ®_val))
736*cfcc706cSMiquel Raynal return -EINVAL;
737*cfcc706cSMiquel Raynal
738*cfcc706cSMiquel Raynal stop_command(info->reg);
739*cfcc706cSMiquel Raynal
740*cfcc706cSMiquel Raynal /* Set ECC selection */
741*cfcc706cSMiquel Raynal tag_size = mtd->oobsize;
742*cfcc706cSMiquel Raynal if (with_ecc)
743*cfcc706cSMiquel Raynal reg_val |= CFG_ECC_EN_TAG_ENABLE;
744*cfcc706cSMiquel Raynal else
745*cfcc706cSMiquel Raynal reg_val |= (CFG_ECC_EN_TAG_DISABLE);
746*cfcc706cSMiquel Raynal
747*cfcc706cSMiquel Raynal reg_val |= ((tag_size - 1) |
748*cfcc706cSMiquel Raynal CFG_SKIP_SPARE_DISABLE |
749*cfcc706cSMiquel Raynal CFG_HW_ECC_CORRECTION_DISABLE |
750*cfcc706cSMiquel Raynal CFG_HW_ECC_DISABLE);
751*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->config);
752*cfcc706cSMiquel Raynal
753*cfcc706cSMiquel Raynal if (is_writing && with_ecc)
754*cfcc706cSMiquel Raynal tag_size -= TAG_ECC_BYTES;
755*cfcc706cSMiquel Raynal
756*cfcc706cSMiquel Raynal if (is_writing)
757*cfcc706cSMiquel Raynal bbflags = GEN_BB_READ;
758*cfcc706cSMiquel Raynal else
759*cfcc706cSMiquel Raynal bbflags = GEN_BB_WRITE;
760*cfcc706cSMiquel Raynal
761*cfcc706cSMiquel Raynal bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, tag_size,
762*cfcc706cSMiquel Raynal bbflags);
763*cfcc706cSMiquel Raynal writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr);
764*cfcc706cSMiquel Raynal
765*cfcc706cSMiquel Raynal writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config);
766*cfcc706cSMiquel Raynal
767*cfcc706cSMiquel Raynal writel(tag_size - 1, &info->reg->dma_cfg_b);
768*cfcc706cSMiquel Raynal
769*cfcc706cSMiquel Raynal nand_clear_interrupt_status(info->reg);
770*cfcc706cSMiquel Raynal
771*cfcc706cSMiquel Raynal reg_val = CMD_CLE | CMD_ALE
772*cfcc706cSMiquel Raynal | CMD_SEC_CMD
773*cfcc706cSMiquel Raynal | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT)
774*cfcc706cSMiquel Raynal | CMD_B_VALID
775*cfcc706cSMiquel Raynal | CMD_CE0;
776*cfcc706cSMiquel Raynal if (!is_writing)
777*cfcc706cSMiquel Raynal reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX);
778*cfcc706cSMiquel Raynal else
779*cfcc706cSMiquel Raynal reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX);
780*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->command);
781*cfcc706cSMiquel Raynal
782*cfcc706cSMiquel Raynal /* Setup DMA engine */
783*cfcc706cSMiquel Raynal reg_val = DMA_MST_CTRL_GO_ENABLE
784*cfcc706cSMiquel Raynal | DMA_MST_CTRL_BURST_8WORDS
785*cfcc706cSMiquel Raynal | DMA_MST_CTRL_EN_B_ENABLE;
786*cfcc706cSMiquel Raynal if (!is_writing)
787*cfcc706cSMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_READ;
788*cfcc706cSMiquel Raynal else
789*cfcc706cSMiquel Raynal reg_val |= DMA_MST_CTRL_DIR_WRITE;
790*cfcc706cSMiquel Raynal
791*cfcc706cSMiquel Raynal writel(reg_val, &info->reg->dma_mst_ctrl);
792*cfcc706cSMiquel Raynal
793*cfcc706cSMiquel Raynal start_command(info->reg);
794*cfcc706cSMiquel Raynal
795*cfcc706cSMiquel Raynal if (!nand_waitfor_cmd_completion(info->reg)) {
796*cfcc706cSMiquel Raynal if (!is_writing)
797*cfcc706cSMiquel Raynal printf("Read OOB of Page 0x%X timeout\n", page);
798*cfcc706cSMiquel Raynal else
799*cfcc706cSMiquel Raynal printf("Write OOB of Page 0x%X timeout\n", page);
800*cfcc706cSMiquel Raynal return -EIO;
801*cfcc706cSMiquel Raynal }
802*cfcc706cSMiquel Raynal
803*cfcc706cSMiquel Raynal bounce_buffer_stop(&bbstate_oob);
804*cfcc706cSMiquel Raynal
805*cfcc706cSMiquel Raynal if (with_ecc && !is_writing) {
806*cfcc706cSMiquel Raynal reg_val = (u32)check_ecc_error(info->reg, 0, 0,
807*cfcc706cSMiquel Raynal (u8 *)(chip->oob_poi + free->offset),
808*cfcc706cSMiquel Raynal chip->ecc.layout->oobavail);
809*cfcc706cSMiquel Raynal if (reg_val & ECC_TAG_ERROR)
810*cfcc706cSMiquel Raynal printf("Read OOB of Page 0x%X tag ECC error\n", page);
811*cfcc706cSMiquel Raynal }
812*cfcc706cSMiquel Raynal return 0;
813*cfcc706cSMiquel Raynal }
814*cfcc706cSMiquel Raynal
815*cfcc706cSMiquel Raynal /**
816*cfcc706cSMiquel Raynal * OOB data read function
817*cfcc706cSMiquel Raynal *
818*cfcc706cSMiquel Raynal * @param mtd mtd info structure
819*cfcc706cSMiquel Raynal * @param chip nand chip info structure
820*cfcc706cSMiquel Raynal * @param page page number to read
821*cfcc706cSMiquel Raynal */
nand_read_oob(struct mtd_info * mtd,struct nand_chip * chip,int page)822*cfcc706cSMiquel Raynal static int nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
823*cfcc706cSMiquel Raynal int page)
824*cfcc706cSMiquel Raynal {
825*cfcc706cSMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
826*cfcc706cSMiquel Raynal nand_rw_oob(mtd, chip, page, 0, 0);
827*cfcc706cSMiquel Raynal return 0;
828*cfcc706cSMiquel Raynal }
829*cfcc706cSMiquel Raynal
830*cfcc706cSMiquel Raynal /**
831*cfcc706cSMiquel Raynal * OOB data write function
832*cfcc706cSMiquel Raynal *
833*cfcc706cSMiquel Raynal * @param mtd mtd info structure
834*cfcc706cSMiquel Raynal * @param chip nand chip info structure
835*cfcc706cSMiquel Raynal * @param page page number to write
836*cfcc706cSMiquel Raynal * @return 0 when successfully completed
837*cfcc706cSMiquel Raynal * -EINVAL when chip->oob_poi is not double-word aligned
838*cfcc706cSMiquel Raynal * -EIO when command timeout
839*cfcc706cSMiquel Raynal */
nand_write_oob(struct mtd_info * mtd,struct nand_chip * chip,int page)840*cfcc706cSMiquel Raynal static int nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
841*cfcc706cSMiquel Raynal int page)
842*cfcc706cSMiquel Raynal {
843*cfcc706cSMiquel Raynal chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
844*cfcc706cSMiquel Raynal
845*cfcc706cSMiquel Raynal return nand_rw_oob(mtd, chip, page, 0, 1);
846*cfcc706cSMiquel Raynal }
847*cfcc706cSMiquel Raynal
848*cfcc706cSMiquel Raynal /**
849*cfcc706cSMiquel Raynal * Set up NAND memory timings according to the provided parameters
850*cfcc706cSMiquel Raynal *
851*cfcc706cSMiquel Raynal * @param timing Timing parameters
852*cfcc706cSMiquel Raynal * @param reg NAND controller register address
853*cfcc706cSMiquel Raynal */
setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT],struct nand_ctlr * reg)854*cfcc706cSMiquel Raynal static void setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT],
855*cfcc706cSMiquel Raynal struct nand_ctlr *reg)
856*cfcc706cSMiquel Raynal {
857*cfcc706cSMiquel Raynal u32 reg_val, clk_rate, clk_period, time_val;
858*cfcc706cSMiquel Raynal
859*cfcc706cSMiquel Raynal clk_rate = (u32)clock_get_periph_rate(PERIPH_ID_NDFLASH,
860*cfcc706cSMiquel Raynal CLOCK_ID_PERIPH) / 1000000;
861*cfcc706cSMiquel Raynal clk_period = 1000 / clk_rate;
862*cfcc706cSMiquel Raynal reg_val = ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) <<
863*cfcc706cSMiquel Raynal TIMING_TRP_RESP_CNT_SHIFT) & TIMING_TRP_RESP_CNT_MASK;
864*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_TWB] / clk_period) <<
865*cfcc706cSMiquel Raynal TIMING_TWB_CNT_SHIFT) & TIMING_TWB_CNT_MASK;
866*cfcc706cSMiquel Raynal time_val = timing[FDT_NAND_MAX_TCR_TAR_TRR] / clk_period;
867*cfcc706cSMiquel Raynal if (time_val > 2)
868*cfcc706cSMiquel Raynal reg_val |= ((time_val - 2) << TIMING_TCR_TAR_TRR_CNT_SHIFT) &
869*cfcc706cSMiquel Raynal TIMING_TCR_TAR_TRR_CNT_MASK;
870*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_TWHR] / clk_period) <<
871*cfcc706cSMiquel Raynal TIMING_TWHR_CNT_SHIFT) & TIMING_TWHR_CNT_MASK;
872*cfcc706cSMiquel Raynal time_val = timing[FDT_NAND_MAX_TCS_TCH_TALS_TALH] / clk_period;
873*cfcc706cSMiquel Raynal if (time_val > 1)
874*cfcc706cSMiquel Raynal reg_val |= ((time_val - 1) << TIMING_TCS_CNT_SHIFT) &
875*cfcc706cSMiquel Raynal TIMING_TCS_CNT_MASK;
876*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_TWH] / clk_period) <<
877*cfcc706cSMiquel Raynal TIMING_TWH_CNT_SHIFT) & TIMING_TWH_CNT_MASK;
878*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_TWP] / clk_period) <<
879*cfcc706cSMiquel Raynal TIMING_TWP_CNT_SHIFT) & TIMING_TWP_CNT_MASK;
880*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_TRH] / clk_period) <<
881*cfcc706cSMiquel Raynal TIMING_TRH_CNT_SHIFT) & TIMING_TRH_CNT_MASK;
882*cfcc706cSMiquel Raynal reg_val |= ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) <<
883*cfcc706cSMiquel Raynal TIMING_TRP_CNT_SHIFT) & TIMING_TRP_CNT_MASK;
884*cfcc706cSMiquel Raynal writel(reg_val, ®->timing);
885*cfcc706cSMiquel Raynal
886*cfcc706cSMiquel Raynal reg_val = 0;
887*cfcc706cSMiquel Raynal time_val = timing[FDT_NAND_TADL] / clk_period;
888*cfcc706cSMiquel Raynal if (time_val > 2)
889*cfcc706cSMiquel Raynal reg_val = (time_val - 2) & TIMING2_TADL_CNT_MASK;
890*cfcc706cSMiquel Raynal writel(reg_val, ®->timing2);
891*cfcc706cSMiquel Raynal }
892*cfcc706cSMiquel Raynal
893*cfcc706cSMiquel Raynal /**
894*cfcc706cSMiquel Raynal * Decode NAND parameters from the device tree
895*cfcc706cSMiquel Raynal *
896*cfcc706cSMiquel Raynal * @param dev Driver model device
897*cfcc706cSMiquel Raynal * @param config Device tree NAND configuration
898*cfcc706cSMiquel Raynal * @return 0 if ok, -ve on error (FDT_ERR_...)
899*cfcc706cSMiquel Raynal */
fdt_decode_nand(struct udevice * dev,struct fdt_nand * config)900*cfcc706cSMiquel Raynal static int fdt_decode_nand(struct udevice *dev, struct fdt_nand *config)
901*cfcc706cSMiquel Raynal {
902*cfcc706cSMiquel Raynal int err;
903*cfcc706cSMiquel Raynal
904*cfcc706cSMiquel Raynal config->reg = (struct nand_ctlr *)dev_read_addr(dev);
905*cfcc706cSMiquel Raynal config->enabled = dev_read_enabled(dev);
906*cfcc706cSMiquel Raynal config->width = dev_read_u32_default(dev, "nvidia,nand-width", 8);
907*cfcc706cSMiquel Raynal err = gpio_request_by_name(dev, "nvidia,wp-gpios", 0, &config->wp_gpio,
908*cfcc706cSMiquel Raynal GPIOD_IS_OUT);
909*cfcc706cSMiquel Raynal if (err)
910*cfcc706cSMiquel Raynal return err;
911*cfcc706cSMiquel Raynal err = dev_read_u32_array(dev, "nvidia,timing", config->timing,
912*cfcc706cSMiquel Raynal FDT_NAND_TIMING_COUNT);
913*cfcc706cSMiquel Raynal if (err < 0)
914*cfcc706cSMiquel Raynal return err;
915*cfcc706cSMiquel Raynal
916*cfcc706cSMiquel Raynal return 0;
917*cfcc706cSMiquel Raynal }
918*cfcc706cSMiquel Raynal
tegra_probe(struct udevice * dev)919*cfcc706cSMiquel Raynal static int tegra_probe(struct udevice *dev)
920*cfcc706cSMiquel Raynal {
921*cfcc706cSMiquel Raynal struct tegra_nand_info *tegra = dev_get_priv(dev);
922*cfcc706cSMiquel Raynal struct nand_chip *nand = &tegra->nand_chip;
923*cfcc706cSMiquel Raynal struct nand_drv *info = &tegra->nand_ctrl;
924*cfcc706cSMiquel Raynal struct fdt_nand *config = &info->config;
925*cfcc706cSMiquel Raynal struct mtd_info *our_mtd;
926*cfcc706cSMiquel Raynal int ret;
927*cfcc706cSMiquel Raynal
928*cfcc706cSMiquel Raynal if (fdt_decode_nand(dev, config)) {
929*cfcc706cSMiquel Raynal printf("Could not decode nand-flash in device tree\n");
930*cfcc706cSMiquel Raynal return -1;
931*cfcc706cSMiquel Raynal }
932*cfcc706cSMiquel Raynal if (!config->enabled)
933*cfcc706cSMiquel Raynal return -1;
934*cfcc706cSMiquel Raynal info->reg = config->reg;
935*cfcc706cSMiquel Raynal nand->ecc.mode = NAND_ECC_HW;
936*cfcc706cSMiquel Raynal nand->ecc.layout = &eccoob;
937*cfcc706cSMiquel Raynal
938*cfcc706cSMiquel Raynal nand->options = LP_OPTIONS;
939*cfcc706cSMiquel Raynal nand->cmdfunc = nand_command;
940*cfcc706cSMiquel Raynal nand->read_byte = read_byte;
941*cfcc706cSMiquel Raynal nand->read_buf = read_buf;
942*cfcc706cSMiquel Raynal nand->ecc.read_page = nand_read_page_hwecc;
943*cfcc706cSMiquel Raynal nand->ecc.write_page = nand_write_page_hwecc;
944*cfcc706cSMiquel Raynal nand->ecc.read_page_raw = nand_read_page_raw;
945*cfcc706cSMiquel Raynal nand->ecc.write_page_raw = nand_write_page_raw;
946*cfcc706cSMiquel Raynal nand->ecc.read_oob = nand_read_oob;
947*cfcc706cSMiquel Raynal nand->ecc.write_oob = nand_write_oob;
948*cfcc706cSMiquel Raynal nand->ecc.strength = 1;
949*cfcc706cSMiquel Raynal nand->select_chip = nand_select_chip;
950*cfcc706cSMiquel Raynal nand->dev_ready = nand_dev_ready;
951*cfcc706cSMiquel Raynal nand_set_controller_data(nand, &tegra->nand_ctrl);
952*cfcc706cSMiquel Raynal
953*cfcc706cSMiquel Raynal /* Disable subpage writes as we do not provide ecc->hwctl */
954*cfcc706cSMiquel Raynal nand->options |= NAND_NO_SUBPAGE_WRITE;
955*cfcc706cSMiquel Raynal
956*cfcc706cSMiquel Raynal /* Adjust controller clock rate */
957*cfcc706cSMiquel Raynal clock_start_periph_pll(PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH, 52000000);
958*cfcc706cSMiquel Raynal
959*cfcc706cSMiquel Raynal /* Adjust timing for NAND device */
960*cfcc706cSMiquel Raynal setup_timing(config->timing, info->reg);
961*cfcc706cSMiquel Raynal
962*cfcc706cSMiquel Raynal dm_gpio_set_value(&config->wp_gpio, 1);
963*cfcc706cSMiquel Raynal
964*cfcc706cSMiquel Raynal our_mtd = nand_to_mtd(nand);
965*cfcc706cSMiquel Raynal ret = nand_scan_ident(our_mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
966*cfcc706cSMiquel Raynal if (ret)
967*cfcc706cSMiquel Raynal return ret;
968*cfcc706cSMiquel Raynal
969*cfcc706cSMiquel Raynal nand->ecc.size = our_mtd->writesize;
970*cfcc706cSMiquel Raynal nand->ecc.bytes = our_mtd->oobsize;
971*cfcc706cSMiquel Raynal
972*cfcc706cSMiquel Raynal ret = nand_scan_tail(our_mtd);
973*cfcc706cSMiquel Raynal if (ret)
974*cfcc706cSMiquel Raynal return ret;
975*cfcc706cSMiquel Raynal
976*cfcc706cSMiquel Raynal ret = nand_register(0, our_mtd);
977*cfcc706cSMiquel Raynal if (ret) {
978*cfcc706cSMiquel Raynal dev_err(dev, "Failed to register MTD: %d\n", ret);
979*cfcc706cSMiquel Raynal return ret;
980*cfcc706cSMiquel Raynal }
981*cfcc706cSMiquel Raynal
982*cfcc706cSMiquel Raynal return 0;
983*cfcc706cSMiquel Raynal }
984*cfcc706cSMiquel Raynal
985*cfcc706cSMiquel Raynal U_BOOT_DRIVER(tegra_nand) = {
986*cfcc706cSMiquel Raynal .name = "tegra-nand",
987*cfcc706cSMiquel Raynal .id = UCLASS_MTD,
988*cfcc706cSMiquel Raynal .of_match = tegra_nand_dt_ids,
989*cfcc706cSMiquel Raynal .probe = tegra_probe,
990*cfcc706cSMiquel Raynal .priv_auto_alloc_size = sizeof(struct tegra_nand_info),
991*cfcc706cSMiquel Raynal };
992*cfcc706cSMiquel Raynal
board_nand_init(void)993*cfcc706cSMiquel Raynal void board_nand_init(void)
994*cfcc706cSMiquel Raynal {
995*cfcc706cSMiquel Raynal struct udevice *dev;
996*cfcc706cSMiquel Raynal int ret;
997*cfcc706cSMiquel Raynal
998*cfcc706cSMiquel Raynal ret = uclass_get_device_by_driver(UCLASS_MTD,
999*cfcc706cSMiquel Raynal DM_GET_DRIVER(tegra_nand), &dev);
1000*cfcc706cSMiquel Raynal if (ret && ret != -ENODEV)
1001*cfcc706cSMiquel Raynal pr_err("Failed to initialize %s. (error %d)\n", dev->name,
1002*cfcc706cSMiquel Raynal ret);
1003*cfcc706cSMiquel Raynal }
1004