1*cfcc706cSMiquel Raynal /* Integrated Flash Controller NAND Machine Driver
2*cfcc706cSMiquel Raynal *
3*cfcc706cSMiquel Raynal * Copyright (c) 2012 Freescale Semiconductor, Inc
4*cfcc706cSMiquel Raynal *
5*cfcc706cSMiquel Raynal * Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com>
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 <malloc.h>
12*cfcc706cSMiquel Raynal #include <nand.h>
13*cfcc706cSMiquel Raynal
14*cfcc706cSMiquel Raynal #include <linux/mtd/mtd.h>
15*cfcc706cSMiquel Raynal #include <linux/mtd/rawnand.h>
16*cfcc706cSMiquel Raynal #include <linux/mtd/nand_ecc.h>
17*cfcc706cSMiquel Raynal
18*cfcc706cSMiquel Raynal #include <asm/io.h>
19*cfcc706cSMiquel Raynal #include <linux/errno.h>
20*cfcc706cSMiquel Raynal #include <fsl_ifc.h>
21*cfcc706cSMiquel Raynal
22*cfcc706cSMiquel Raynal #ifndef CONFIG_SYS_FSL_IFC_BANK_COUNT
23*cfcc706cSMiquel Raynal #define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
24*cfcc706cSMiquel Raynal #endif
25*cfcc706cSMiquel Raynal
26*cfcc706cSMiquel Raynal #define MAX_BANKS CONFIG_SYS_FSL_IFC_BANK_COUNT
27*cfcc706cSMiquel Raynal #define ERR_BYTE 0xFF /* Value returned for read bytes
28*cfcc706cSMiquel Raynal when read failed */
29*cfcc706cSMiquel Raynal
30*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl;
31*cfcc706cSMiquel Raynal
32*cfcc706cSMiquel Raynal /* mtd information per set */
33*cfcc706cSMiquel Raynal struct fsl_ifc_mtd {
34*cfcc706cSMiquel Raynal struct nand_chip chip;
35*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl;
36*cfcc706cSMiquel Raynal
37*cfcc706cSMiquel Raynal struct device *dev;
38*cfcc706cSMiquel Raynal int bank; /* Chip select bank number */
39*cfcc706cSMiquel Raynal unsigned int bufnum_mask; /* bufnum = page & bufnum_mask */
40*cfcc706cSMiquel Raynal u8 __iomem *vbase; /* Chip select base virtual address */
41*cfcc706cSMiquel Raynal };
42*cfcc706cSMiquel Raynal
43*cfcc706cSMiquel Raynal /* overview of the fsl ifc controller */
44*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl {
45*cfcc706cSMiquel Raynal struct nand_hw_control controller;
46*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *chips[MAX_BANKS];
47*cfcc706cSMiquel Raynal
48*cfcc706cSMiquel Raynal /* device info */
49*cfcc706cSMiquel Raynal struct fsl_ifc regs;
50*cfcc706cSMiquel Raynal void __iomem *addr; /* Address of assigned IFC buffer */
51*cfcc706cSMiquel Raynal unsigned int page; /* Last page written to / read from */
52*cfcc706cSMiquel Raynal unsigned int read_bytes; /* Number of bytes read during command */
53*cfcc706cSMiquel Raynal unsigned int column; /* Saved column from SEQIN */
54*cfcc706cSMiquel Raynal unsigned int index; /* Pointer to next byte to 'read' */
55*cfcc706cSMiquel Raynal unsigned int status; /* status read from NEESR after last op */
56*cfcc706cSMiquel Raynal unsigned int oob; /* Non zero if operating on OOB data */
57*cfcc706cSMiquel Raynal unsigned int eccread; /* Non zero for a full-page ECC read */
58*cfcc706cSMiquel Raynal };
59*cfcc706cSMiquel Raynal
60*cfcc706cSMiquel Raynal static struct fsl_ifc_ctrl *ifc_ctrl;
61*cfcc706cSMiquel Raynal
62*cfcc706cSMiquel Raynal /* 512-byte page with 4-bit ECC, 8-bit */
63*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_512_8bit_ecc4 = {
64*cfcc706cSMiquel Raynal .eccbytes = 8,
65*cfcc706cSMiquel Raynal .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
66*cfcc706cSMiquel Raynal .oobfree = { {0, 5}, {6, 2} },
67*cfcc706cSMiquel Raynal };
68*cfcc706cSMiquel Raynal
69*cfcc706cSMiquel Raynal /* 512-byte page with 4-bit ECC, 16-bit */
70*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_512_16bit_ecc4 = {
71*cfcc706cSMiquel Raynal .eccbytes = 8,
72*cfcc706cSMiquel Raynal .eccpos = {8, 9, 10, 11, 12, 13, 14, 15},
73*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, },
74*cfcc706cSMiquel Raynal };
75*cfcc706cSMiquel Raynal
76*cfcc706cSMiquel Raynal /* 2048-byte page size with 4-bit ECC */
77*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_2048_ecc4 = {
78*cfcc706cSMiquel Raynal .eccbytes = 32,
79*cfcc706cSMiquel Raynal .eccpos = {
80*cfcc706cSMiquel Raynal 8, 9, 10, 11, 12, 13, 14, 15,
81*cfcc706cSMiquel Raynal 16, 17, 18, 19, 20, 21, 22, 23,
82*cfcc706cSMiquel Raynal 24, 25, 26, 27, 28, 29, 30, 31,
83*cfcc706cSMiquel Raynal 32, 33, 34, 35, 36, 37, 38, 39,
84*cfcc706cSMiquel Raynal },
85*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, {40, 24} },
86*cfcc706cSMiquel Raynal };
87*cfcc706cSMiquel Raynal
88*cfcc706cSMiquel Raynal /* 4096-byte page size with 4-bit ECC */
89*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_4096_ecc4 = {
90*cfcc706cSMiquel Raynal .eccbytes = 64,
91*cfcc706cSMiquel Raynal .eccpos = {
92*cfcc706cSMiquel Raynal 8, 9, 10, 11, 12, 13, 14, 15,
93*cfcc706cSMiquel Raynal 16, 17, 18, 19, 20, 21, 22, 23,
94*cfcc706cSMiquel Raynal 24, 25, 26, 27, 28, 29, 30, 31,
95*cfcc706cSMiquel Raynal 32, 33, 34, 35, 36, 37, 38, 39,
96*cfcc706cSMiquel Raynal 40, 41, 42, 43, 44, 45, 46, 47,
97*cfcc706cSMiquel Raynal 48, 49, 50, 51, 52, 53, 54, 55,
98*cfcc706cSMiquel Raynal 56, 57, 58, 59, 60, 61, 62, 63,
99*cfcc706cSMiquel Raynal 64, 65, 66, 67, 68, 69, 70, 71,
100*cfcc706cSMiquel Raynal },
101*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, {72, 56} },
102*cfcc706cSMiquel Raynal };
103*cfcc706cSMiquel Raynal
104*cfcc706cSMiquel Raynal /* 4096-byte page size with 8-bit ECC -- requires 218-byte OOB */
105*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_4096_ecc8 = {
106*cfcc706cSMiquel Raynal .eccbytes = 128,
107*cfcc706cSMiquel Raynal .eccpos = {
108*cfcc706cSMiquel Raynal 8, 9, 10, 11, 12, 13, 14, 15,
109*cfcc706cSMiquel Raynal 16, 17, 18, 19, 20, 21, 22, 23,
110*cfcc706cSMiquel Raynal 24, 25, 26, 27, 28, 29, 30, 31,
111*cfcc706cSMiquel Raynal 32, 33, 34, 35, 36, 37, 38, 39,
112*cfcc706cSMiquel Raynal 40, 41, 42, 43, 44, 45, 46, 47,
113*cfcc706cSMiquel Raynal 48, 49, 50, 51, 52, 53, 54, 55,
114*cfcc706cSMiquel Raynal 56, 57, 58, 59, 60, 61, 62, 63,
115*cfcc706cSMiquel Raynal 64, 65, 66, 67, 68, 69, 70, 71,
116*cfcc706cSMiquel Raynal 72, 73, 74, 75, 76, 77, 78, 79,
117*cfcc706cSMiquel Raynal 80, 81, 82, 83, 84, 85, 86, 87,
118*cfcc706cSMiquel Raynal 88, 89, 90, 91, 92, 93, 94, 95,
119*cfcc706cSMiquel Raynal 96, 97, 98, 99, 100, 101, 102, 103,
120*cfcc706cSMiquel Raynal 104, 105, 106, 107, 108, 109, 110, 111,
121*cfcc706cSMiquel Raynal 112, 113, 114, 115, 116, 117, 118, 119,
122*cfcc706cSMiquel Raynal 120, 121, 122, 123, 124, 125, 126, 127,
123*cfcc706cSMiquel Raynal 128, 129, 130, 131, 132, 133, 134, 135,
124*cfcc706cSMiquel Raynal },
125*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, {136, 82} },
126*cfcc706cSMiquel Raynal };
127*cfcc706cSMiquel Raynal
128*cfcc706cSMiquel Raynal /* 8192-byte page size with 4-bit ECC */
129*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_8192_ecc4 = {
130*cfcc706cSMiquel Raynal .eccbytes = 128,
131*cfcc706cSMiquel Raynal .eccpos = {
132*cfcc706cSMiquel Raynal 8, 9, 10, 11, 12, 13, 14, 15,
133*cfcc706cSMiquel Raynal 16, 17, 18, 19, 20, 21, 22, 23,
134*cfcc706cSMiquel Raynal 24, 25, 26, 27, 28, 29, 30, 31,
135*cfcc706cSMiquel Raynal 32, 33, 34, 35, 36, 37, 38, 39,
136*cfcc706cSMiquel Raynal 40, 41, 42, 43, 44, 45, 46, 47,
137*cfcc706cSMiquel Raynal 48, 49, 50, 51, 52, 53, 54, 55,
138*cfcc706cSMiquel Raynal 56, 57, 58, 59, 60, 61, 62, 63,
139*cfcc706cSMiquel Raynal 64, 65, 66, 67, 68, 69, 70, 71,
140*cfcc706cSMiquel Raynal 72, 73, 74, 75, 76, 77, 78, 79,
141*cfcc706cSMiquel Raynal 80, 81, 82, 83, 84, 85, 86, 87,
142*cfcc706cSMiquel Raynal 88, 89, 90, 91, 92, 93, 94, 95,
143*cfcc706cSMiquel Raynal 96, 97, 98, 99, 100, 101, 102, 103,
144*cfcc706cSMiquel Raynal 104, 105, 106, 107, 108, 109, 110, 111,
145*cfcc706cSMiquel Raynal 112, 113, 114, 115, 116, 117, 118, 119,
146*cfcc706cSMiquel Raynal 120, 121, 122, 123, 124, 125, 126, 127,
147*cfcc706cSMiquel Raynal 128, 129, 130, 131, 132, 133, 134, 135,
148*cfcc706cSMiquel Raynal },
149*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, {136, 208} },
150*cfcc706cSMiquel Raynal };
151*cfcc706cSMiquel Raynal
152*cfcc706cSMiquel Raynal /* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
153*cfcc706cSMiquel Raynal static struct nand_ecclayout oob_8192_ecc8 = {
154*cfcc706cSMiquel Raynal .eccbytes = 256,
155*cfcc706cSMiquel Raynal .eccpos = {
156*cfcc706cSMiquel Raynal 8, 9, 10, 11, 12, 13, 14, 15,
157*cfcc706cSMiquel Raynal 16, 17, 18, 19, 20, 21, 22, 23,
158*cfcc706cSMiquel Raynal 24, 25, 26, 27, 28, 29, 30, 31,
159*cfcc706cSMiquel Raynal 32, 33, 34, 35, 36, 37, 38, 39,
160*cfcc706cSMiquel Raynal 40, 41, 42, 43, 44, 45, 46, 47,
161*cfcc706cSMiquel Raynal 48, 49, 50, 51, 52, 53, 54, 55,
162*cfcc706cSMiquel Raynal 56, 57, 58, 59, 60, 61, 62, 63,
163*cfcc706cSMiquel Raynal 64, 65, 66, 67, 68, 69, 70, 71,
164*cfcc706cSMiquel Raynal 72, 73, 74, 75, 76, 77, 78, 79,
165*cfcc706cSMiquel Raynal 80, 81, 82, 83, 84, 85, 86, 87,
166*cfcc706cSMiquel Raynal 88, 89, 90, 91, 92, 93, 94, 95,
167*cfcc706cSMiquel Raynal 96, 97, 98, 99, 100, 101, 102, 103,
168*cfcc706cSMiquel Raynal 104, 105, 106, 107, 108, 109, 110, 111,
169*cfcc706cSMiquel Raynal 112, 113, 114, 115, 116, 117, 118, 119,
170*cfcc706cSMiquel Raynal 120, 121, 122, 123, 124, 125, 126, 127,
171*cfcc706cSMiquel Raynal 128, 129, 130, 131, 132, 133, 134, 135,
172*cfcc706cSMiquel Raynal 136, 137, 138, 139, 140, 141, 142, 143,
173*cfcc706cSMiquel Raynal 144, 145, 146, 147, 148, 149, 150, 151,
174*cfcc706cSMiquel Raynal 152, 153, 154, 155, 156, 157, 158, 159,
175*cfcc706cSMiquel Raynal 160, 161, 162, 163, 164, 165, 166, 167,
176*cfcc706cSMiquel Raynal 168, 169, 170, 171, 172, 173, 174, 175,
177*cfcc706cSMiquel Raynal 176, 177, 178, 179, 180, 181, 182, 183,
178*cfcc706cSMiquel Raynal 184, 185, 186, 187, 188, 189, 190, 191,
179*cfcc706cSMiquel Raynal 192, 193, 194, 195, 196, 197, 198, 199,
180*cfcc706cSMiquel Raynal 200, 201, 202, 203, 204, 205, 206, 207,
181*cfcc706cSMiquel Raynal 208, 209, 210, 211, 212, 213, 214, 215,
182*cfcc706cSMiquel Raynal 216, 217, 218, 219, 220, 221, 222, 223,
183*cfcc706cSMiquel Raynal 224, 225, 226, 227, 228, 229, 230, 231,
184*cfcc706cSMiquel Raynal 232, 233, 234, 235, 236, 237, 238, 239,
185*cfcc706cSMiquel Raynal 240, 241, 242, 243, 244, 245, 246, 247,
186*cfcc706cSMiquel Raynal 248, 249, 250, 251, 252, 253, 254, 255,
187*cfcc706cSMiquel Raynal 256, 257, 258, 259, 260, 261, 262, 263,
188*cfcc706cSMiquel Raynal },
189*cfcc706cSMiquel Raynal .oobfree = { {2, 6}, {264, 80} },
190*cfcc706cSMiquel Raynal };
191*cfcc706cSMiquel Raynal
192*cfcc706cSMiquel Raynal /*
193*cfcc706cSMiquel Raynal * Generic flash bbt descriptors
194*cfcc706cSMiquel Raynal */
195*cfcc706cSMiquel Raynal static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
196*cfcc706cSMiquel Raynal static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
197*cfcc706cSMiquel Raynal
198*cfcc706cSMiquel Raynal static struct nand_bbt_descr bbt_main_descr = {
199*cfcc706cSMiquel Raynal .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
200*cfcc706cSMiquel Raynal NAND_BBT_2BIT | NAND_BBT_VERSION,
201*cfcc706cSMiquel Raynal .offs = 2, /* 0 on 8-bit small page */
202*cfcc706cSMiquel Raynal .len = 4,
203*cfcc706cSMiquel Raynal .veroffs = 6,
204*cfcc706cSMiquel Raynal .maxblocks = 4,
205*cfcc706cSMiquel Raynal .pattern = bbt_pattern,
206*cfcc706cSMiquel Raynal };
207*cfcc706cSMiquel Raynal
208*cfcc706cSMiquel Raynal static struct nand_bbt_descr bbt_mirror_descr = {
209*cfcc706cSMiquel Raynal .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
210*cfcc706cSMiquel Raynal NAND_BBT_2BIT | NAND_BBT_VERSION,
211*cfcc706cSMiquel Raynal .offs = 2, /* 0 on 8-bit small page */
212*cfcc706cSMiquel Raynal .len = 4,
213*cfcc706cSMiquel Raynal .veroffs = 6,
214*cfcc706cSMiquel Raynal .maxblocks = 4,
215*cfcc706cSMiquel Raynal .pattern = mirror_pattern,
216*cfcc706cSMiquel Raynal };
217*cfcc706cSMiquel Raynal
218*cfcc706cSMiquel Raynal /*
219*cfcc706cSMiquel Raynal * Set up the IFC hardware block and page address fields, and the ifc nand
220*cfcc706cSMiquel Raynal * structure addr field to point to the correct IFC buffer in memory
221*cfcc706cSMiquel Raynal */
set_addr(struct mtd_info * mtd,int column,int page_addr,int oob)222*cfcc706cSMiquel Raynal static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
223*cfcc706cSMiquel Raynal {
224*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
225*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
226*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
227*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
228*cfcc706cSMiquel Raynal int buf_num;
229*cfcc706cSMiquel Raynal
230*cfcc706cSMiquel Raynal ctrl->page = page_addr;
231*cfcc706cSMiquel Raynal
232*cfcc706cSMiquel Raynal /* Program ROW0/COL0 */
233*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.row0, page_addr);
234*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.col0, (oob ? IFC_NAND_COL_MS : 0) | column);
235*cfcc706cSMiquel Raynal
236*cfcc706cSMiquel Raynal buf_num = page_addr & priv->bufnum_mask;
237*cfcc706cSMiquel Raynal
238*cfcc706cSMiquel Raynal ctrl->addr = priv->vbase + buf_num * (mtd->writesize * 2);
239*cfcc706cSMiquel Raynal ctrl->index = column;
240*cfcc706cSMiquel Raynal
241*cfcc706cSMiquel Raynal /* for OOB data point to the second half of the buffer */
242*cfcc706cSMiquel Raynal if (oob)
243*cfcc706cSMiquel Raynal ctrl->index += mtd->writesize;
244*cfcc706cSMiquel Raynal }
245*cfcc706cSMiquel Raynal
246*cfcc706cSMiquel Raynal /* returns nonzero if entire page is blank */
check_read_ecc(struct mtd_info * mtd,struct fsl_ifc_ctrl * ctrl,u32 eccstat,unsigned int bufnum)247*cfcc706cSMiquel Raynal static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
248*cfcc706cSMiquel Raynal u32 eccstat, unsigned int bufnum)
249*cfcc706cSMiquel Raynal {
250*cfcc706cSMiquel Raynal return (eccstat >> ((3 - bufnum % 4) * 8)) & 15;
251*cfcc706cSMiquel Raynal }
252*cfcc706cSMiquel Raynal
253*cfcc706cSMiquel Raynal /*
254*cfcc706cSMiquel Raynal * execute IFC NAND command and wait for it to complete
255*cfcc706cSMiquel Raynal */
fsl_ifc_run_command(struct mtd_info * mtd)256*cfcc706cSMiquel Raynal static int fsl_ifc_run_command(struct mtd_info *mtd)
257*cfcc706cSMiquel Raynal {
258*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
259*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
260*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
261*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
262*cfcc706cSMiquel Raynal u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
263*cfcc706cSMiquel Raynal u32 time_start;
264*cfcc706cSMiquel Raynal u32 eccstat;
265*cfcc706cSMiquel Raynal int i;
266*cfcc706cSMiquel Raynal
267*cfcc706cSMiquel Raynal /* set the chip select for NAND Transaction */
268*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_csel, priv->bank << IFC_NAND_CSEL_SHIFT);
269*cfcc706cSMiquel Raynal
270*cfcc706cSMiquel Raynal /* start read/write seq */
271*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nandseq_strt,
272*cfcc706cSMiquel Raynal IFC_NAND_SEQ_STRT_FIR_STRT);
273*cfcc706cSMiquel Raynal
274*cfcc706cSMiquel Raynal /* wait for NAND Machine complete flag or timeout */
275*cfcc706cSMiquel Raynal time_start = get_timer(0);
276*cfcc706cSMiquel Raynal
277*cfcc706cSMiquel Raynal while (get_timer(time_start) < timeo) {
278*cfcc706cSMiquel Raynal ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
279*cfcc706cSMiquel Raynal
280*cfcc706cSMiquel Raynal if (ctrl->status & IFC_NAND_EVTER_STAT_OPC)
281*cfcc706cSMiquel Raynal break;
282*cfcc706cSMiquel Raynal }
283*cfcc706cSMiquel Raynal
284*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_evter_stat, ctrl->status);
285*cfcc706cSMiquel Raynal
286*cfcc706cSMiquel Raynal if (ctrl->status & IFC_NAND_EVTER_STAT_FTOER)
287*cfcc706cSMiquel Raynal printf("%s: Flash Time Out Error\n", __func__);
288*cfcc706cSMiquel Raynal if (ctrl->status & IFC_NAND_EVTER_STAT_WPER)
289*cfcc706cSMiquel Raynal printf("%s: Write Protect Error\n", __func__);
290*cfcc706cSMiquel Raynal
291*cfcc706cSMiquel Raynal if (ctrl->eccread) {
292*cfcc706cSMiquel Raynal int errors;
293*cfcc706cSMiquel Raynal int bufnum = ctrl->page & priv->bufnum_mask;
294*cfcc706cSMiquel Raynal int sector_start = bufnum * chip->ecc.steps;
295*cfcc706cSMiquel Raynal int sector_end = sector_start + chip->ecc.steps - 1;
296*cfcc706cSMiquel Raynal u32 *eccstat_regs;
297*cfcc706cSMiquel Raynal
298*cfcc706cSMiquel Raynal eccstat_regs = ifc->ifc_nand.nand_eccstat;
299*cfcc706cSMiquel Raynal eccstat = ifc_in32(&eccstat_regs[sector_start / 4]);
300*cfcc706cSMiquel Raynal
301*cfcc706cSMiquel Raynal for (i = sector_start; i <= sector_end; i++) {
302*cfcc706cSMiquel Raynal if ((i != sector_start) && !(i % 4))
303*cfcc706cSMiquel Raynal eccstat = ifc_in32(&eccstat_regs[i / 4]);
304*cfcc706cSMiquel Raynal
305*cfcc706cSMiquel Raynal errors = check_read_ecc(mtd, ctrl, eccstat, i);
306*cfcc706cSMiquel Raynal
307*cfcc706cSMiquel Raynal if (errors == 15) {
308*cfcc706cSMiquel Raynal /*
309*cfcc706cSMiquel Raynal * Uncorrectable error.
310*cfcc706cSMiquel Raynal * We'll check for blank pages later.
311*cfcc706cSMiquel Raynal *
312*cfcc706cSMiquel Raynal * We disable ECCER reporting due to erratum
313*cfcc706cSMiquel Raynal * IFC-A002770 -- so report it now if we
314*cfcc706cSMiquel Raynal * see an uncorrectable error in ECCSTAT.
315*cfcc706cSMiquel Raynal */
316*cfcc706cSMiquel Raynal ctrl->status |= IFC_NAND_EVTER_STAT_ECCER;
317*cfcc706cSMiquel Raynal continue;
318*cfcc706cSMiquel Raynal }
319*cfcc706cSMiquel Raynal
320*cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += errors;
321*cfcc706cSMiquel Raynal }
322*cfcc706cSMiquel Raynal
323*cfcc706cSMiquel Raynal ctrl->eccread = 0;
324*cfcc706cSMiquel Raynal }
325*cfcc706cSMiquel Raynal
326*cfcc706cSMiquel Raynal /* returns 0 on success otherwise non-zero) */
327*cfcc706cSMiquel Raynal return ctrl->status == IFC_NAND_EVTER_STAT_OPC ? 0 : -EIO;
328*cfcc706cSMiquel Raynal }
329*cfcc706cSMiquel Raynal
fsl_ifc_do_read(struct nand_chip * chip,int oob,struct mtd_info * mtd)330*cfcc706cSMiquel Raynal static void fsl_ifc_do_read(struct nand_chip *chip,
331*cfcc706cSMiquel Raynal int oob,
332*cfcc706cSMiquel Raynal struct mtd_info *mtd)
333*cfcc706cSMiquel Raynal {
334*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
335*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
336*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
337*cfcc706cSMiquel Raynal
338*cfcc706cSMiquel Raynal /* Program FIR/IFC_NAND_FCR0 for Small/Large page */
339*cfcc706cSMiquel Raynal if (mtd->writesize > 512) {
340*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
341*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
342*cfcc706cSMiquel Raynal (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
343*cfcc706cSMiquel Raynal (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
344*cfcc706cSMiquel Raynal (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) |
345*cfcc706cSMiquel Raynal (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP4_SHIFT));
346*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir1, 0x0);
347*cfcc706cSMiquel Raynal
348*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
349*cfcc706cSMiquel Raynal (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) |
350*cfcc706cSMiquel Raynal (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT));
351*cfcc706cSMiquel Raynal } else {
352*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
353*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
354*cfcc706cSMiquel Raynal (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
355*cfcc706cSMiquel Raynal (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
356*cfcc706cSMiquel Raynal (IFC_FIR_OP_RBCD << IFC_NAND_FIR0_OP3_SHIFT));
357*cfcc706cSMiquel Raynal
358*cfcc706cSMiquel Raynal if (oob)
359*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
360*cfcc706cSMiquel Raynal NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT);
361*cfcc706cSMiquel Raynal else
362*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
363*cfcc706cSMiquel Raynal NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT);
364*cfcc706cSMiquel Raynal }
365*cfcc706cSMiquel Raynal }
366*cfcc706cSMiquel Raynal
367*cfcc706cSMiquel Raynal /* cmdfunc send commands to the IFC NAND Machine */
fsl_ifc_cmdfunc(struct mtd_info * mtd,unsigned int command,int column,int page_addr)368*cfcc706cSMiquel Raynal static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
369*cfcc706cSMiquel Raynal int column, int page_addr)
370*cfcc706cSMiquel Raynal {
371*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
372*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
373*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
374*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
375*cfcc706cSMiquel Raynal
376*cfcc706cSMiquel Raynal /* clear the read buffer */
377*cfcc706cSMiquel Raynal ctrl->read_bytes = 0;
378*cfcc706cSMiquel Raynal if (command != NAND_CMD_PAGEPROG)
379*cfcc706cSMiquel Raynal ctrl->index = 0;
380*cfcc706cSMiquel Raynal
381*cfcc706cSMiquel Raynal switch (command) {
382*cfcc706cSMiquel Raynal /* READ0 read the entire buffer to use hardware ECC. */
383*cfcc706cSMiquel Raynal case NAND_CMD_READ0: {
384*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
385*cfcc706cSMiquel Raynal set_addr(mtd, 0, page_addr, 0);
386*cfcc706cSMiquel Raynal
387*cfcc706cSMiquel Raynal ctrl->read_bytes = mtd->writesize + mtd->oobsize;
388*cfcc706cSMiquel Raynal ctrl->index += column;
389*cfcc706cSMiquel Raynal
390*cfcc706cSMiquel Raynal if (chip->ecc.mode == NAND_ECC_HW)
391*cfcc706cSMiquel Raynal ctrl->eccread = 1;
392*cfcc706cSMiquel Raynal
393*cfcc706cSMiquel Raynal fsl_ifc_do_read(chip, 0, mtd);
394*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
395*cfcc706cSMiquel Raynal return;
396*cfcc706cSMiquel Raynal }
397*cfcc706cSMiquel Raynal
398*cfcc706cSMiquel Raynal /* READOOB reads only the OOB because no ECC is performed. */
399*cfcc706cSMiquel Raynal case NAND_CMD_READOOB:
400*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, mtd->oobsize - column);
401*cfcc706cSMiquel Raynal set_addr(mtd, column, page_addr, 1);
402*cfcc706cSMiquel Raynal
403*cfcc706cSMiquel Raynal ctrl->read_bytes = mtd->writesize + mtd->oobsize;
404*cfcc706cSMiquel Raynal
405*cfcc706cSMiquel Raynal fsl_ifc_do_read(chip, 1, mtd);
406*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
407*cfcc706cSMiquel Raynal
408*cfcc706cSMiquel Raynal return;
409*cfcc706cSMiquel Raynal
410*cfcc706cSMiquel Raynal /* READID must read all possible bytes while CEB is active */
411*cfcc706cSMiquel Raynal case NAND_CMD_READID:
412*cfcc706cSMiquel Raynal case NAND_CMD_PARAM: {
413*cfcc706cSMiquel Raynal int timing = IFC_FIR_OP_RB;
414*cfcc706cSMiquel Raynal if (command == NAND_CMD_PARAM)
415*cfcc706cSMiquel Raynal timing = IFC_FIR_OP_RBCD;
416*cfcc706cSMiquel Raynal
417*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
418*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
419*cfcc706cSMiquel Raynal (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
420*cfcc706cSMiquel Raynal (timing << IFC_NAND_FIR0_OP2_SHIFT));
421*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
422*cfcc706cSMiquel Raynal command << IFC_NAND_FCR0_CMD0_SHIFT);
423*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.row3, column);
424*cfcc706cSMiquel Raynal
425*cfcc706cSMiquel Raynal /*
426*cfcc706cSMiquel Raynal * although currently it's 8 bytes for READID, we always read
427*cfcc706cSMiquel Raynal * the maximum 256 bytes(for PARAM)
428*cfcc706cSMiquel Raynal */
429*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 256);
430*cfcc706cSMiquel Raynal ctrl->read_bytes = 256;
431*cfcc706cSMiquel Raynal
432*cfcc706cSMiquel Raynal set_addr(mtd, 0, 0, 0);
433*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
434*cfcc706cSMiquel Raynal return;
435*cfcc706cSMiquel Raynal }
436*cfcc706cSMiquel Raynal
437*cfcc706cSMiquel Raynal /* ERASE1 stores the block and page address */
438*cfcc706cSMiquel Raynal case NAND_CMD_ERASE1:
439*cfcc706cSMiquel Raynal set_addr(mtd, 0, page_addr, 0);
440*cfcc706cSMiquel Raynal return;
441*cfcc706cSMiquel Raynal
442*cfcc706cSMiquel Raynal /* ERASE2 uses the block and page address from ERASE1 */
443*cfcc706cSMiquel Raynal case NAND_CMD_ERASE2:
444*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
445*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
446*cfcc706cSMiquel Raynal (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP1_SHIFT) |
447*cfcc706cSMiquel Raynal (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP2_SHIFT));
448*cfcc706cSMiquel Raynal
449*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
450*cfcc706cSMiquel Raynal (NAND_CMD_ERASE1 << IFC_NAND_FCR0_CMD0_SHIFT) |
451*cfcc706cSMiquel Raynal (NAND_CMD_ERASE2 << IFC_NAND_FCR0_CMD1_SHIFT));
452*cfcc706cSMiquel Raynal
453*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
454*cfcc706cSMiquel Raynal ctrl->read_bytes = 0;
455*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
456*cfcc706cSMiquel Raynal return;
457*cfcc706cSMiquel Raynal
458*cfcc706cSMiquel Raynal /* SEQIN sets up the addr buffer and all registers except the length */
459*cfcc706cSMiquel Raynal case NAND_CMD_SEQIN: {
460*cfcc706cSMiquel Raynal u32 nand_fcr0;
461*cfcc706cSMiquel Raynal ctrl->column = column;
462*cfcc706cSMiquel Raynal ctrl->oob = 0;
463*cfcc706cSMiquel Raynal
464*cfcc706cSMiquel Raynal if (mtd->writesize > 512) {
465*cfcc706cSMiquel Raynal nand_fcr0 =
466*cfcc706cSMiquel Raynal (NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
467*cfcc706cSMiquel Raynal (NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
468*cfcc706cSMiquel Raynal (NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
469*cfcc706cSMiquel Raynal
470*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
471*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
472*cfcc706cSMiquel Raynal (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
473*cfcc706cSMiquel Raynal (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
474*cfcc706cSMiquel Raynal (IFC_FIR_OP_WBCD <<
475*cfcc706cSMiquel Raynal IFC_NAND_FIR0_OP3_SHIFT) |
476*cfcc706cSMiquel Raynal (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT));
477*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir1,
478*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
479*cfcc706cSMiquel Raynal (IFC_FIR_OP_RDSTAT <<
480*cfcc706cSMiquel Raynal IFC_NAND_FIR1_OP6_SHIFT) |
481*cfcc706cSMiquel Raynal (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT));
482*cfcc706cSMiquel Raynal } else {
483*cfcc706cSMiquel Raynal nand_fcr0 = ((NAND_CMD_PAGEPROG <<
484*cfcc706cSMiquel Raynal IFC_NAND_FCR0_CMD1_SHIFT) |
485*cfcc706cSMiquel Raynal (NAND_CMD_SEQIN <<
486*cfcc706cSMiquel Raynal IFC_NAND_FCR0_CMD2_SHIFT) |
487*cfcc706cSMiquel Raynal (NAND_CMD_STATUS <<
488*cfcc706cSMiquel Raynal IFC_NAND_FCR0_CMD3_SHIFT));
489*cfcc706cSMiquel Raynal
490*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
491*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
492*cfcc706cSMiquel Raynal (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP1_SHIFT) |
493*cfcc706cSMiquel Raynal (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP2_SHIFT) |
494*cfcc706cSMiquel Raynal (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
495*cfcc706cSMiquel Raynal (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT));
496*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir1,
497*cfcc706cSMiquel Raynal (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
498*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
499*cfcc706cSMiquel Raynal (IFC_FIR_OP_RDSTAT <<
500*cfcc706cSMiquel Raynal IFC_NAND_FIR1_OP7_SHIFT) |
501*cfcc706cSMiquel Raynal (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT));
502*cfcc706cSMiquel Raynal
503*cfcc706cSMiquel Raynal if (column >= mtd->writesize)
504*cfcc706cSMiquel Raynal nand_fcr0 |=
505*cfcc706cSMiquel Raynal NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
506*cfcc706cSMiquel Raynal else
507*cfcc706cSMiquel Raynal nand_fcr0 |=
508*cfcc706cSMiquel Raynal NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
509*cfcc706cSMiquel Raynal }
510*cfcc706cSMiquel Raynal
511*cfcc706cSMiquel Raynal if (column >= mtd->writesize) {
512*cfcc706cSMiquel Raynal /* OOB area --> READOOB */
513*cfcc706cSMiquel Raynal column -= mtd->writesize;
514*cfcc706cSMiquel Raynal ctrl->oob = 1;
515*cfcc706cSMiquel Raynal }
516*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
517*cfcc706cSMiquel Raynal set_addr(mtd, column, page_addr, ctrl->oob);
518*cfcc706cSMiquel Raynal return;
519*cfcc706cSMiquel Raynal }
520*cfcc706cSMiquel Raynal
521*cfcc706cSMiquel Raynal /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
522*cfcc706cSMiquel Raynal case NAND_CMD_PAGEPROG:
523*cfcc706cSMiquel Raynal if (ctrl->oob)
524*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr,
525*cfcc706cSMiquel Raynal ctrl->index - ctrl->column);
526*cfcc706cSMiquel Raynal else
527*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 0);
528*cfcc706cSMiquel Raynal
529*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
530*cfcc706cSMiquel Raynal return;
531*cfcc706cSMiquel Raynal
532*cfcc706cSMiquel Raynal case NAND_CMD_STATUS:
533*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
534*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
535*cfcc706cSMiquel Raynal (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP1_SHIFT));
536*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
537*cfcc706cSMiquel Raynal NAND_CMD_STATUS << IFC_NAND_FCR0_CMD0_SHIFT);
538*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 1);
539*cfcc706cSMiquel Raynal set_addr(mtd, 0, 0, 0);
540*cfcc706cSMiquel Raynal ctrl->read_bytes = 1;
541*cfcc706cSMiquel Raynal
542*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
543*cfcc706cSMiquel Raynal
544*cfcc706cSMiquel Raynal /*
545*cfcc706cSMiquel Raynal * The chip always seems to report that it is
546*cfcc706cSMiquel Raynal * write-protected, even when it is not.
547*cfcc706cSMiquel Raynal */
548*cfcc706cSMiquel Raynal if (chip->options & NAND_BUSWIDTH_16)
549*cfcc706cSMiquel Raynal ifc_out16(ctrl->addr,
550*cfcc706cSMiquel Raynal ifc_in16(ctrl->addr) | NAND_STATUS_WP);
551*cfcc706cSMiquel Raynal else
552*cfcc706cSMiquel Raynal out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP);
553*cfcc706cSMiquel Raynal return;
554*cfcc706cSMiquel Raynal
555*cfcc706cSMiquel Raynal case NAND_CMD_RESET:
556*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
557*cfcc706cSMiquel Raynal IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT);
558*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
559*cfcc706cSMiquel Raynal NAND_CMD_RESET << IFC_NAND_FCR0_CMD0_SHIFT);
560*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
561*cfcc706cSMiquel Raynal return;
562*cfcc706cSMiquel Raynal
563*cfcc706cSMiquel Raynal default:
564*cfcc706cSMiquel Raynal printf("%s: error, unsupported command 0x%x.\n",
565*cfcc706cSMiquel Raynal __func__, command);
566*cfcc706cSMiquel Raynal }
567*cfcc706cSMiquel Raynal }
568*cfcc706cSMiquel Raynal
569*cfcc706cSMiquel Raynal /*
570*cfcc706cSMiquel Raynal * Write buf to the IFC NAND Controller Data Buffer
571*cfcc706cSMiquel Raynal */
fsl_ifc_write_buf(struct mtd_info * mtd,const u8 * buf,int len)572*cfcc706cSMiquel Raynal static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
573*cfcc706cSMiquel Raynal {
574*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
575*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
576*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
577*cfcc706cSMiquel Raynal unsigned int bufsize = mtd->writesize + mtd->oobsize;
578*cfcc706cSMiquel Raynal
579*cfcc706cSMiquel Raynal if (len <= 0) {
580*cfcc706cSMiquel Raynal printf("%s of %d bytes", __func__, len);
581*cfcc706cSMiquel Raynal ctrl->status = 0;
582*cfcc706cSMiquel Raynal return;
583*cfcc706cSMiquel Raynal }
584*cfcc706cSMiquel Raynal
585*cfcc706cSMiquel Raynal if ((unsigned int)len > bufsize - ctrl->index) {
586*cfcc706cSMiquel Raynal printf("%s beyond end of buffer "
587*cfcc706cSMiquel Raynal "(%d requested, %u available)\n",
588*cfcc706cSMiquel Raynal __func__, len, bufsize - ctrl->index);
589*cfcc706cSMiquel Raynal len = bufsize - ctrl->index;
590*cfcc706cSMiquel Raynal }
591*cfcc706cSMiquel Raynal
592*cfcc706cSMiquel Raynal memcpy_toio(ctrl->addr + ctrl->index, buf, len);
593*cfcc706cSMiquel Raynal ctrl->index += len;
594*cfcc706cSMiquel Raynal }
595*cfcc706cSMiquel Raynal
596*cfcc706cSMiquel Raynal /*
597*cfcc706cSMiquel Raynal * read a byte from either the IFC hardware buffer if it has any data left
598*cfcc706cSMiquel Raynal * otherwise issue a command to read a single byte.
599*cfcc706cSMiquel Raynal */
fsl_ifc_read_byte(struct mtd_info * mtd)600*cfcc706cSMiquel Raynal static u8 fsl_ifc_read_byte(struct mtd_info *mtd)
601*cfcc706cSMiquel Raynal {
602*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
603*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
604*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
605*cfcc706cSMiquel Raynal unsigned int offset;
606*cfcc706cSMiquel Raynal
607*cfcc706cSMiquel Raynal /*
608*cfcc706cSMiquel Raynal * If there are still bytes in the IFC buffer, then use the
609*cfcc706cSMiquel Raynal * next byte.
610*cfcc706cSMiquel Raynal */
611*cfcc706cSMiquel Raynal if (ctrl->index < ctrl->read_bytes) {
612*cfcc706cSMiquel Raynal offset = ctrl->index++;
613*cfcc706cSMiquel Raynal return in_8(ctrl->addr + offset);
614*cfcc706cSMiquel Raynal }
615*cfcc706cSMiquel Raynal
616*cfcc706cSMiquel Raynal printf("%s beyond end of buffer\n", __func__);
617*cfcc706cSMiquel Raynal return ERR_BYTE;
618*cfcc706cSMiquel Raynal }
619*cfcc706cSMiquel Raynal
620*cfcc706cSMiquel Raynal /*
621*cfcc706cSMiquel Raynal * Read two bytes from the IFC hardware buffer
622*cfcc706cSMiquel Raynal * read function for 16-bit buswith
623*cfcc706cSMiquel Raynal */
fsl_ifc_read_byte16(struct mtd_info * mtd)624*cfcc706cSMiquel Raynal static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd)
625*cfcc706cSMiquel Raynal {
626*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
627*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
628*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
629*cfcc706cSMiquel Raynal uint16_t data;
630*cfcc706cSMiquel Raynal
631*cfcc706cSMiquel Raynal /*
632*cfcc706cSMiquel Raynal * If there are still bytes in the IFC buffer, then use the
633*cfcc706cSMiquel Raynal * next byte.
634*cfcc706cSMiquel Raynal */
635*cfcc706cSMiquel Raynal if (ctrl->index < ctrl->read_bytes) {
636*cfcc706cSMiquel Raynal data = ifc_in16(ctrl->addr + ctrl->index);
637*cfcc706cSMiquel Raynal ctrl->index += 2;
638*cfcc706cSMiquel Raynal return (uint8_t)data;
639*cfcc706cSMiquel Raynal }
640*cfcc706cSMiquel Raynal
641*cfcc706cSMiquel Raynal printf("%s beyond end of buffer\n", __func__);
642*cfcc706cSMiquel Raynal return ERR_BYTE;
643*cfcc706cSMiquel Raynal }
644*cfcc706cSMiquel Raynal
645*cfcc706cSMiquel Raynal /*
646*cfcc706cSMiquel Raynal * Read from the IFC Controller Data Buffer
647*cfcc706cSMiquel Raynal */
fsl_ifc_read_buf(struct mtd_info * mtd,u8 * buf,int len)648*cfcc706cSMiquel Raynal static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
649*cfcc706cSMiquel Raynal {
650*cfcc706cSMiquel Raynal struct nand_chip *chip = mtd_to_nand(mtd);
651*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
652*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
653*cfcc706cSMiquel Raynal int avail;
654*cfcc706cSMiquel Raynal
655*cfcc706cSMiquel Raynal if (len < 0)
656*cfcc706cSMiquel Raynal return;
657*cfcc706cSMiquel Raynal
658*cfcc706cSMiquel Raynal avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index);
659*cfcc706cSMiquel Raynal memcpy_fromio(buf, ctrl->addr + ctrl->index, avail);
660*cfcc706cSMiquel Raynal ctrl->index += avail;
661*cfcc706cSMiquel Raynal
662*cfcc706cSMiquel Raynal if (len > avail)
663*cfcc706cSMiquel Raynal printf("%s beyond end of buffer "
664*cfcc706cSMiquel Raynal "(%d requested, %d available)\n",
665*cfcc706cSMiquel Raynal __func__, len, avail);
666*cfcc706cSMiquel Raynal }
667*cfcc706cSMiquel Raynal
668*cfcc706cSMiquel Raynal /* This function is called after Program and Erase Operations to
669*cfcc706cSMiquel Raynal * check for success or failure.
670*cfcc706cSMiquel Raynal */
fsl_ifc_wait(struct mtd_info * mtd,struct nand_chip * chip)671*cfcc706cSMiquel Raynal static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
672*cfcc706cSMiquel Raynal {
673*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
674*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
675*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
676*cfcc706cSMiquel Raynal u32 nand_fsr;
677*cfcc706cSMiquel Raynal int status;
678*cfcc706cSMiquel Raynal
679*cfcc706cSMiquel Raynal if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
680*cfcc706cSMiquel Raynal return NAND_STATUS_FAIL;
681*cfcc706cSMiquel Raynal
682*cfcc706cSMiquel Raynal /* Use READ_STATUS command, but wait for the device to be ready */
683*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
684*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
685*cfcc706cSMiquel Raynal (IFC_FIR_OP_RDSTAT << IFC_NAND_FIR0_OP1_SHIFT));
686*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0, NAND_CMD_STATUS <<
687*cfcc706cSMiquel Raynal IFC_NAND_FCR0_CMD0_SHIFT);
688*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 1);
689*cfcc706cSMiquel Raynal set_addr(mtd, 0, 0, 0);
690*cfcc706cSMiquel Raynal ctrl->read_bytes = 1;
691*cfcc706cSMiquel Raynal
692*cfcc706cSMiquel Raynal fsl_ifc_run_command(mtd);
693*cfcc706cSMiquel Raynal
694*cfcc706cSMiquel Raynal if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
695*cfcc706cSMiquel Raynal return NAND_STATUS_FAIL;
696*cfcc706cSMiquel Raynal
697*cfcc706cSMiquel Raynal nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
698*cfcc706cSMiquel Raynal status = nand_fsr >> 24;
699*cfcc706cSMiquel Raynal
700*cfcc706cSMiquel Raynal /* Chip sometimes reporting write protect even when it's not */
701*cfcc706cSMiquel Raynal return status | NAND_STATUS_WP;
702*cfcc706cSMiquel Raynal }
703*cfcc706cSMiquel Raynal
704*cfcc706cSMiquel Raynal /*
705*cfcc706cSMiquel Raynal * The controller does not check for bitflips in erased pages,
706*cfcc706cSMiquel Raynal * therefore software must check instead.
707*cfcc706cSMiquel Raynal */
708*cfcc706cSMiquel Raynal static int
check_erased_page(struct nand_chip * chip,u8 * buf,struct mtd_info * mtd)709*cfcc706cSMiquel Raynal check_erased_page(struct nand_chip *chip, u8 *buf, struct mtd_info *mtd)
710*cfcc706cSMiquel Raynal {
711*cfcc706cSMiquel Raynal u8 *ecc = chip->oob_poi;
712*cfcc706cSMiquel Raynal const int ecc_size = chip->ecc.bytes;
713*cfcc706cSMiquel Raynal const int pkt_size = chip->ecc.size;
714*cfcc706cSMiquel Raynal int i, res, bitflips;
715*cfcc706cSMiquel Raynal
716*cfcc706cSMiquel Raynal /* IFC starts ecc bytes at offset 8 in the spare area. */
717*cfcc706cSMiquel Raynal ecc += 8;
718*cfcc706cSMiquel Raynal bitflips = 0;
719*cfcc706cSMiquel Raynal for (i = 0; i < chip->ecc.steps; i++) {
720*cfcc706cSMiquel Raynal res = nand_check_erased_ecc_chunk(buf, pkt_size, ecc, ecc_size,
721*cfcc706cSMiquel Raynal NULL, 0, chip->ecc.strength);
722*cfcc706cSMiquel Raynal
723*cfcc706cSMiquel Raynal if (res < 0) {
724*cfcc706cSMiquel Raynal printf("fsl-ifc: NAND Flash ECC Uncorrectable Error\n");
725*cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
726*cfcc706cSMiquel Raynal } else if (res > 0) {
727*cfcc706cSMiquel Raynal mtd->ecc_stats.corrected += res;
728*cfcc706cSMiquel Raynal }
729*cfcc706cSMiquel Raynal bitflips = max(res, bitflips);
730*cfcc706cSMiquel Raynal buf += pkt_size;
731*cfcc706cSMiquel Raynal ecc += ecc_size;
732*cfcc706cSMiquel Raynal }
733*cfcc706cSMiquel Raynal
734*cfcc706cSMiquel Raynal return bitflips;
735*cfcc706cSMiquel Raynal }
736*cfcc706cSMiquel Raynal
fsl_ifc_read_page(struct mtd_info * mtd,struct nand_chip * chip,uint8_t * buf,int oob_required,int page)737*cfcc706cSMiquel Raynal static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
738*cfcc706cSMiquel Raynal uint8_t *buf, int oob_required, int page)
739*cfcc706cSMiquel Raynal {
740*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
741*cfcc706cSMiquel Raynal struct fsl_ifc_ctrl *ctrl = priv->ctrl;
742*cfcc706cSMiquel Raynal
743*cfcc706cSMiquel Raynal fsl_ifc_read_buf(mtd, buf, mtd->writesize);
744*cfcc706cSMiquel Raynal fsl_ifc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
745*cfcc706cSMiquel Raynal
746*cfcc706cSMiquel Raynal if (ctrl->status & IFC_NAND_EVTER_STAT_ECCER)
747*cfcc706cSMiquel Raynal return check_erased_page(chip, buf, mtd);
748*cfcc706cSMiquel Raynal
749*cfcc706cSMiquel Raynal if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
750*cfcc706cSMiquel Raynal mtd->ecc_stats.failed++;
751*cfcc706cSMiquel Raynal
752*cfcc706cSMiquel Raynal return 0;
753*cfcc706cSMiquel Raynal }
754*cfcc706cSMiquel Raynal
755*cfcc706cSMiquel Raynal /* ECC will be calculated automatically, and errors will be detected in
756*cfcc706cSMiquel Raynal * waitfunc.
757*cfcc706cSMiquel Raynal */
fsl_ifc_write_page(struct mtd_info * mtd,struct nand_chip * chip,const uint8_t * buf,int oob_required,int page)758*cfcc706cSMiquel Raynal static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
759*cfcc706cSMiquel Raynal const uint8_t *buf, int oob_required, int page)
760*cfcc706cSMiquel Raynal {
761*cfcc706cSMiquel Raynal fsl_ifc_write_buf(mtd, buf, mtd->writesize);
762*cfcc706cSMiquel Raynal fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
763*cfcc706cSMiquel Raynal
764*cfcc706cSMiquel Raynal return 0;
765*cfcc706cSMiquel Raynal }
766*cfcc706cSMiquel Raynal
fsl_ifc_ctrl_init(void)767*cfcc706cSMiquel Raynal static void fsl_ifc_ctrl_init(void)
768*cfcc706cSMiquel Raynal {
769*cfcc706cSMiquel Raynal uint32_t ver = 0;
770*cfcc706cSMiquel Raynal ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL);
771*cfcc706cSMiquel Raynal if (!ifc_ctrl)
772*cfcc706cSMiquel Raynal return;
773*cfcc706cSMiquel Raynal
774*cfcc706cSMiquel Raynal ifc_ctrl->regs.gregs = IFC_FCM_BASE_ADDR;
775*cfcc706cSMiquel Raynal
776*cfcc706cSMiquel Raynal ver = ifc_in32(&ifc_ctrl->regs.gregs->ifc_rev);
777*cfcc706cSMiquel Raynal if (ver >= FSL_IFC_V2_0_0)
778*cfcc706cSMiquel Raynal ifc_ctrl->regs.rregs =
779*cfcc706cSMiquel Raynal (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET;
780*cfcc706cSMiquel Raynal else
781*cfcc706cSMiquel Raynal ifc_ctrl->regs.rregs =
782*cfcc706cSMiquel Raynal (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET;
783*cfcc706cSMiquel Raynal
784*cfcc706cSMiquel Raynal /* clear event registers */
785*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_stat, ~0U);
786*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
787*cfcc706cSMiquel Raynal
788*cfcc706cSMiquel Raynal /* Enable error and event for any detected errors */
789*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_en,
790*cfcc706cSMiquel Raynal IFC_NAND_EVTER_EN_OPC_EN |
791*cfcc706cSMiquel Raynal IFC_NAND_EVTER_EN_PGRDCMPL_EN |
792*cfcc706cSMiquel Raynal IFC_NAND_EVTER_EN_FTOER_EN |
793*cfcc706cSMiquel Raynal IFC_NAND_EVTER_EN_WPER_EN);
794*cfcc706cSMiquel Raynal
795*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.ncfgr, 0x0);
796*cfcc706cSMiquel Raynal }
797*cfcc706cSMiquel Raynal
fsl_ifc_select_chip(struct mtd_info * mtd,int chip)798*cfcc706cSMiquel Raynal static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
799*cfcc706cSMiquel Raynal {
800*cfcc706cSMiquel Raynal }
801*cfcc706cSMiquel Raynal
fsl_ifc_sram_init(struct fsl_ifc_mtd * priv,uint32_t ver)802*cfcc706cSMiquel Raynal static int fsl_ifc_sram_init(struct fsl_ifc_mtd *priv, uint32_t ver)
803*cfcc706cSMiquel Raynal {
804*cfcc706cSMiquel Raynal struct fsl_ifc_runtime *ifc = ifc_ctrl->regs.rregs;
805*cfcc706cSMiquel Raynal uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
806*cfcc706cSMiquel Raynal uint32_t ncfgr = 0;
807*cfcc706cSMiquel Raynal u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
808*cfcc706cSMiquel Raynal u32 time_start;
809*cfcc706cSMiquel Raynal
810*cfcc706cSMiquel Raynal if (ver > FSL_IFC_V1_1_0) {
811*cfcc706cSMiquel Raynal ncfgr = ifc_in32(&ifc->ifc_nand.ncfgr);
812*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.ncfgr, ncfgr | IFC_NAND_SRAM_INIT_EN);
813*cfcc706cSMiquel Raynal
814*cfcc706cSMiquel Raynal /* wait for SRAM_INIT bit to be clear or timeout */
815*cfcc706cSMiquel Raynal time_start = get_timer(0);
816*cfcc706cSMiquel Raynal while (get_timer(time_start) < timeo) {
817*cfcc706cSMiquel Raynal ifc_ctrl->status =
818*cfcc706cSMiquel Raynal ifc_in32(&ifc->ifc_nand.nand_evter_stat);
819*cfcc706cSMiquel Raynal
820*cfcc706cSMiquel Raynal if (!(ifc_ctrl->status & IFC_NAND_SRAM_INIT_EN))
821*cfcc706cSMiquel Raynal return 0;
822*cfcc706cSMiquel Raynal }
823*cfcc706cSMiquel Raynal printf("fsl-ifc: Failed to Initialise SRAM\n");
824*cfcc706cSMiquel Raynal return 1;
825*cfcc706cSMiquel Raynal }
826*cfcc706cSMiquel Raynal
827*cfcc706cSMiquel Raynal cs = priv->bank;
828*cfcc706cSMiquel Raynal
829*cfcc706cSMiquel Raynal /* Save CSOR and CSOR_ext */
830*cfcc706cSMiquel Raynal csor = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor);
831*cfcc706cSMiquel Raynal csor_ext = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext);
832*cfcc706cSMiquel Raynal
833*cfcc706cSMiquel Raynal /* chage PageSize 8K and SpareSize 1K*/
834*cfcc706cSMiquel Raynal csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
835*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor_8k);
836*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, 0x0000400);
837*cfcc706cSMiquel Raynal
838*cfcc706cSMiquel Raynal /* READID */
839*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fir0,
840*cfcc706cSMiquel Raynal (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
841*cfcc706cSMiquel Raynal (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) |
842*cfcc706cSMiquel Raynal (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT));
843*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fcr0,
844*cfcc706cSMiquel Raynal NAND_CMD_READID << IFC_NAND_FCR0_CMD0_SHIFT);
845*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.row3, 0x0);
846*cfcc706cSMiquel Raynal
847*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_fbcr, 0x0);
848*cfcc706cSMiquel Raynal
849*cfcc706cSMiquel Raynal /* Program ROW0/COL0 */
850*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.row0, 0x0);
851*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.col0, 0x0);
852*cfcc706cSMiquel Raynal
853*cfcc706cSMiquel Raynal /* set the chip select for NAND Transaction */
854*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_csel, priv->bank << IFC_NAND_CSEL_SHIFT);
855*cfcc706cSMiquel Raynal
856*cfcc706cSMiquel Raynal /* start read seq */
857*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
858*cfcc706cSMiquel Raynal
859*cfcc706cSMiquel Raynal time_start = get_timer(0);
860*cfcc706cSMiquel Raynal
861*cfcc706cSMiquel Raynal while (get_timer(time_start) < timeo) {
862*cfcc706cSMiquel Raynal ifc_ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
863*cfcc706cSMiquel Raynal
864*cfcc706cSMiquel Raynal if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
865*cfcc706cSMiquel Raynal break;
866*cfcc706cSMiquel Raynal }
867*cfcc706cSMiquel Raynal
868*cfcc706cSMiquel Raynal if (ifc_ctrl->status != IFC_NAND_EVTER_STAT_OPC) {
869*cfcc706cSMiquel Raynal printf("fsl-ifc: Failed to Initialise SRAM\n");
870*cfcc706cSMiquel Raynal return 1;
871*cfcc706cSMiquel Raynal }
872*cfcc706cSMiquel Raynal
873*cfcc706cSMiquel Raynal ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
874*cfcc706cSMiquel Raynal
875*cfcc706cSMiquel Raynal /* Restore CSOR and CSOR_ext */
876*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor);
877*cfcc706cSMiquel Raynal ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, csor_ext);
878*cfcc706cSMiquel Raynal
879*cfcc706cSMiquel Raynal return 0;
880*cfcc706cSMiquel Raynal }
881*cfcc706cSMiquel Raynal
fsl_ifc_chip_init(int devnum,u8 * addr)882*cfcc706cSMiquel Raynal static int fsl_ifc_chip_init(int devnum, u8 *addr)
883*cfcc706cSMiquel Raynal {
884*cfcc706cSMiquel Raynal struct mtd_info *mtd;
885*cfcc706cSMiquel Raynal struct nand_chip *nand;
886*cfcc706cSMiquel Raynal struct fsl_ifc_mtd *priv;
887*cfcc706cSMiquel Raynal struct nand_ecclayout *layout;
888*cfcc706cSMiquel Raynal struct fsl_ifc_fcm *gregs = NULL;
889*cfcc706cSMiquel Raynal uint32_t cspr = 0, csor = 0, ver = 0;
890*cfcc706cSMiquel Raynal int ret = 0;
891*cfcc706cSMiquel Raynal
892*cfcc706cSMiquel Raynal if (!ifc_ctrl) {
893*cfcc706cSMiquel Raynal fsl_ifc_ctrl_init();
894*cfcc706cSMiquel Raynal if (!ifc_ctrl)
895*cfcc706cSMiquel Raynal return -1;
896*cfcc706cSMiquel Raynal }
897*cfcc706cSMiquel Raynal
898*cfcc706cSMiquel Raynal priv = kzalloc(sizeof(*priv), GFP_KERNEL);
899*cfcc706cSMiquel Raynal if (!priv)
900*cfcc706cSMiquel Raynal return -ENOMEM;
901*cfcc706cSMiquel Raynal
902*cfcc706cSMiquel Raynal priv->ctrl = ifc_ctrl;
903*cfcc706cSMiquel Raynal priv->vbase = addr;
904*cfcc706cSMiquel Raynal gregs = ifc_ctrl->regs.gregs;
905*cfcc706cSMiquel Raynal
906*cfcc706cSMiquel Raynal /* Find which chip select it is connected to.
907*cfcc706cSMiquel Raynal */
908*cfcc706cSMiquel Raynal for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
909*cfcc706cSMiquel Raynal phys_addr_t phys_addr = virt_to_phys(addr);
910*cfcc706cSMiquel Raynal
911*cfcc706cSMiquel Raynal cspr = ifc_in32(&gregs->cspr_cs[priv->bank].cspr);
912*cfcc706cSMiquel Raynal csor = ifc_in32(&gregs->csor_cs[priv->bank].csor);
913*cfcc706cSMiquel Raynal
914*cfcc706cSMiquel Raynal if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
915*cfcc706cSMiquel Raynal (cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr))
916*cfcc706cSMiquel Raynal break;
917*cfcc706cSMiquel Raynal }
918*cfcc706cSMiquel Raynal
919*cfcc706cSMiquel Raynal if (priv->bank >= MAX_BANKS) {
920*cfcc706cSMiquel Raynal printf("%s: address did not match any "
921*cfcc706cSMiquel Raynal "chip selects\n", __func__);
922*cfcc706cSMiquel Raynal kfree(priv);
923*cfcc706cSMiquel Raynal return -ENODEV;
924*cfcc706cSMiquel Raynal }
925*cfcc706cSMiquel Raynal
926*cfcc706cSMiquel Raynal nand = &priv->chip;
927*cfcc706cSMiquel Raynal mtd = nand_to_mtd(nand);
928*cfcc706cSMiquel Raynal
929*cfcc706cSMiquel Raynal ifc_ctrl->chips[priv->bank] = priv;
930*cfcc706cSMiquel Raynal
931*cfcc706cSMiquel Raynal /* fill in nand_chip structure */
932*cfcc706cSMiquel Raynal /* set up function call table */
933*cfcc706cSMiquel Raynal
934*cfcc706cSMiquel Raynal nand->write_buf = fsl_ifc_write_buf;
935*cfcc706cSMiquel Raynal nand->read_buf = fsl_ifc_read_buf;
936*cfcc706cSMiquel Raynal nand->select_chip = fsl_ifc_select_chip;
937*cfcc706cSMiquel Raynal nand->cmdfunc = fsl_ifc_cmdfunc;
938*cfcc706cSMiquel Raynal nand->waitfunc = fsl_ifc_wait;
939*cfcc706cSMiquel Raynal
940*cfcc706cSMiquel Raynal /* set up nand options */
941*cfcc706cSMiquel Raynal nand->bbt_td = &bbt_main_descr;
942*cfcc706cSMiquel Raynal nand->bbt_md = &bbt_mirror_descr;
943*cfcc706cSMiquel Raynal
944*cfcc706cSMiquel Raynal /* set up nand options */
945*cfcc706cSMiquel Raynal nand->options = NAND_NO_SUBPAGE_WRITE;
946*cfcc706cSMiquel Raynal nand->bbt_options = NAND_BBT_USE_FLASH;
947*cfcc706cSMiquel Raynal
948*cfcc706cSMiquel Raynal if (cspr & CSPR_PORT_SIZE_16) {
949*cfcc706cSMiquel Raynal nand->read_byte = fsl_ifc_read_byte16;
950*cfcc706cSMiquel Raynal nand->options |= NAND_BUSWIDTH_16;
951*cfcc706cSMiquel Raynal } else {
952*cfcc706cSMiquel Raynal nand->read_byte = fsl_ifc_read_byte;
953*cfcc706cSMiquel Raynal }
954*cfcc706cSMiquel Raynal
955*cfcc706cSMiquel Raynal nand->controller = &ifc_ctrl->controller;
956*cfcc706cSMiquel Raynal nand_set_controller_data(nand, priv);
957*cfcc706cSMiquel Raynal
958*cfcc706cSMiquel Raynal nand->ecc.read_page = fsl_ifc_read_page;
959*cfcc706cSMiquel Raynal nand->ecc.write_page = fsl_ifc_write_page;
960*cfcc706cSMiquel Raynal
961*cfcc706cSMiquel Raynal /* Hardware generates ECC per 512 Bytes */
962*cfcc706cSMiquel Raynal nand->ecc.size = 512;
963*cfcc706cSMiquel Raynal nand->ecc.bytes = 8;
964*cfcc706cSMiquel Raynal
965*cfcc706cSMiquel Raynal switch (csor & CSOR_NAND_PGS_MASK) {
966*cfcc706cSMiquel Raynal case CSOR_NAND_PGS_512:
967*cfcc706cSMiquel Raynal if (nand->options & NAND_BUSWIDTH_16) {
968*cfcc706cSMiquel Raynal layout = &oob_512_16bit_ecc4;
969*cfcc706cSMiquel Raynal } else {
970*cfcc706cSMiquel Raynal layout = &oob_512_8bit_ecc4;
971*cfcc706cSMiquel Raynal
972*cfcc706cSMiquel Raynal /* Avoid conflict with bad block marker */
973*cfcc706cSMiquel Raynal bbt_main_descr.offs = 0;
974*cfcc706cSMiquel Raynal bbt_mirror_descr.offs = 0;
975*cfcc706cSMiquel Raynal }
976*cfcc706cSMiquel Raynal
977*cfcc706cSMiquel Raynal nand->ecc.strength = 4;
978*cfcc706cSMiquel Raynal priv->bufnum_mask = 15;
979*cfcc706cSMiquel Raynal break;
980*cfcc706cSMiquel Raynal
981*cfcc706cSMiquel Raynal case CSOR_NAND_PGS_2K:
982*cfcc706cSMiquel Raynal layout = &oob_2048_ecc4;
983*cfcc706cSMiquel Raynal nand->ecc.strength = 4;
984*cfcc706cSMiquel Raynal priv->bufnum_mask = 3;
985*cfcc706cSMiquel Raynal break;
986*cfcc706cSMiquel Raynal
987*cfcc706cSMiquel Raynal case CSOR_NAND_PGS_4K:
988*cfcc706cSMiquel Raynal if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
989*cfcc706cSMiquel Raynal CSOR_NAND_ECC_MODE_4) {
990*cfcc706cSMiquel Raynal layout = &oob_4096_ecc4;
991*cfcc706cSMiquel Raynal nand->ecc.strength = 4;
992*cfcc706cSMiquel Raynal } else {
993*cfcc706cSMiquel Raynal layout = &oob_4096_ecc8;
994*cfcc706cSMiquel Raynal nand->ecc.strength = 8;
995*cfcc706cSMiquel Raynal nand->ecc.bytes = 16;
996*cfcc706cSMiquel Raynal }
997*cfcc706cSMiquel Raynal
998*cfcc706cSMiquel Raynal priv->bufnum_mask = 1;
999*cfcc706cSMiquel Raynal break;
1000*cfcc706cSMiquel Raynal
1001*cfcc706cSMiquel Raynal case CSOR_NAND_PGS_8K:
1002*cfcc706cSMiquel Raynal if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
1003*cfcc706cSMiquel Raynal CSOR_NAND_ECC_MODE_4) {
1004*cfcc706cSMiquel Raynal layout = &oob_8192_ecc4;
1005*cfcc706cSMiquel Raynal nand->ecc.strength = 4;
1006*cfcc706cSMiquel Raynal } else {
1007*cfcc706cSMiquel Raynal layout = &oob_8192_ecc8;
1008*cfcc706cSMiquel Raynal nand->ecc.strength = 8;
1009*cfcc706cSMiquel Raynal nand->ecc.bytes = 16;
1010*cfcc706cSMiquel Raynal }
1011*cfcc706cSMiquel Raynal
1012*cfcc706cSMiquel Raynal priv->bufnum_mask = 0;
1013*cfcc706cSMiquel Raynal break;
1014*cfcc706cSMiquel Raynal
1015*cfcc706cSMiquel Raynal
1016*cfcc706cSMiquel Raynal default:
1017*cfcc706cSMiquel Raynal printf("ifc nand: bad csor %#x: bad page size\n", csor);
1018*cfcc706cSMiquel Raynal return -ENODEV;
1019*cfcc706cSMiquel Raynal }
1020*cfcc706cSMiquel Raynal
1021*cfcc706cSMiquel Raynal /* Must also set CSOR_NAND_ECC_ENC_EN if DEC_EN set */
1022*cfcc706cSMiquel Raynal if (csor & CSOR_NAND_ECC_DEC_EN) {
1023*cfcc706cSMiquel Raynal nand->ecc.mode = NAND_ECC_HW;
1024*cfcc706cSMiquel Raynal nand->ecc.layout = layout;
1025*cfcc706cSMiquel Raynal } else {
1026*cfcc706cSMiquel Raynal nand->ecc.mode = NAND_ECC_SOFT;
1027*cfcc706cSMiquel Raynal }
1028*cfcc706cSMiquel Raynal
1029*cfcc706cSMiquel Raynal ver = ifc_in32(&gregs->ifc_rev);
1030*cfcc706cSMiquel Raynal if (ver >= FSL_IFC_V1_1_0)
1031*cfcc706cSMiquel Raynal ret = fsl_ifc_sram_init(priv, ver);
1032*cfcc706cSMiquel Raynal if (ret)
1033*cfcc706cSMiquel Raynal return ret;
1034*cfcc706cSMiquel Raynal
1035*cfcc706cSMiquel Raynal if (ver >= FSL_IFC_V2_0_0)
1036*cfcc706cSMiquel Raynal priv->bufnum_mask = (priv->bufnum_mask * 2) + 1;
1037*cfcc706cSMiquel Raynal
1038*cfcc706cSMiquel Raynal ret = nand_scan_ident(mtd, 1, NULL);
1039*cfcc706cSMiquel Raynal if (ret)
1040*cfcc706cSMiquel Raynal return ret;
1041*cfcc706cSMiquel Raynal
1042*cfcc706cSMiquel Raynal ret = nand_scan_tail(mtd);
1043*cfcc706cSMiquel Raynal if (ret)
1044*cfcc706cSMiquel Raynal return ret;
1045*cfcc706cSMiquel Raynal
1046*cfcc706cSMiquel Raynal ret = nand_register(devnum, mtd);
1047*cfcc706cSMiquel Raynal if (ret)
1048*cfcc706cSMiquel Raynal return ret;
1049*cfcc706cSMiquel Raynal return 0;
1050*cfcc706cSMiquel Raynal }
1051*cfcc706cSMiquel Raynal
1052*cfcc706cSMiquel Raynal #ifndef CONFIG_SYS_NAND_BASE_LIST
1053*cfcc706cSMiquel Raynal #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
1054*cfcc706cSMiquel Raynal #endif
1055*cfcc706cSMiquel Raynal
1056*cfcc706cSMiquel Raynal static unsigned long base_address[CONFIG_SYS_MAX_NAND_DEVICE] =
1057*cfcc706cSMiquel Raynal CONFIG_SYS_NAND_BASE_LIST;
1058*cfcc706cSMiquel Raynal
board_nand_init(void)1059*cfcc706cSMiquel Raynal void board_nand_init(void)
1060*cfcc706cSMiquel Raynal {
1061*cfcc706cSMiquel Raynal int i;
1062*cfcc706cSMiquel Raynal
1063*cfcc706cSMiquel Raynal for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
1064*cfcc706cSMiquel Raynal fsl_ifc_chip_init(i, (u8 *)base_address[i]);
1065*cfcc706cSMiquel Raynal }
1066