xref: /rk3399_rockchip-uboot/drivers/mtd/nand/raw/fsl_ifc_nand.c (revision cfcc706c901d603707657919484e4f65467be9ff)
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