xref: /OK3568_Linux_fs/u-boot/drivers/mtd/nand/raw/zynq_nand.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2016 Xilinx, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Xilinx Zynq NAND Flash Controller Driver
5*4882a593Smuzhiyun  * This driver is based on plat_nand.c and mxc_nand.c drivers
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <common.h>
11*4882a593Smuzhiyun #include <malloc.h>
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <linux/errno.h>
14*4882a593Smuzhiyun #include <nand.h>
15*4882a593Smuzhiyun #include <linux/mtd/mtd.h>
16*4882a593Smuzhiyun #include <linux/mtd/rawnand.h>
17*4882a593Smuzhiyun #include <linux/mtd/partitions.h>
18*4882a593Smuzhiyun #include <linux/mtd/nand_ecc.h>
19*4882a593Smuzhiyun #include <asm/arch/hardware.h>
20*4882a593Smuzhiyun #include <asm/arch/sys_proto.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /* The NAND flash driver defines */
23*4882a593Smuzhiyun #define ZYNQ_NAND_CMD_PHASE		1
24*4882a593Smuzhiyun #define ZYNQ_NAND_DATA_PHASE		2
25*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_SIZE		512
26*4882a593Smuzhiyun #define ZYNQ_NAND_SET_OPMODE_8BIT	(0 << 0)
27*4882a593Smuzhiyun #define ZYNQ_NAND_SET_OPMODE_16BIT	(1 << 0)
28*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_STATUS		(1 << 6)
29*4882a593Smuzhiyun #define ZYNQ_MEMC_CLRCR_INT_CLR1	(1 << 4)
30*4882a593Smuzhiyun #define ZYNQ_MEMC_SR_RAW_INT_ST1	(1 << 6)
31*4882a593Smuzhiyun #define ZYNQ_MEMC_SR_INT_ST1		(1 << 4)
32*4882a593Smuzhiyun #define ZYNQ_MEMC_NAND_ECC_MODE_MASK	0xC
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /* Flash memory controller operating parameters */
35*4882a593Smuzhiyun #define ZYNQ_NAND_CLR_CONFIG	((0x1 << 1)  |	/* Disable interrupt */ \
36*4882a593Smuzhiyun 				(0x1 << 4)   |	/* Clear interrupt */ \
37*4882a593Smuzhiyun 				(0x1 << 6))	/* Disable ECC interrupt */
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #ifndef CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /* Assuming 50MHz clock (20ns cycle time) and 3V operation */
42*4882a593Smuzhiyun #define ZYNQ_NAND_SET_CYCLES	((0x2 << 20) |	/* t_rr from nand_cycles */ \
43*4882a593Smuzhiyun 				(0x2 << 17)  |	/* t_ar from nand_cycles */ \
44*4882a593Smuzhiyun 				(0x1 << 14)  |	/* t_clr from nand_cycles */ \
45*4882a593Smuzhiyun 				(0x3 << 11)  |	/* t_wp from nand_cycles */ \
46*4882a593Smuzhiyun 				(0x2 << 8)   |	/* t_rea from nand_cycles */ \
47*4882a593Smuzhiyun 				(0x5 << 4)   |	/* t_wc from nand_cycles */ \
48*4882a593Smuzhiyun 				(0x5 << 0))	/* t_rc from nand_cycles */
49*4882a593Smuzhiyun #endif
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define ZYNQ_NAND_DIRECT_CMD	((0x4 << 23) |	/* Chip 0 from interface 1 */ \
53*4882a593Smuzhiyun 				(0x2 << 21))	/* UpdateRegs operation */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_CONFIG	((0x1 << 2)  |	/* ECC available on APB */ \
56*4882a593Smuzhiyun 				(0x1 << 4)   |	/* ECC read at end of page */ \
57*4882a593Smuzhiyun 				(0x0 << 5))	/* No Jumping */
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_CMD1	((0x80)      |	/* Write command */ \
60*4882a593Smuzhiyun 				(0x00 << 8)  |	/* Read command */ \
61*4882a593Smuzhiyun 				(0x30 << 16) |	/* Read End command */ \
62*4882a593Smuzhiyun 				(0x1 << 24))	/* Read End command calid */
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_CMD2	((0x85)      |	/* Write col change cmd */ \
65*4882a593Smuzhiyun 				(0x05 << 8)  |	/* Read col change cmd */ \
66*4882a593Smuzhiyun 				(0xE0 << 16) |	/* Read col change end cmd */ \
67*4882a593Smuzhiyun 				(0x1 << 24))	/* Read col change
68*4882a593Smuzhiyun 							end cmd valid */
69*4882a593Smuzhiyun /* AXI Address definitions */
70*4882a593Smuzhiyun #define START_CMD_SHIFT			3
71*4882a593Smuzhiyun #define END_CMD_SHIFT			11
72*4882a593Smuzhiyun #define END_CMD_VALID_SHIFT		20
73*4882a593Smuzhiyun #define ADDR_CYCLES_SHIFT		21
74*4882a593Smuzhiyun #define CLEAR_CS_SHIFT			21
75*4882a593Smuzhiyun #define ECC_LAST_SHIFT			10
76*4882a593Smuzhiyun #define COMMAND_PHASE			(0 << 19)
77*4882a593Smuzhiyun #define DATA_PHASE			(1 << 19)
78*4882a593Smuzhiyun #define ONDIE_ECC_FEATURE_ADDR		0x90
79*4882a593Smuzhiyun #define ONDIE_ECC_FEATURE_ENABLE	0x08
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_LAST	(1 << ECC_LAST_SHIFT)	/* Set ECC_Last */
82*4882a593Smuzhiyun #define ZYNQ_NAND_CLEAR_CS	(1 << CLEAR_CS_SHIFT)	/* Clear chip select */
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /* ECC block registers bit position and bit mask */
85*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_BUSY	(1 << 6)	/* ECC block is busy */
86*4882a593Smuzhiyun #define ZYNQ_NAND_ECC_MASK	0x00FFFFFF	/* ECC value mask */
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #define ZYNQ_NAND_ROW_ADDR_CYCL_MASK	0x0F
89*4882a593Smuzhiyun #define ZYNQ_NAND_COL_ADDR_CYCL_MASK	0xF0
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #define ZYNQ_NAND_MIO_NUM_NAND_8BIT	13
92*4882a593Smuzhiyun #define ZYNQ_NAND_MIO_NUM_NAND_16BIT	8
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun enum zynq_nand_bus_width {
95*4882a593Smuzhiyun 	NAND_BW_UNKNOWN = -1,
96*4882a593Smuzhiyun 	NAND_BW_8BIT,
97*4882a593Smuzhiyun 	NAND_BW_16BIT,
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #ifndef NAND_CMD_LOCK_TIGHT
101*4882a593Smuzhiyun #define NAND_CMD_LOCK_TIGHT 0x2c
102*4882a593Smuzhiyun #endif
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #ifndef NAND_CMD_LOCK_STATUS
105*4882a593Smuzhiyun #define NAND_CMD_LOCK_STATUS 0x7a
106*4882a593Smuzhiyun #endif
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /* SMC register set */
109*4882a593Smuzhiyun struct zynq_nand_smc_regs {
110*4882a593Smuzhiyun 	u32 csr;		/* 0x00 */
111*4882a593Smuzhiyun 	u32 reserved0[2];
112*4882a593Smuzhiyun 	u32 cfr;		/* 0x0C */
113*4882a593Smuzhiyun 	u32 dcr;		/* 0x10 */
114*4882a593Smuzhiyun 	u32 scr;		/* 0x14 */
115*4882a593Smuzhiyun 	u32 sor;		/* 0x18 */
116*4882a593Smuzhiyun 	u32 reserved1[249];
117*4882a593Smuzhiyun 	u32 esr;		/* 0x400 */
118*4882a593Smuzhiyun 	u32 emcr;		/* 0x404 */
119*4882a593Smuzhiyun 	u32 emcmd1r;		/* 0x408 */
120*4882a593Smuzhiyun 	u32 emcmd2r;		/* 0x40C */
121*4882a593Smuzhiyun 	u32 reserved2[2];
122*4882a593Smuzhiyun 	u32 eval0r;		/* 0x418 */
123*4882a593Smuzhiyun };
124*4882a593Smuzhiyun #define zynq_nand_smc_base	((struct zynq_nand_smc_regs __iomem *)\
125*4882a593Smuzhiyun 				ZYNQ_SMC_BASEADDR)
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun  * struct zynq_nand_info - Defines the NAND flash driver instance
129*4882a593Smuzhiyun  * @parts:		Pointer to the mtd_partition structure
130*4882a593Smuzhiyun  * @nand_base:		Virtual address of the NAND flash device
131*4882a593Smuzhiyun  * @end_cmd_pending:	End command is pending
132*4882a593Smuzhiyun  * @end_cmd:		End command
133*4882a593Smuzhiyun  */
134*4882a593Smuzhiyun struct zynq_nand_info {
135*4882a593Smuzhiyun 	void __iomem	*nand_base;
136*4882a593Smuzhiyun 	u8		end_cmd_pending;
137*4882a593Smuzhiyun 	u8		end_cmd;
138*4882a593Smuzhiyun };
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun  * struct zynq_nand_command_format - Defines NAND flash command format
142*4882a593Smuzhiyun  * @start_cmd:		First cycle command (Start command)
143*4882a593Smuzhiyun  * @end_cmd:		Second cycle command (Last command)
144*4882a593Smuzhiyun  * @addr_cycles:	Number of address cycles required to send the address
145*4882a593Smuzhiyun  * @end_cmd_valid:	The second cycle command is valid for cmd or data phase
146*4882a593Smuzhiyun  */
147*4882a593Smuzhiyun struct zynq_nand_command_format {
148*4882a593Smuzhiyun 	u8 start_cmd;
149*4882a593Smuzhiyun 	u8 end_cmd;
150*4882a593Smuzhiyun 	u8 addr_cycles;
151*4882a593Smuzhiyun 	u8 end_cmd_valid;
152*4882a593Smuzhiyun };
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /*  The NAND flash operations command format */
155*4882a593Smuzhiyun static const struct zynq_nand_command_format zynq_nand_commands[] = {
156*4882a593Smuzhiyun 	{NAND_CMD_READ0, NAND_CMD_READSTART, 5, ZYNQ_NAND_CMD_PHASE},
157*4882a593Smuzhiyun 	{NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, 2, ZYNQ_NAND_CMD_PHASE},
158*4882a593Smuzhiyun 	{NAND_CMD_READID, NAND_CMD_NONE, 1, 0},
159*4882a593Smuzhiyun 	{NAND_CMD_STATUS, NAND_CMD_NONE, 0, 0},
160*4882a593Smuzhiyun 	{NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, 5, ZYNQ_NAND_DATA_PHASE},
161*4882a593Smuzhiyun 	{NAND_CMD_RNDIN, NAND_CMD_NONE, 2, 0},
162*4882a593Smuzhiyun 	{NAND_CMD_ERASE1, NAND_CMD_ERASE2, 3, ZYNQ_NAND_CMD_PHASE},
163*4882a593Smuzhiyun 	{NAND_CMD_RESET, NAND_CMD_NONE, 0, 0},
164*4882a593Smuzhiyun 	{NAND_CMD_PARAM, NAND_CMD_NONE, 1, 0},
165*4882a593Smuzhiyun 	{NAND_CMD_GET_FEATURES, NAND_CMD_NONE, 1, 0},
166*4882a593Smuzhiyun 	{NAND_CMD_SET_FEATURES, NAND_CMD_NONE, 1, 0},
167*4882a593Smuzhiyun 	{NAND_CMD_LOCK, NAND_CMD_NONE, 0, 0},
168*4882a593Smuzhiyun 	{NAND_CMD_LOCK_TIGHT, NAND_CMD_NONE, 0, 0},
169*4882a593Smuzhiyun 	{NAND_CMD_UNLOCK1, NAND_CMD_NONE, 3, 0},
170*4882a593Smuzhiyun 	{NAND_CMD_UNLOCK2, NAND_CMD_NONE, 3, 0},
171*4882a593Smuzhiyun 	{NAND_CMD_LOCK_STATUS, NAND_CMD_NONE, 3, 0},
172*4882a593Smuzhiyun 	{NAND_CMD_NONE, NAND_CMD_NONE, 0, 0},
173*4882a593Smuzhiyun 	/* Add all the flash commands supported by the flash device */
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /* Define default oob placement schemes for large and small page devices */
177*4882a593Smuzhiyun static struct nand_ecclayout nand_oob_16 = {
178*4882a593Smuzhiyun 	.eccbytes = 3,
179*4882a593Smuzhiyun 	.eccpos = {0, 1, 2},
180*4882a593Smuzhiyun 	.oobfree = {
181*4882a593Smuzhiyun 		{ .offset = 8, .length = 8 }
182*4882a593Smuzhiyun 	}
183*4882a593Smuzhiyun };
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun static struct nand_ecclayout nand_oob_64 = {
186*4882a593Smuzhiyun 	.eccbytes = 12,
187*4882a593Smuzhiyun 	.eccpos = {
188*4882a593Smuzhiyun 		   52, 53, 54, 55, 56, 57,
189*4882a593Smuzhiyun 		   58, 59, 60, 61, 62, 63},
190*4882a593Smuzhiyun 	.oobfree = {
191*4882a593Smuzhiyun 		{ .offset = 2, .length = 50 }
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun static struct nand_ecclayout ondie_nand_oob_64 = {
196*4882a593Smuzhiyun 	.eccbytes = 32,
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	.eccpos = {
199*4882a593Smuzhiyun 		8, 9, 10, 11, 12, 13, 14, 15,
200*4882a593Smuzhiyun 		24, 25, 26, 27, 28, 29, 30, 31,
201*4882a593Smuzhiyun 		40, 41, 42, 43, 44, 45, 46, 47,
202*4882a593Smuzhiyun 		56, 57, 58, 59, 60, 61, 62, 63
203*4882a593Smuzhiyun 	},
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	.oobfree = {
206*4882a593Smuzhiyun 		{ .offset = 4, .length = 4 },
207*4882a593Smuzhiyun 		{ .offset = 20, .length = 4 },
208*4882a593Smuzhiyun 		{ .offset = 36, .length = 4 },
209*4882a593Smuzhiyun 		{ .offset = 52, .length = 4 }
210*4882a593Smuzhiyun 	}
211*4882a593Smuzhiyun };
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun /* bbt decriptors for chips with on-die ECC and
214*4882a593Smuzhiyun    chips with 64-byte OOB */
215*4882a593Smuzhiyun static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
216*4882a593Smuzhiyun static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun static struct nand_bbt_descr bbt_main_descr = {
219*4882a593Smuzhiyun 	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
220*4882a593Smuzhiyun 		NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
221*4882a593Smuzhiyun 	.offs = 4,
222*4882a593Smuzhiyun 	.len = 4,
223*4882a593Smuzhiyun 	.veroffs = 20,
224*4882a593Smuzhiyun 	.maxblocks = 4,
225*4882a593Smuzhiyun 	.pattern = bbt_pattern
226*4882a593Smuzhiyun };
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun static struct nand_bbt_descr bbt_mirror_descr = {
229*4882a593Smuzhiyun 	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
230*4882a593Smuzhiyun 		NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
231*4882a593Smuzhiyun 	.offs = 4,
232*4882a593Smuzhiyun 	.len = 4,
233*4882a593Smuzhiyun 	.veroffs = 20,
234*4882a593Smuzhiyun 	.maxblocks = 4,
235*4882a593Smuzhiyun 	.pattern = mirror_pattern
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /*
239*4882a593Smuzhiyun  * zynq_nand_waitfor_ecc_completion - Wait for ECC completion
240*4882a593Smuzhiyun  *
241*4882a593Smuzhiyun  * returns: status for command completion, -1 for Timeout
242*4882a593Smuzhiyun  */
zynq_nand_waitfor_ecc_completion(void)243*4882a593Smuzhiyun static int zynq_nand_waitfor_ecc_completion(void)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	unsigned long timeout;
246*4882a593Smuzhiyun 	u32 status;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	/* Wait max 10us */
249*4882a593Smuzhiyun 	timeout = 10;
250*4882a593Smuzhiyun 	status = readl(&zynq_nand_smc_base->esr);
251*4882a593Smuzhiyun 	while (status & ZYNQ_NAND_ECC_BUSY) {
252*4882a593Smuzhiyun 		status = readl(&zynq_nand_smc_base->esr);
253*4882a593Smuzhiyun 		if (timeout == 0)
254*4882a593Smuzhiyun 			return -1;
255*4882a593Smuzhiyun 		timeout--;
256*4882a593Smuzhiyun 		udelay(1);
257*4882a593Smuzhiyun 	}
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	return status;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun /*
263*4882a593Smuzhiyun  * zynq_nand_init_nand_flash - Initialize NAND controller
264*4882a593Smuzhiyun  * @option:	Device property flags
265*4882a593Smuzhiyun  *
266*4882a593Smuzhiyun  * This function initializes the NAND flash interface on the NAND controller.
267*4882a593Smuzhiyun  *
268*4882a593Smuzhiyun  * returns:	0 on success or error value on failure
269*4882a593Smuzhiyun  */
zynq_nand_init_nand_flash(int option)270*4882a593Smuzhiyun static int zynq_nand_init_nand_flash(int option)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	u32 status;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	/* disable interrupts */
275*4882a593Smuzhiyun 	writel(ZYNQ_NAND_CLR_CONFIG, &zynq_nand_smc_base->cfr);
276*4882a593Smuzhiyun #ifndef CONFIG_NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS
277*4882a593Smuzhiyun 	/* Initialize the NAND interface by setting cycles and operation mode */
278*4882a593Smuzhiyun 	writel(ZYNQ_NAND_SET_CYCLES, &zynq_nand_smc_base->scr);
279*4882a593Smuzhiyun #endif
280*4882a593Smuzhiyun 	if (option & NAND_BUSWIDTH_16)
281*4882a593Smuzhiyun 		writel(ZYNQ_NAND_SET_OPMODE_16BIT, &zynq_nand_smc_base->sor);
282*4882a593Smuzhiyun 	else
283*4882a593Smuzhiyun 		writel(ZYNQ_NAND_SET_OPMODE_8BIT, &zynq_nand_smc_base->sor);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	writel(ZYNQ_NAND_DIRECT_CMD, &zynq_nand_smc_base->dcr);
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	/* Wait till the ECC operation is complete */
288*4882a593Smuzhiyun 	status = zynq_nand_waitfor_ecc_completion();
289*4882a593Smuzhiyun 	if (status < 0) {
290*4882a593Smuzhiyun 		printf("%s: Timeout\n", __func__);
291*4882a593Smuzhiyun 		return status;
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	/* Set the command1 and command2 register */
295*4882a593Smuzhiyun 	writel(ZYNQ_NAND_ECC_CMD1, &zynq_nand_smc_base->emcmd1r);
296*4882a593Smuzhiyun 	writel(ZYNQ_NAND_ECC_CMD2, &zynq_nand_smc_base->emcmd2r);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	return 0;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun /*
302*4882a593Smuzhiyun  * zynq_nand_calculate_hwecc - Calculate Hardware ECC
303*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd_info structure
304*4882a593Smuzhiyun  * @data:	Pointer to the page data
305*4882a593Smuzhiyun  * @ecc_code:	Pointer to the ECC buffer where ECC data needs to be stored
306*4882a593Smuzhiyun  *
307*4882a593Smuzhiyun  * This function retrieves the Hardware ECC data from the controller and returns
308*4882a593Smuzhiyun  * ECC data back to the MTD subsystem.
309*4882a593Smuzhiyun  *
310*4882a593Smuzhiyun  * returns:	0 on success or error value on failure
311*4882a593Smuzhiyun  */
zynq_nand_calculate_hwecc(struct mtd_info * mtd,const u8 * data,u8 * ecc_code)312*4882a593Smuzhiyun static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data,
313*4882a593Smuzhiyun 		u8 *ecc_code)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun 	u32 ecc_value = 0;
316*4882a593Smuzhiyun 	u8 ecc_reg, ecc_byte;
317*4882a593Smuzhiyun 	u32 ecc_status;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	/* Wait till the ECC operation is complete */
320*4882a593Smuzhiyun 	ecc_status = zynq_nand_waitfor_ecc_completion();
321*4882a593Smuzhiyun 	if (ecc_status < 0) {
322*4882a593Smuzhiyun 		printf("%s: Timeout\n", __func__);
323*4882a593Smuzhiyun 		return ecc_status;
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) {
327*4882a593Smuzhiyun 		/* Read ECC value for each block */
328*4882a593Smuzhiyun 		ecc_value = readl(&zynq_nand_smc_base->eval0r + ecc_reg);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		/* Get the ecc status from ecc read value */
331*4882a593Smuzhiyun 		ecc_status = (ecc_value >> 24) & 0xFF;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 		/* ECC value valid */
334*4882a593Smuzhiyun 		if (ecc_status & ZYNQ_NAND_ECC_STATUS) {
335*4882a593Smuzhiyun 			for (ecc_byte = 0; ecc_byte < 3; ecc_byte++) {
336*4882a593Smuzhiyun 				/* Copy ECC bytes to MTD buffer */
337*4882a593Smuzhiyun 				*ecc_code = ecc_value & 0xFF;
338*4882a593Smuzhiyun 				ecc_value = ecc_value >> 8;
339*4882a593Smuzhiyun 				ecc_code++;
340*4882a593Smuzhiyun 			}
341*4882a593Smuzhiyun 		} else {
342*4882a593Smuzhiyun 			debug("%s: ecc status failed\n", __func__);
343*4882a593Smuzhiyun 		}
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	return 0;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun /*
350*4882a593Smuzhiyun  * onehot - onehot function
351*4882a593Smuzhiyun  * @value:	value to check for onehot
352*4882a593Smuzhiyun  *
353*4882a593Smuzhiyun  * This function checks whether a value is onehot or not.
354*4882a593Smuzhiyun  * onehot is if and only if one bit is set.
355*4882a593Smuzhiyun  *
356*4882a593Smuzhiyun  * FIXME: Try to move this in common.h
357*4882a593Smuzhiyun  */
onehot(unsigned short value)358*4882a593Smuzhiyun static bool onehot(unsigned short value)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	bool onehot;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	onehot = value && !(value & (value - 1));
363*4882a593Smuzhiyun 	return onehot;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun /*
367*4882a593Smuzhiyun  * zynq_nand_correct_data - ECC correction function
368*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd_info structure
369*4882a593Smuzhiyun  * @buf:	Pointer to the page data
370*4882a593Smuzhiyun  * @read_ecc:	Pointer to the ECC value read from spare data area
371*4882a593Smuzhiyun  * @calc_ecc:	Pointer to the calculated ECC value
372*4882a593Smuzhiyun  *
373*4882a593Smuzhiyun  * This function corrects the ECC single bit errors & detects 2-bit errors.
374*4882a593Smuzhiyun  *
375*4882a593Smuzhiyun  * returns:	0 if no ECC errors found
376*4882a593Smuzhiyun  *		1 if single bit error found and corrected.
377*4882a593Smuzhiyun  *		-1 if multiple ECC errors found.
378*4882a593Smuzhiyun  */
zynq_nand_correct_data(struct mtd_info * mtd,unsigned char * buf,unsigned char * read_ecc,unsigned char * calc_ecc)379*4882a593Smuzhiyun static int zynq_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
380*4882a593Smuzhiyun 			unsigned char *read_ecc, unsigned char *calc_ecc)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	unsigned char bit_addr;
383*4882a593Smuzhiyun 	unsigned int byte_addr;
384*4882a593Smuzhiyun 	unsigned short ecc_odd, ecc_even;
385*4882a593Smuzhiyun 	unsigned short read_ecc_lower, read_ecc_upper;
386*4882a593Smuzhiyun 	unsigned short calc_ecc_lower, calc_ecc_upper;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & 0xfff;
389*4882a593Smuzhiyun 	read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & 0xfff;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & 0xfff;
392*4882a593Smuzhiyun 	calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & 0xfff;
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	ecc_odd = read_ecc_lower ^ calc_ecc_lower;
395*4882a593Smuzhiyun 	ecc_even = read_ecc_upper ^ calc_ecc_upper;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	if ((ecc_odd == 0) && (ecc_even == 0))
398*4882a593Smuzhiyun 		return 0;       /* no error */
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	if (ecc_odd == (~ecc_even & 0xfff)) {
401*4882a593Smuzhiyun 		/* bits [11:3] of error code is byte offset */
402*4882a593Smuzhiyun 		byte_addr = (ecc_odd >> 3) & 0x1ff;
403*4882a593Smuzhiyun 		/* bits [2:0] of error code is bit offset */
404*4882a593Smuzhiyun 		bit_addr = ecc_odd & 0x7;
405*4882a593Smuzhiyun 		/* Toggling error bit */
406*4882a593Smuzhiyun 		buf[byte_addr] ^= (1 << bit_addr);
407*4882a593Smuzhiyun 		return 1;
408*4882a593Smuzhiyun 	}
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	if (onehot(ecc_odd | ecc_even))
411*4882a593Smuzhiyun 		return 1; /* one error in parity */
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	return -1; /* Uncorrectable error */
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun /*
417*4882a593Smuzhiyun  * zynq_nand_read_oob - [REPLACABLE] the most common OOB data read function
418*4882a593Smuzhiyun  * @mtd:	mtd info structure
419*4882a593Smuzhiyun  * @chip:	nand chip info structure
420*4882a593Smuzhiyun  * @page:	page number to read
421*4882a593Smuzhiyun  * @sndcmd:	flag whether to issue read command or not
422*4882a593Smuzhiyun  */
zynq_nand_read_oob(struct mtd_info * mtd,struct nand_chip * chip,int page)423*4882a593Smuzhiyun static int zynq_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
424*4882a593Smuzhiyun 			int page)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
427*4882a593Smuzhiyun 	int data_width = 4;
428*4882a593Smuzhiyun 	u8 *p;
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	p = chip->oob_poi;
433*4882a593Smuzhiyun 	chip->read_buf(mtd, p, (mtd->oobsize - data_width));
434*4882a593Smuzhiyun 	p += mtd->oobsize - data_width;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_R;
437*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
438*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
439*4882a593Smuzhiyun 	chip->read_buf(mtd, p, data_width);
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	return 0;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun /*
445*4882a593Smuzhiyun  * zynq_nand_write_oob - [REPLACABLE] the most common OOB data write function
446*4882a593Smuzhiyun  * @mtd:	mtd info structure
447*4882a593Smuzhiyun  * @chip:	nand chip info structure
448*4882a593Smuzhiyun  * @page:	page number to write
449*4882a593Smuzhiyun  */
zynq_nand_write_oob(struct mtd_info * mtd,struct nand_chip * chip,int page)450*4882a593Smuzhiyun static int zynq_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
451*4882a593Smuzhiyun 			     int page)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	int status = 0, data_width = 4;
454*4882a593Smuzhiyun 	const u8 *buf = chip->oob_poi;
455*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	chip->write_buf(mtd, buf, (mtd->oobsize - data_width));
460*4882a593Smuzhiyun 	buf += mtd->oobsize - data_width;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_W;
463*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
464*4882a593Smuzhiyun 	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
465*4882a593Smuzhiyun 	chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
466*4882a593Smuzhiyun 	chip->write_buf(mtd, buf, data_width);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/* Send command to program the OOB data */
469*4882a593Smuzhiyun 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
470*4882a593Smuzhiyun 	status = chip->waitfunc(mtd, chip);
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	return status & NAND_STATUS_FAIL ? -EIO : 0;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun /*
476*4882a593Smuzhiyun  * zynq_nand_read_page_raw - [Intern] read raw page data without ecc
477*4882a593Smuzhiyun  * @mtd:        mtd info structure
478*4882a593Smuzhiyun  * @chip:       nand chip info structure
479*4882a593Smuzhiyun  * @buf:        buffer to store read data
480*4882a593Smuzhiyun  * @oob_required: must write chip->oob_poi to OOB
481*4882a593Smuzhiyun  * @page:       page number to read
482*4882a593Smuzhiyun  */
zynq_nand_read_page_raw(struct mtd_info * mtd,struct nand_chip * chip,u8 * buf,int oob_required,int page)483*4882a593Smuzhiyun static int zynq_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
484*4882a593Smuzhiyun 				   u8 *buf,  int oob_required, int page)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun 	unsigned long data_width = 4;
487*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
488*4882a593Smuzhiyun 	u8 *p;
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	chip->read_buf(mtd, buf, mtd->writesize);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	p = chip->oob_poi;
493*4882a593Smuzhiyun 	chip->read_buf(mtd, p, (mtd->oobsize - data_width));
494*4882a593Smuzhiyun 	p += (mtd->oobsize - data_width);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_R;
497*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
498*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	chip->read_buf(mtd, p, data_width);
501*4882a593Smuzhiyun 	return 0;
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun 
zynq_nand_read_page_raw_nooob(struct mtd_info * mtd,struct nand_chip * chip,u8 * buf,int oob_required,int page)504*4882a593Smuzhiyun static int zynq_nand_read_page_raw_nooob(struct mtd_info *mtd,
505*4882a593Smuzhiyun 		struct nand_chip *chip, u8 *buf, int oob_required, int page)
506*4882a593Smuzhiyun {
507*4882a593Smuzhiyun 	chip->read_buf(mtd, buf, mtd->writesize);
508*4882a593Smuzhiyun 	return 0;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
zynq_nand_read_subpage_raw(struct mtd_info * mtd,struct nand_chip * chip,u32 data_offs,u32 readlen,u8 * buf,int page)511*4882a593Smuzhiyun static int zynq_nand_read_subpage_raw(struct mtd_info *mtd,
512*4882a593Smuzhiyun 				    struct nand_chip *chip, u32 data_offs,
513*4882a593Smuzhiyun 				    u32 readlen, u8 *buf, int page)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun 	if (data_offs != 0) {
516*4882a593Smuzhiyun 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_offs, -1);
517*4882a593Smuzhiyun 		buf += data_offs;
518*4882a593Smuzhiyun 	}
519*4882a593Smuzhiyun 	chip->read_buf(mtd, buf, readlen);
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	return 0;
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun /*
525*4882a593Smuzhiyun  * zynq_nand_write_page_raw - [Intern] raw page write function
526*4882a593Smuzhiyun  * @mtd:        mtd info structure
527*4882a593Smuzhiyun  * @chip:       nand chip info structure
528*4882a593Smuzhiyun  * @buf:        data buffer
529*4882a593Smuzhiyun  * @oob_required: must write chip->oob_poi to OOB
530*4882a593Smuzhiyun  */
zynq_nand_write_page_raw(struct mtd_info * mtd,struct nand_chip * chip,const u8 * buf,int oob_required,int page)531*4882a593Smuzhiyun static int zynq_nand_write_page_raw(struct mtd_info *mtd,
532*4882a593Smuzhiyun 	struct nand_chip *chip, const u8 *buf, int oob_required, int page)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun 	unsigned long data_width = 4;
535*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
536*4882a593Smuzhiyun 	u8 *p;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	chip->write_buf(mtd, buf, mtd->writesize);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	p = chip->oob_poi;
541*4882a593Smuzhiyun 	chip->write_buf(mtd, p, (mtd->oobsize - data_width));
542*4882a593Smuzhiyun 	p += (mtd->oobsize - data_width);
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_W;
545*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
546*4882a593Smuzhiyun 	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
547*4882a593Smuzhiyun 	chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	chip->write_buf(mtd, p, data_width);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	return 0;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun /*
555*4882a593Smuzhiyun  * nand_write_page_hwecc - Hardware ECC based page write function
556*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd info structure
557*4882a593Smuzhiyun  * @chip:	Pointer to the NAND chip info structure
558*4882a593Smuzhiyun  * @buf:	Pointer to the data buffer
559*4882a593Smuzhiyun  * @oob_required: must write chip->oob_poi to OOB
560*4882a593Smuzhiyun  *
561*4882a593Smuzhiyun  * This functions writes data and hardware generated ECC values in to the page.
562*4882a593Smuzhiyun  */
zynq_nand_write_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,const u8 * buf,int oob_required,int page)563*4882a593Smuzhiyun static int zynq_nand_write_page_hwecc(struct mtd_info *mtd,
564*4882a593Smuzhiyun 	struct nand_chip *chip, const u8 *buf, int oob_required, int page)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun 	int i, eccsteps, eccsize = chip->ecc.size;
567*4882a593Smuzhiyun 	u8 *ecc_calc = chip->buffers->ecccalc;
568*4882a593Smuzhiyun 	const u8 *p = buf;
569*4882a593Smuzhiyun 	u32 *eccpos = chip->ecc.layout->eccpos;
570*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
571*4882a593Smuzhiyun 	unsigned long data_width = 4;
572*4882a593Smuzhiyun 	u8 *oob_ptr;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	for (eccsteps = chip->ecc.steps; (eccsteps - 1); eccsteps--) {
575*4882a593Smuzhiyun 		chip->write_buf(mtd, p, eccsize);
576*4882a593Smuzhiyun 		p += eccsize;
577*4882a593Smuzhiyun 	}
578*4882a593Smuzhiyun 	chip->write_buf(mtd, p, (eccsize - data_width));
579*4882a593Smuzhiyun 	p += eccsize - data_width;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	/* Set ECC Last bit to 1 */
582*4882a593Smuzhiyun 	data_phase_addr = (unsigned long) chip->IO_ADDR_W;
583*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_ECC_LAST;
584*4882a593Smuzhiyun 	chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
585*4882a593Smuzhiyun 	chip->write_buf(mtd, p, data_width);
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	/* Wait for ECC to be calculated and read the error values */
588*4882a593Smuzhiyun 	p = buf;
589*4882a593Smuzhiyun 	chip->ecc.calculate(mtd, p, &ecc_calc[0]);
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	for (i = 0; i < chip->ecc.total; i++)
592*4882a593Smuzhiyun 		chip->oob_poi[eccpos[i]] = ~(ecc_calc[i]);
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	/* Clear ECC last bit */
595*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_W;
596*4882a593Smuzhiyun 	data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
597*4882a593Smuzhiyun 	chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	/* Write the spare area with ECC bytes */
600*4882a593Smuzhiyun 	oob_ptr = chip->oob_poi;
601*4882a593Smuzhiyun 	chip->write_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_W;
604*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
605*4882a593Smuzhiyun 	data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
606*4882a593Smuzhiyun 	chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
607*4882a593Smuzhiyun 	oob_ptr += (mtd->oobsize - data_width);
608*4882a593Smuzhiyun 	chip->write_buf(mtd, oob_ptr, data_width);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	return 0;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun /*
614*4882a593Smuzhiyun  * zynq_nand_write_page_swecc - [REPLACABLE] software ecc based page
615*4882a593Smuzhiyun  * write function
616*4882a593Smuzhiyun  * @mtd:	mtd info structure
617*4882a593Smuzhiyun  * @chip:	nand chip info structure
618*4882a593Smuzhiyun  * @buf:	data buffer
619*4882a593Smuzhiyun  * @oob_required: must write chip->oob_poi to OOB
620*4882a593Smuzhiyun  */
zynq_nand_write_page_swecc(struct mtd_info * mtd,struct nand_chip * chip,const u8 * buf,int oob_required,int page)621*4882a593Smuzhiyun static int zynq_nand_write_page_swecc(struct mtd_info *mtd,
622*4882a593Smuzhiyun 	struct nand_chip *chip, const u8 *buf, int oob_required, int page)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	int i, eccsize = chip->ecc.size;
625*4882a593Smuzhiyun 	int eccbytes = chip->ecc.bytes;
626*4882a593Smuzhiyun 	int eccsteps = chip->ecc.steps;
627*4882a593Smuzhiyun 	u8 *ecc_calc = chip->buffers->ecccalc;
628*4882a593Smuzhiyun 	const u8 *p = buf;
629*4882a593Smuzhiyun 	u32 *eccpos = chip->ecc.layout->eccpos;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	/* Software ecc calculation */
632*4882a593Smuzhiyun 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
633*4882a593Smuzhiyun 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	for (i = 0; i < chip->ecc.total; i++)
636*4882a593Smuzhiyun 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun 	return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun /*
642*4882a593Smuzhiyun  * nand_read_page_hwecc - Hardware ECC based page read function
643*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd info structure
644*4882a593Smuzhiyun  * @chip:	Pointer to the NAND chip info structure
645*4882a593Smuzhiyun  * @buf:	Pointer to the buffer to store read data
646*4882a593Smuzhiyun  * @oob_required: must write chip->oob_poi to OOB
647*4882a593Smuzhiyun  * @page:	page number to read
648*4882a593Smuzhiyun  *
649*4882a593Smuzhiyun  * This functions reads data and checks the data integrity by comparing hardware
650*4882a593Smuzhiyun  * generated ECC values and read ECC values from spare area.
651*4882a593Smuzhiyun  *
652*4882a593Smuzhiyun  * returns:	0 always and updates ECC operation status in to MTD structure
653*4882a593Smuzhiyun  */
zynq_nand_read_page_hwecc(struct mtd_info * mtd,struct nand_chip * chip,u8 * buf,int oob_required,int page)654*4882a593Smuzhiyun static int zynq_nand_read_page_hwecc(struct mtd_info *mtd,
655*4882a593Smuzhiyun 	struct nand_chip *chip, u8 *buf, int oob_required, int page)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun 	int i, stat, eccsteps, eccsize = chip->ecc.size;
658*4882a593Smuzhiyun 	int eccbytes = chip->ecc.bytes;
659*4882a593Smuzhiyun 	u8 *p = buf;
660*4882a593Smuzhiyun 	u8 *ecc_calc = chip->buffers->ecccalc;
661*4882a593Smuzhiyun 	u8 *ecc_code = chip->buffers->ecccode;
662*4882a593Smuzhiyun 	u32 *eccpos = chip->ecc.layout->eccpos;
663*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
664*4882a593Smuzhiyun 	unsigned long data_width = 4;
665*4882a593Smuzhiyun 	u8 *oob_ptr;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	for (eccsteps = chip->ecc.steps; (eccsteps - 1); eccsteps--) {
668*4882a593Smuzhiyun 		chip->read_buf(mtd, p, eccsize);
669*4882a593Smuzhiyun 		p += eccsize;
670*4882a593Smuzhiyun 	}
671*4882a593Smuzhiyun 	chip->read_buf(mtd, p, (eccsize - data_width));
672*4882a593Smuzhiyun 	p += eccsize - data_width;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	/* Set ECC Last bit to 1 */
675*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_R;
676*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_ECC_LAST;
677*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
678*4882a593Smuzhiyun 	chip->read_buf(mtd, p, data_width);
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	/* Read the calculated ECC value */
681*4882a593Smuzhiyun 	p = buf;
682*4882a593Smuzhiyun 	chip->ecc.calculate(mtd, p, &ecc_calc[0]);
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	/* Clear ECC last bit */
685*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_R;
686*4882a593Smuzhiyun 	data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
687*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* Read the stored ECC value */
690*4882a593Smuzhiyun 	oob_ptr = chip->oob_poi;
691*4882a593Smuzhiyun 	chip->read_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	/* de-assert chip select */
694*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)chip->IO_ADDR_R;
695*4882a593Smuzhiyun 	data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
696*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	oob_ptr += (mtd->oobsize - data_width);
699*4882a593Smuzhiyun 	chip->read_buf(mtd, oob_ptr, data_width);
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	for (i = 0; i < chip->ecc.total; i++)
702*4882a593Smuzhiyun 		ecc_code[i] = ~(chip->oob_poi[eccpos[i]]);
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	eccsteps = chip->ecc.steps;
705*4882a593Smuzhiyun 	p = buf;
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	/* Check ECC error for all blocks and correct if it is correctable */
708*4882a593Smuzhiyun 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
709*4882a593Smuzhiyun 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
710*4882a593Smuzhiyun 		if (stat < 0)
711*4882a593Smuzhiyun 			mtd->ecc_stats.failed++;
712*4882a593Smuzhiyun 		else
713*4882a593Smuzhiyun 			mtd->ecc_stats.corrected += stat;
714*4882a593Smuzhiyun 	}
715*4882a593Smuzhiyun 	return 0;
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun /*
719*4882a593Smuzhiyun  * zynq_nand_read_page_swecc - [REPLACABLE] software ecc based page
720*4882a593Smuzhiyun  * read function
721*4882a593Smuzhiyun  * @mtd:	mtd info structure
722*4882a593Smuzhiyun  * @chip:	nand chip info structure
723*4882a593Smuzhiyun  * @buf:	buffer to store read data
724*4882a593Smuzhiyun  * @page:	page number to read
725*4882a593Smuzhiyun  */
zynq_nand_read_page_swecc(struct mtd_info * mtd,struct nand_chip * chip,u8 * buf,int oob_required,int page)726*4882a593Smuzhiyun static int zynq_nand_read_page_swecc(struct mtd_info *mtd,
727*4882a593Smuzhiyun 	struct nand_chip *chip, u8 *buf, int oob_required,  int page)
728*4882a593Smuzhiyun {
729*4882a593Smuzhiyun 	int i, eccsize = chip->ecc.size;
730*4882a593Smuzhiyun 	int eccbytes = chip->ecc.bytes;
731*4882a593Smuzhiyun 	int eccsteps = chip->ecc.steps;
732*4882a593Smuzhiyun 	u8 *p = buf;
733*4882a593Smuzhiyun 	u8 *ecc_calc = chip->buffers->ecccalc;
734*4882a593Smuzhiyun 	u8 *ecc_code = chip->buffers->ecccode;
735*4882a593Smuzhiyun 	u32 *eccpos = chip->ecc.layout->eccpos;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
740*4882a593Smuzhiyun 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	for (i = 0; i < chip->ecc.total; i++)
743*4882a593Smuzhiyun 		ecc_code[i] = chip->oob_poi[eccpos[i]];
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	eccsteps = chip->ecc.steps;
746*4882a593Smuzhiyun 	p = buf;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
749*4882a593Smuzhiyun 		int stat;
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
752*4882a593Smuzhiyun 		if (stat < 0)
753*4882a593Smuzhiyun 			mtd->ecc_stats.failed++;
754*4882a593Smuzhiyun 		else
755*4882a593Smuzhiyun 			mtd->ecc_stats.corrected += stat;
756*4882a593Smuzhiyun 	}
757*4882a593Smuzhiyun 	return 0;
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun /*
761*4882a593Smuzhiyun  * zynq_nand_select_chip - Select the flash device
762*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd_info structure
763*4882a593Smuzhiyun  * @chip:	Chip number to be selected
764*4882a593Smuzhiyun  *
765*4882a593Smuzhiyun  * This function is empty as the NAND controller handles chip select line
766*4882a593Smuzhiyun  * internally based on the chip address passed in command and data phase.
767*4882a593Smuzhiyun  */
zynq_nand_select_chip(struct mtd_info * mtd,int chip)768*4882a593Smuzhiyun static void zynq_nand_select_chip(struct mtd_info *mtd, int chip)
769*4882a593Smuzhiyun {
770*4882a593Smuzhiyun 	/* Not support multiple chips yet */
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun /*
774*4882a593Smuzhiyun  * zynq_nand_cmd_function - Send command to NAND device
775*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd_info structure
776*4882a593Smuzhiyun  * @command:	The command to be sent to the flash device
777*4882a593Smuzhiyun  * @column:	The column address for this command, -1 if none
778*4882a593Smuzhiyun  * @page_addr:	The page address for this command, -1 if none
779*4882a593Smuzhiyun  */
zynq_nand_cmd_function(struct mtd_info * mtd,unsigned int command,int column,int page_addr)780*4882a593Smuzhiyun static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
781*4882a593Smuzhiyun 				 int column, int page_addr)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun 	struct nand_chip *chip = mtd->priv;
784*4882a593Smuzhiyun 	const struct zynq_nand_command_format *curr_cmd = NULL;
785*4882a593Smuzhiyun 	u8 addr_cycles = 0;
786*4882a593Smuzhiyun 	struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv;
787*4882a593Smuzhiyun 	void *cmd_addr;
788*4882a593Smuzhiyun 	unsigned long cmd_data = 0;
789*4882a593Smuzhiyun 	unsigned long cmd_phase_addr = 0;
790*4882a593Smuzhiyun 	unsigned long data_phase_addr = 0;
791*4882a593Smuzhiyun 	u8 end_cmd = 0;
792*4882a593Smuzhiyun 	u8 end_cmd_valid = 0;
793*4882a593Smuzhiyun 	u32 index;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	if (xnand->end_cmd_pending) {
796*4882a593Smuzhiyun 		/* Check for end command if this command request is same as the
797*4882a593Smuzhiyun 		 * pending command then return
798*4882a593Smuzhiyun 		 */
799*4882a593Smuzhiyun 		if (xnand->end_cmd == command) {
800*4882a593Smuzhiyun 			xnand->end_cmd = 0;
801*4882a593Smuzhiyun 			xnand->end_cmd_pending = 0;
802*4882a593Smuzhiyun 			return;
803*4882a593Smuzhiyun 		}
804*4882a593Smuzhiyun 	}
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun 	/* Emulate NAND_CMD_READOOB for large page device */
807*4882a593Smuzhiyun 	if ((mtd->writesize > ZYNQ_NAND_ECC_SIZE) &&
808*4882a593Smuzhiyun 	    (command == NAND_CMD_READOOB)) {
809*4882a593Smuzhiyun 		column += mtd->writesize;
810*4882a593Smuzhiyun 		command = NAND_CMD_READ0;
811*4882a593Smuzhiyun 	}
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 	/* Get the command format */
814*4882a593Smuzhiyun 	for (index = 0; index < ARRAY_SIZE(zynq_nand_commands); index++)
815*4882a593Smuzhiyun 		if (command == zynq_nand_commands[index].start_cmd)
816*4882a593Smuzhiyun 			break;
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	if (index == ARRAY_SIZE(zynq_nand_commands)) {
819*4882a593Smuzhiyun 		printf("%s: Unsupported start cmd %02x\n", __func__, command);
820*4882a593Smuzhiyun 		return;
821*4882a593Smuzhiyun 	}
822*4882a593Smuzhiyun 	curr_cmd = &zynq_nand_commands[index];
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	/* Clear interrupt */
825*4882a593Smuzhiyun 	writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &zynq_nand_smc_base->cfr);
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	/* Get the command phase address */
828*4882a593Smuzhiyun 	if (curr_cmd->end_cmd_valid == ZYNQ_NAND_CMD_PHASE)
829*4882a593Smuzhiyun 		end_cmd_valid = 1;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	if (curr_cmd->end_cmd == NAND_CMD_NONE)
832*4882a593Smuzhiyun 		end_cmd = 0x0;
833*4882a593Smuzhiyun 	else
834*4882a593Smuzhiyun 		end_cmd = curr_cmd->end_cmd;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	if (command == NAND_CMD_READ0 ||
837*4882a593Smuzhiyun 	    command == NAND_CMD_SEQIN) {
838*4882a593Smuzhiyun 		addr_cycles = chip->onfi_params.addr_cycles &
839*4882a593Smuzhiyun 				ZYNQ_NAND_ROW_ADDR_CYCL_MASK;
840*4882a593Smuzhiyun 		addr_cycles += ((chip->onfi_params.addr_cycles &
841*4882a593Smuzhiyun 				ZYNQ_NAND_COL_ADDR_CYCL_MASK) >> 4);
842*4882a593Smuzhiyun 	} else {
843*4882a593Smuzhiyun 		addr_cycles = curr_cmd->addr_cycles;
844*4882a593Smuzhiyun 	}
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	cmd_phase_addr = (unsigned long)xnand->nand_base	|
847*4882a593Smuzhiyun 			(addr_cycles << ADDR_CYCLES_SHIFT)	|
848*4882a593Smuzhiyun 			(end_cmd_valid << END_CMD_VALID_SHIFT)		|
849*4882a593Smuzhiyun 			(COMMAND_PHASE)					|
850*4882a593Smuzhiyun 			(end_cmd << END_CMD_SHIFT)			|
851*4882a593Smuzhiyun 			(curr_cmd->start_cmd << START_CMD_SHIFT);
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	cmd_addr = (void __iomem *)cmd_phase_addr;
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	/* Get the data phase address */
856*4882a593Smuzhiyun 	end_cmd_valid = 0;
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	data_phase_addr = (unsigned long)xnand->nand_base	|
859*4882a593Smuzhiyun 			(0x0 << CLEAR_CS_SHIFT)				|
860*4882a593Smuzhiyun 			(end_cmd_valid << END_CMD_VALID_SHIFT)		|
861*4882a593Smuzhiyun 			(DATA_PHASE)					|
862*4882a593Smuzhiyun 			(end_cmd << END_CMD_SHIFT)			|
863*4882a593Smuzhiyun 			(0x0 << ECC_LAST_SHIFT);
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	chip->IO_ADDR_R = (void  __iomem *)data_phase_addr;
866*4882a593Smuzhiyun 	chip->IO_ADDR_W = chip->IO_ADDR_R;
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	/* Command phase AXI Read & Write */
869*4882a593Smuzhiyun 	if (column != -1 && page_addr != -1) {
870*4882a593Smuzhiyun 		/* Adjust columns for 16 bit bus width */
871*4882a593Smuzhiyun 		if (chip->options & NAND_BUSWIDTH_16)
872*4882a593Smuzhiyun 			column >>= 1;
873*4882a593Smuzhiyun 		cmd_data = column;
874*4882a593Smuzhiyun 		if (mtd->writesize > ZYNQ_NAND_ECC_SIZE) {
875*4882a593Smuzhiyun 			cmd_data |= page_addr << 16;
876*4882a593Smuzhiyun 			/* Another address cycle for devices > 128MiB */
877*4882a593Smuzhiyun 			if (chip->chipsize > (128 << 20)) {
878*4882a593Smuzhiyun 				writel(cmd_data, cmd_addr);
879*4882a593Smuzhiyun 				cmd_data = (page_addr >> 16);
880*4882a593Smuzhiyun 			}
881*4882a593Smuzhiyun 		} else {
882*4882a593Smuzhiyun 			cmd_data |= page_addr << 8;
883*4882a593Smuzhiyun 		}
884*4882a593Smuzhiyun 	} else if (page_addr != -1)  { /* Erase */
885*4882a593Smuzhiyun 		cmd_data = page_addr;
886*4882a593Smuzhiyun 	} else if (column != -1) { /* Change read/write column, read id etc */
887*4882a593Smuzhiyun 		/* Adjust columns for 16 bit bus width */
888*4882a593Smuzhiyun 		if ((chip->options & NAND_BUSWIDTH_16) &&
889*4882a593Smuzhiyun 		    ((command == NAND_CMD_READ0) ||
890*4882a593Smuzhiyun 		     (command == NAND_CMD_SEQIN) ||
891*4882a593Smuzhiyun 		     (command == NAND_CMD_RNDOUT) ||
892*4882a593Smuzhiyun 		     (command == NAND_CMD_RNDIN)))
893*4882a593Smuzhiyun 			column >>= 1;
894*4882a593Smuzhiyun 		cmd_data = column;
895*4882a593Smuzhiyun 	}
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	writel(cmd_data, cmd_addr);
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	if (curr_cmd->end_cmd_valid) {
900*4882a593Smuzhiyun 		xnand->end_cmd = curr_cmd->end_cmd;
901*4882a593Smuzhiyun 		xnand->end_cmd_pending = 1;
902*4882a593Smuzhiyun 	}
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	ndelay(100);
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 	if ((command == NAND_CMD_READ0) ||
907*4882a593Smuzhiyun 	    (command == NAND_CMD_RESET) ||
908*4882a593Smuzhiyun 	    (command == NAND_CMD_PARAM) ||
909*4882a593Smuzhiyun 	    (command == NAND_CMD_GET_FEATURES))
910*4882a593Smuzhiyun 		/* wait until command is processed */
911*4882a593Smuzhiyun 		nand_wait_ready(mtd);
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun /*
915*4882a593Smuzhiyun  * zynq_nand_read_buf - read chip data into buffer
916*4882a593Smuzhiyun  * @mtd:        MTD device structure
917*4882a593Smuzhiyun  * @buf:        buffer to store date
918*4882a593Smuzhiyun  * @len:        number of bytes to read
919*4882a593Smuzhiyun  */
zynq_nand_read_buf(struct mtd_info * mtd,u8 * buf,int len)920*4882a593Smuzhiyun static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun 	struct nand_chip *chip = mtd->priv;
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 	/* Make sure that buf is 32 bit aligned */
925*4882a593Smuzhiyun 	if (((unsigned long)buf & 0x3) != 0) {
926*4882a593Smuzhiyun 		if (((unsigned long)buf & 0x1) != 0) {
927*4882a593Smuzhiyun 			if (len) {
928*4882a593Smuzhiyun 				*buf = readb(chip->IO_ADDR_R);
929*4882a593Smuzhiyun 				buf += 1;
930*4882a593Smuzhiyun 				len--;
931*4882a593Smuzhiyun 			}
932*4882a593Smuzhiyun 		}
933*4882a593Smuzhiyun 
934*4882a593Smuzhiyun 		if (((unsigned long)buf & 0x3) != 0) {
935*4882a593Smuzhiyun 			if (len >= 2) {
936*4882a593Smuzhiyun 				*(u16 *)buf = readw(chip->IO_ADDR_R);
937*4882a593Smuzhiyun 				buf += 2;
938*4882a593Smuzhiyun 				len -= 2;
939*4882a593Smuzhiyun 			}
940*4882a593Smuzhiyun 		}
941*4882a593Smuzhiyun 	}
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	/* copy aligned data */
944*4882a593Smuzhiyun 	while (len >= 4) {
945*4882a593Smuzhiyun 		*(u32 *)buf = readl(chip->IO_ADDR_R);
946*4882a593Smuzhiyun 		buf += 4;
947*4882a593Smuzhiyun 		len -= 4;
948*4882a593Smuzhiyun 	}
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	/* mop up any remaining bytes */
951*4882a593Smuzhiyun 	if (len) {
952*4882a593Smuzhiyun 		if (len >= 2) {
953*4882a593Smuzhiyun 			*(u16 *)buf = readw(chip->IO_ADDR_R);
954*4882a593Smuzhiyun 			buf += 2;
955*4882a593Smuzhiyun 			len -= 2;
956*4882a593Smuzhiyun 		}
957*4882a593Smuzhiyun 		if (len)
958*4882a593Smuzhiyun 			*buf = readb(chip->IO_ADDR_R);
959*4882a593Smuzhiyun 	}
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun /*
963*4882a593Smuzhiyun  * zynq_nand_write_buf - write buffer to chip
964*4882a593Smuzhiyun  * @mtd:        MTD device structure
965*4882a593Smuzhiyun  * @buf:        data buffer
966*4882a593Smuzhiyun  * @len:        number of bytes to write
967*4882a593Smuzhiyun  */
zynq_nand_write_buf(struct mtd_info * mtd,const u8 * buf,int len)968*4882a593Smuzhiyun static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
969*4882a593Smuzhiyun {
970*4882a593Smuzhiyun 	struct nand_chip *chip = mtd->priv;
971*4882a593Smuzhiyun 	const u32 *nand = chip->IO_ADDR_W;
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 	/* Make sure that buf is 32 bit aligned */
974*4882a593Smuzhiyun 	if (((unsigned long)buf & 0x3) != 0) {
975*4882a593Smuzhiyun 		if (((unsigned long)buf & 0x1) != 0) {
976*4882a593Smuzhiyun 			if (len) {
977*4882a593Smuzhiyun 				writeb(*buf, nand);
978*4882a593Smuzhiyun 				buf += 1;
979*4882a593Smuzhiyun 				len--;
980*4882a593Smuzhiyun 			}
981*4882a593Smuzhiyun 		}
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 		if (((unsigned long)buf & 0x3) != 0) {
984*4882a593Smuzhiyun 			if (len >= 2) {
985*4882a593Smuzhiyun 				writew(*(u16 *)buf, nand);
986*4882a593Smuzhiyun 				buf += 2;
987*4882a593Smuzhiyun 				len -= 2;
988*4882a593Smuzhiyun 			}
989*4882a593Smuzhiyun 		}
990*4882a593Smuzhiyun 	}
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	/* copy aligned data */
993*4882a593Smuzhiyun 	while (len >= 4) {
994*4882a593Smuzhiyun 		writel(*(u32 *)buf, nand);
995*4882a593Smuzhiyun 		buf += 4;
996*4882a593Smuzhiyun 		len -= 4;
997*4882a593Smuzhiyun 	}
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	/* mop up any remaining bytes */
1000*4882a593Smuzhiyun 	if (len) {
1001*4882a593Smuzhiyun 		if (len >= 2) {
1002*4882a593Smuzhiyun 			writew(*(u16 *)buf, nand);
1003*4882a593Smuzhiyun 			buf += 2;
1004*4882a593Smuzhiyun 			len -= 2;
1005*4882a593Smuzhiyun 		}
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 		if (len)
1008*4882a593Smuzhiyun 			writeb(*buf, nand);
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun }
1011*4882a593Smuzhiyun 
1012*4882a593Smuzhiyun /*
1013*4882a593Smuzhiyun  * zynq_nand_device_ready - Check device ready/busy line
1014*4882a593Smuzhiyun  * @mtd:	Pointer to the mtd_info structure
1015*4882a593Smuzhiyun  *
1016*4882a593Smuzhiyun  * returns:	0 on busy or 1 on ready state
1017*4882a593Smuzhiyun  */
zynq_nand_device_ready(struct mtd_info * mtd)1018*4882a593Smuzhiyun static int zynq_nand_device_ready(struct mtd_info *mtd)
1019*4882a593Smuzhiyun {
1020*4882a593Smuzhiyun 	u32 csr_val;
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	csr_val = readl(&zynq_nand_smc_base->csr);
1023*4882a593Smuzhiyun 	/* Check the raw_int_status1 bit */
1024*4882a593Smuzhiyun 	if (csr_val & ZYNQ_MEMC_SR_RAW_INT_ST1) {
1025*4882a593Smuzhiyun 		/* Clear the interrupt condition */
1026*4882a593Smuzhiyun 		writel(ZYNQ_MEMC_SR_INT_ST1, &zynq_nand_smc_base->cfr);
1027*4882a593Smuzhiyun 		return 1;
1028*4882a593Smuzhiyun 	}
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	return 0;
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun 
zynq_nand_check_is_16bit_bw_flash(void)1033*4882a593Smuzhiyun static int zynq_nand_check_is_16bit_bw_flash(void)
1034*4882a593Smuzhiyun {
1035*4882a593Smuzhiyun 	int is_16bit_bw = NAND_BW_UNKNOWN;
1036*4882a593Smuzhiyun 	int mio_num_8bit = 0, mio_num_16bit = 0;
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 	mio_num_8bit = zynq_slcr_get_mio_pin_status("nand8");
1039*4882a593Smuzhiyun 	if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT)
1040*4882a593Smuzhiyun 		is_16bit_bw = NAND_BW_8BIT;
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 	mio_num_16bit = zynq_slcr_get_mio_pin_status("nand16");
1043*4882a593Smuzhiyun 	if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT &&
1044*4882a593Smuzhiyun 	    mio_num_16bit == ZYNQ_NAND_MIO_NUM_NAND_16BIT)
1045*4882a593Smuzhiyun 		is_16bit_bw = NAND_BW_16BIT;
1046*4882a593Smuzhiyun 
1047*4882a593Smuzhiyun 	return is_16bit_bw;
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun 
zynq_nand_init(struct nand_chip * nand_chip,int devnum)1050*4882a593Smuzhiyun static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
1051*4882a593Smuzhiyun {
1052*4882a593Smuzhiyun 	struct zynq_nand_info *xnand;
1053*4882a593Smuzhiyun 	struct mtd_info *mtd;
1054*4882a593Smuzhiyun 	unsigned long ecc_page_size;
1055*4882a593Smuzhiyun 	u8 maf_id, dev_id, i;
1056*4882a593Smuzhiyun 	u8 get_feature[4];
1057*4882a593Smuzhiyun 	u8 set_feature[4] = {ONDIE_ECC_FEATURE_ENABLE, 0x00, 0x00, 0x00};
1058*4882a593Smuzhiyun 	unsigned long ecc_cfg;
1059*4882a593Smuzhiyun 	int ondie_ecc_enabled = 0;
1060*4882a593Smuzhiyun 	int err = -1;
1061*4882a593Smuzhiyun 	int is_16bit_bw;
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	xnand = calloc(1, sizeof(struct zynq_nand_info));
1064*4882a593Smuzhiyun 	if (!xnand) {
1065*4882a593Smuzhiyun 		printf("%s: failed to allocate\n", __func__);
1066*4882a593Smuzhiyun 		goto fail;
1067*4882a593Smuzhiyun 	}
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	xnand->nand_base = (void __iomem *)ZYNQ_NAND_BASEADDR;
1070*4882a593Smuzhiyun 	mtd = nand_to_mtd(nand_chip);
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	nand_chip->priv = xnand;
1073*4882a593Smuzhiyun 	mtd->priv = nand_chip;
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun 	/* Set address of NAND IO lines */
1076*4882a593Smuzhiyun 	nand_chip->IO_ADDR_R = xnand->nand_base;
1077*4882a593Smuzhiyun 	nand_chip->IO_ADDR_W = xnand->nand_base;
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun 	/* Set the driver entry points for MTD */
1080*4882a593Smuzhiyun 	nand_chip->cmdfunc = zynq_nand_cmd_function;
1081*4882a593Smuzhiyun 	nand_chip->dev_ready = zynq_nand_device_ready;
1082*4882a593Smuzhiyun 	nand_chip->select_chip = zynq_nand_select_chip;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	/* If we don't set this delay driver sets 20us by default */
1085*4882a593Smuzhiyun 	nand_chip->chip_delay = 30;
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 	/* Buffer read/write routines */
1088*4882a593Smuzhiyun 	nand_chip->read_buf = zynq_nand_read_buf;
1089*4882a593Smuzhiyun 	nand_chip->write_buf = zynq_nand_write_buf;
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	is_16bit_bw = zynq_nand_check_is_16bit_bw_flash();
1092*4882a593Smuzhiyun 	if (is_16bit_bw == NAND_BW_UNKNOWN) {
1093*4882a593Smuzhiyun 		printf("%s: Unable detect NAND based on MIO settings\n",
1094*4882a593Smuzhiyun 		       __func__);
1095*4882a593Smuzhiyun 		goto fail;
1096*4882a593Smuzhiyun 	}
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 	if (is_16bit_bw == NAND_BW_16BIT)
1099*4882a593Smuzhiyun 		nand_chip->options = NAND_BUSWIDTH_16;
1100*4882a593Smuzhiyun 
1101*4882a593Smuzhiyun 	nand_chip->bbt_options = NAND_BBT_USE_FLASH;
1102*4882a593Smuzhiyun 
1103*4882a593Smuzhiyun 	/* Initialize the NAND flash interface on NAND controller */
1104*4882a593Smuzhiyun 	if (zynq_nand_init_nand_flash(nand_chip->options) < 0) {
1105*4882a593Smuzhiyun 		printf("%s: nand flash init failed\n", __func__);
1106*4882a593Smuzhiyun 		goto fail;
1107*4882a593Smuzhiyun 	}
1108*4882a593Smuzhiyun 
1109*4882a593Smuzhiyun 	/* first scan to find the device and get the page size */
1110*4882a593Smuzhiyun 	if (nand_scan_ident(mtd, 1, NULL)) {
1111*4882a593Smuzhiyun 		printf("%s: nand_scan_ident failed\n", __func__);
1112*4882a593Smuzhiyun 		goto fail;
1113*4882a593Smuzhiyun 	}
1114*4882a593Smuzhiyun 	/* Send the command for reading device ID */
1115*4882a593Smuzhiyun 	nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1116*4882a593Smuzhiyun 	nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	/* Read manufacturer and device IDs */
1119*4882a593Smuzhiyun 	maf_id = nand_chip->read_byte(mtd);
1120*4882a593Smuzhiyun 	dev_id = nand_chip->read_byte(mtd);
1121*4882a593Smuzhiyun 
1122*4882a593Smuzhiyun 	if ((maf_id == 0x2c) && ((dev_id == 0xf1) ||
1123*4882a593Smuzhiyun 				 (dev_id == 0xa1) || (dev_id == 0xb1) ||
1124*4882a593Smuzhiyun 				 (dev_id == 0xaa) || (dev_id == 0xba) ||
1125*4882a593Smuzhiyun 				 (dev_id == 0xda) || (dev_id == 0xca) ||
1126*4882a593Smuzhiyun 				 (dev_id == 0xac) || (dev_id == 0xbc) ||
1127*4882a593Smuzhiyun 				 (dev_id == 0xdc) || (dev_id == 0xcc) ||
1128*4882a593Smuzhiyun 				 (dev_id == 0xa3) || (dev_id == 0xb3) ||
1129*4882a593Smuzhiyun 				 (dev_id == 0xd3) || (dev_id == 0xc3))) {
1130*4882a593Smuzhiyun 		nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
1131*4882a593Smuzhiyun 						ONDIE_ECC_FEATURE_ADDR, -1);
1132*4882a593Smuzhiyun 		for (i = 0; i < 4; i++)
1133*4882a593Smuzhiyun 			writeb(set_feature[i], nand_chip->IO_ADDR_W);
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 		/* Wait for 1us after writing data with SET_FEATURES command */
1136*4882a593Smuzhiyun 		ndelay(1000);
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 		nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
1139*4882a593Smuzhiyun 						ONDIE_ECC_FEATURE_ADDR, -1);
1140*4882a593Smuzhiyun 		nand_chip->read_buf(mtd, get_feature, 4);
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 		if (get_feature[0] & ONDIE_ECC_FEATURE_ENABLE) {
1143*4882a593Smuzhiyun 			debug("%s: OnDie ECC flash\n", __func__);
1144*4882a593Smuzhiyun 			ondie_ecc_enabled = 1;
1145*4882a593Smuzhiyun 		} else {
1146*4882a593Smuzhiyun 			printf("%s: Unable to detect OnDie ECC\n", __func__);
1147*4882a593Smuzhiyun 		}
1148*4882a593Smuzhiyun 	}
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun 	if (ondie_ecc_enabled) {
1151*4882a593Smuzhiyun 		/* Bypass the controller ECC block */
1152*4882a593Smuzhiyun 		ecc_cfg = readl(&zynq_nand_smc_base->emcr);
1153*4882a593Smuzhiyun 		ecc_cfg &= ~ZYNQ_MEMC_NAND_ECC_MODE_MASK;
1154*4882a593Smuzhiyun 		writel(ecc_cfg, &zynq_nand_smc_base->emcr);
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 		/* The software ECC routines won't work
1157*4882a593Smuzhiyun 		 * with the SMC controller
1158*4882a593Smuzhiyun 		 */
1159*4882a593Smuzhiyun 		nand_chip->ecc.mode = NAND_ECC_HW;
1160*4882a593Smuzhiyun 		nand_chip->ecc.strength = 1;
1161*4882a593Smuzhiyun 		nand_chip->ecc.read_page = zynq_nand_read_page_raw_nooob;
1162*4882a593Smuzhiyun 		nand_chip->ecc.read_subpage = zynq_nand_read_subpage_raw;
1163*4882a593Smuzhiyun 		nand_chip->ecc.write_page = zynq_nand_write_page_raw;
1164*4882a593Smuzhiyun 		nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
1165*4882a593Smuzhiyun 		nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
1166*4882a593Smuzhiyun 		nand_chip->ecc.read_oob = zynq_nand_read_oob;
1167*4882a593Smuzhiyun 		nand_chip->ecc.write_oob = zynq_nand_write_oob;
1168*4882a593Smuzhiyun 		nand_chip->ecc.size = mtd->writesize;
1169*4882a593Smuzhiyun 		nand_chip->ecc.bytes = 0;
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 		/* NAND with on-die ECC supports subpage reads */
1172*4882a593Smuzhiyun 		nand_chip->options |= NAND_SUBPAGE_READ;
1173*4882a593Smuzhiyun 
1174*4882a593Smuzhiyun 		/* On-Die ECC spare bytes offset 8 is used for ECC codes */
1175*4882a593Smuzhiyun 		if (ondie_ecc_enabled) {
1176*4882a593Smuzhiyun 			nand_chip->ecc.layout = &ondie_nand_oob_64;
1177*4882a593Smuzhiyun 			/* Use the BBT pattern descriptors */
1178*4882a593Smuzhiyun 			nand_chip->bbt_td = &bbt_main_descr;
1179*4882a593Smuzhiyun 			nand_chip->bbt_md = &bbt_mirror_descr;
1180*4882a593Smuzhiyun 		}
1181*4882a593Smuzhiyun 	} else {
1182*4882a593Smuzhiyun 		/* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
1183*4882a593Smuzhiyun 		nand_chip->ecc.mode = NAND_ECC_HW;
1184*4882a593Smuzhiyun 		nand_chip->ecc.strength = 1;
1185*4882a593Smuzhiyun 		nand_chip->ecc.size = ZYNQ_NAND_ECC_SIZE;
1186*4882a593Smuzhiyun 		nand_chip->ecc.bytes = 3;
1187*4882a593Smuzhiyun 		nand_chip->ecc.calculate = zynq_nand_calculate_hwecc;
1188*4882a593Smuzhiyun 		nand_chip->ecc.correct = zynq_nand_correct_data;
1189*4882a593Smuzhiyun 		nand_chip->ecc.hwctl = NULL;
1190*4882a593Smuzhiyun 		nand_chip->ecc.read_page = zynq_nand_read_page_hwecc;
1191*4882a593Smuzhiyun 		nand_chip->ecc.write_page = zynq_nand_write_page_hwecc;
1192*4882a593Smuzhiyun 		nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
1193*4882a593Smuzhiyun 		nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
1194*4882a593Smuzhiyun 		nand_chip->ecc.read_oob = zynq_nand_read_oob;
1195*4882a593Smuzhiyun 		nand_chip->ecc.write_oob = zynq_nand_write_oob;
1196*4882a593Smuzhiyun 
1197*4882a593Smuzhiyun 		switch (mtd->writesize) {
1198*4882a593Smuzhiyun 		case 512:
1199*4882a593Smuzhiyun 			ecc_page_size = 0x1;
1200*4882a593Smuzhiyun 			/* Set the ECC memory config register */
1201*4882a593Smuzhiyun 			writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
1202*4882a593Smuzhiyun 			       &zynq_nand_smc_base->emcr);
1203*4882a593Smuzhiyun 			break;
1204*4882a593Smuzhiyun 		case 1024:
1205*4882a593Smuzhiyun 			ecc_page_size = 0x2;
1206*4882a593Smuzhiyun 			/* Set the ECC memory config register */
1207*4882a593Smuzhiyun 			writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
1208*4882a593Smuzhiyun 			       &zynq_nand_smc_base->emcr);
1209*4882a593Smuzhiyun 			break;
1210*4882a593Smuzhiyun 		case 2048:
1211*4882a593Smuzhiyun 			ecc_page_size = 0x3;
1212*4882a593Smuzhiyun 			/* Set the ECC memory config register */
1213*4882a593Smuzhiyun 			writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
1214*4882a593Smuzhiyun 			       &zynq_nand_smc_base->emcr);
1215*4882a593Smuzhiyun 			break;
1216*4882a593Smuzhiyun 		default:
1217*4882a593Smuzhiyun 			nand_chip->ecc.mode = NAND_ECC_SOFT;
1218*4882a593Smuzhiyun 			nand_chip->ecc.calculate = nand_calculate_ecc;
1219*4882a593Smuzhiyun 			nand_chip->ecc.correct = nand_correct_data;
1220*4882a593Smuzhiyun 			nand_chip->ecc.read_page = zynq_nand_read_page_swecc;
1221*4882a593Smuzhiyun 			nand_chip->ecc.write_page = zynq_nand_write_page_swecc;
1222*4882a593Smuzhiyun 			nand_chip->ecc.size = 256;
1223*4882a593Smuzhiyun 			break;
1224*4882a593Smuzhiyun 		}
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 		if (mtd->oobsize == 16)
1227*4882a593Smuzhiyun 			nand_chip->ecc.layout = &nand_oob_16;
1228*4882a593Smuzhiyun 		else if (mtd->oobsize == 64)
1229*4882a593Smuzhiyun 			nand_chip->ecc.layout = &nand_oob_64;
1230*4882a593Smuzhiyun 		else
1231*4882a593Smuzhiyun 			printf("%s: No oob layout found\n", __func__);
1232*4882a593Smuzhiyun 	}
1233*4882a593Smuzhiyun 
1234*4882a593Smuzhiyun 	/* Second phase scan */
1235*4882a593Smuzhiyun 	if (nand_scan_tail(mtd)) {
1236*4882a593Smuzhiyun 		printf("%s: nand_scan_tail failed\n", __func__);
1237*4882a593Smuzhiyun 		goto fail;
1238*4882a593Smuzhiyun 	}
1239*4882a593Smuzhiyun 	if (nand_register(devnum, mtd))
1240*4882a593Smuzhiyun 		goto fail;
1241*4882a593Smuzhiyun 	return 0;
1242*4882a593Smuzhiyun fail:
1243*4882a593Smuzhiyun 	free(xnand);
1244*4882a593Smuzhiyun 	return err;
1245*4882a593Smuzhiyun }
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
1248*4882a593Smuzhiyun 
board_nand_init(void)1249*4882a593Smuzhiyun void board_nand_init(void)
1250*4882a593Smuzhiyun {
1251*4882a593Smuzhiyun 	struct nand_chip *nand = &nand_chip[0];
1252*4882a593Smuzhiyun 
1253*4882a593Smuzhiyun 	if (zynq_nand_init(nand, 0))
1254*4882a593Smuzhiyun 		puts("ZYNQ NAND init failed\n");
1255*4882a593Smuzhiyun }
1256