xref: /rk3399_rockchip-uboot/board/synopsys/axs10x/nand.c (revision 65fcba1251dcb1fc2c48966406145a69fee3a817)
1*65fcba12SAlexey Brodkin /*
2*65fcba12SAlexey Brodkin  * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
3*65fcba12SAlexey Brodkin  *
4*65fcba12SAlexey Brodkin  * SPDX-License-Identifier:	GPL-2.0+
5*65fcba12SAlexey Brodkin  */
6*65fcba12SAlexey Brodkin 
7*65fcba12SAlexey Brodkin #include <bouncebuf.h>
8*65fcba12SAlexey Brodkin #include <common.h>
9*65fcba12SAlexey Brodkin #include <malloc.h>
10*65fcba12SAlexey Brodkin #include <nand.h>
11*65fcba12SAlexey Brodkin #include <asm/io.h>
12*65fcba12SAlexey Brodkin #include "axs10x.h"
13*65fcba12SAlexey Brodkin 
14*65fcba12SAlexey Brodkin DECLARE_GLOBAL_DATA_PTR;
15*65fcba12SAlexey Brodkin 
16*65fcba12SAlexey Brodkin #define BUS_WIDTH	8		/* AXI data bus width in bytes	*/
17*65fcba12SAlexey Brodkin 
18*65fcba12SAlexey Brodkin /* DMA buffer descriptor bits & masks */
19*65fcba12SAlexey Brodkin #define BD_STAT_OWN			(1 << 31)
20*65fcba12SAlexey Brodkin #define BD_STAT_BD_FIRST		(1 << 3)
21*65fcba12SAlexey Brodkin #define BD_STAT_BD_LAST			(1 << 2)
22*65fcba12SAlexey Brodkin #define BD_SIZES_BUFFER1_MASK		0xfff
23*65fcba12SAlexey Brodkin 
24*65fcba12SAlexey Brodkin #define BD_STAT_BD_COMPLETE	(BD_STAT_BD_FIRST | BD_STAT_BD_LAST)
25*65fcba12SAlexey Brodkin 
26*65fcba12SAlexey Brodkin /* Controller command flags */
27*65fcba12SAlexey Brodkin #define B_WFR		(1 << 19)	/* 1b - Wait for ready		*/
28*65fcba12SAlexey Brodkin #define B_LC		(1 << 18)	/* 1b - Last cycle		*/
29*65fcba12SAlexey Brodkin #define B_IWC		(1 << 13)	/* 1b - Interrupt when complete	*/
30*65fcba12SAlexey Brodkin 
31*65fcba12SAlexey Brodkin /* NAND cycle types */
32*65fcba12SAlexey Brodkin #define B_CT_ADDRESS	(0x0 << 16)	/* Address operation		*/
33*65fcba12SAlexey Brodkin #define B_CT_COMMAND	(0x1 << 16)	/* Command operation		*/
34*65fcba12SAlexey Brodkin #define B_CT_WRITE	(0x2 << 16)	/* Write operation		*/
35*65fcba12SAlexey Brodkin #define B_CT_READ	(0x3 << 16)	/* Write operation		*/
36*65fcba12SAlexey Brodkin 
37*65fcba12SAlexey Brodkin enum nand_isr_t {
38*65fcba12SAlexey Brodkin 	NAND_ISR_DATAREQUIRED = 0,
39*65fcba12SAlexey Brodkin 	NAND_ISR_TXUNDERFLOW,
40*65fcba12SAlexey Brodkin 	NAND_ISR_TXOVERFLOW,
41*65fcba12SAlexey Brodkin 	NAND_ISR_DATAAVAILABLE,
42*65fcba12SAlexey Brodkin 	NAND_ISR_RXUNDERFLOW,
43*65fcba12SAlexey Brodkin 	NAND_ISR_RXOVERFLOW,
44*65fcba12SAlexey Brodkin 	NAND_ISR_TXDMACOMPLETE,
45*65fcba12SAlexey Brodkin 	NAND_ISR_RXDMACOMPLETE,
46*65fcba12SAlexey Brodkin 	NAND_ISR_DESCRIPTORUNAVAILABLE,
47*65fcba12SAlexey Brodkin 	NAND_ISR_CMDDONE,
48*65fcba12SAlexey Brodkin 	NAND_ISR_CMDAVAILABLE,
49*65fcba12SAlexey Brodkin 	NAND_ISR_CMDERROR,
50*65fcba12SAlexey Brodkin 	NAND_ISR_DATATRANSFEROVER,
51*65fcba12SAlexey Brodkin 	NAND_ISR_NONE
52*65fcba12SAlexey Brodkin };
53*65fcba12SAlexey Brodkin 
54*65fcba12SAlexey Brodkin enum nand_regs_t {
55*65fcba12SAlexey Brodkin 	AC_FIFO = 0,		/* address and command fifo */
56*65fcba12SAlexey Brodkin 	IDMAC_BDADDR = 0x18,	/* idmac descriptor list base address */
57*65fcba12SAlexey Brodkin 	INT_STATUS = 0x118,	/* interrupt status register */
58*65fcba12SAlexey Brodkin 	INT_CLR_STATUS = 0x120,	/* interrupt clear status register */
59*65fcba12SAlexey Brodkin };
60*65fcba12SAlexey Brodkin 
61*65fcba12SAlexey Brodkin struct nand_bd {
62*65fcba12SAlexey Brodkin 	uint32_t status;	/* DES0 */
63*65fcba12SAlexey Brodkin 	uint32_t sizes;		/* DES1 */
64*65fcba12SAlexey Brodkin 	uint32_t buffer_ptr0;	/* DES2 */
65*65fcba12SAlexey Brodkin 	uint32_t buffer_ptr1;	/* DES3 */
66*65fcba12SAlexey Brodkin };
67*65fcba12SAlexey Brodkin 
68*65fcba12SAlexey Brodkin #define NAND_REG_WRITE(r, v)	\
69*65fcba12SAlexey Brodkin 	writel(v, (volatile void __iomem *)(CONFIG_SYS_NAND_BASE + r))
70*65fcba12SAlexey Brodkin #define NAND_REG_READ(r)		\
71*65fcba12SAlexey Brodkin 	readl((const volatile void __iomem *)(CONFIG_SYS_NAND_BASE + r))
72*65fcba12SAlexey Brodkin 
73*65fcba12SAlexey Brodkin static struct nand_bd *bd;	/* DMA buffer descriptors	*/
74*65fcba12SAlexey Brodkin 
75*65fcba12SAlexey Brodkin /**
76*65fcba12SAlexey Brodkin  * axs101_nand_write_buf -  write buffer to chip
77*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
78*65fcba12SAlexey Brodkin  * @buf:	data buffer
79*65fcba12SAlexey Brodkin  * @len:	number of bytes to write
80*65fcba12SAlexey Brodkin  */
nand_flag_is_set(uint32_t flag)81*65fcba12SAlexey Brodkin static uint32_t nand_flag_is_set(uint32_t flag)
82*65fcba12SAlexey Brodkin {
83*65fcba12SAlexey Brodkin 	uint32_t reg = NAND_REG_READ(INT_STATUS);
84*65fcba12SAlexey Brodkin 
85*65fcba12SAlexey Brodkin 	if (reg & (1 << NAND_ISR_CMDERROR))
86*65fcba12SAlexey Brodkin 		return 0;
87*65fcba12SAlexey Brodkin 
88*65fcba12SAlexey Brodkin 	if (reg & (1 << flag)) {
89*65fcba12SAlexey Brodkin 		NAND_REG_WRITE(INT_CLR_STATUS, 1 << flag);
90*65fcba12SAlexey Brodkin 		return 1;
91*65fcba12SAlexey Brodkin 	}
92*65fcba12SAlexey Brodkin 
93*65fcba12SAlexey Brodkin 	return 0;
94*65fcba12SAlexey Brodkin }
95*65fcba12SAlexey Brodkin 
96*65fcba12SAlexey Brodkin /**
97*65fcba12SAlexey Brodkin  * axs101_nand_write_buf -  write buffer to chip
98*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
99*65fcba12SAlexey Brodkin  * @buf:	data buffer
100*65fcba12SAlexey Brodkin  * @len:	number of bytes to write
101*65fcba12SAlexey Brodkin  */
axs101_nand_write_buf(struct mtd_info * mtd,const u_char * buf,int len)102*65fcba12SAlexey Brodkin static void axs101_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
103*65fcba12SAlexey Brodkin 				   int len)
104*65fcba12SAlexey Brodkin {
105*65fcba12SAlexey Brodkin 	struct bounce_buffer bbstate;
106*65fcba12SAlexey Brodkin 
107*65fcba12SAlexey Brodkin 	bounce_buffer_start(&bbstate, (void *)buf, len, GEN_BB_READ);
108*65fcba12SAlexey Brodkin 
109*65fcba12SAlexey Brodkin 	/* Setup buffer descriptor */
110*65fcba12SAlexey Brodkin 	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
111*65fcba12SAlexey Brodkin 	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
112*65fcba12SAlexey Brodkin 	writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
113*65fcba12SAlexey Brodkin 	writel(0, &bd->buffer_ptr1);
114*65fcba12SAlexey Brodkin 
115*65fcba12SAlexey Brodkin 	/* Flush modified buffer descriptor */
116*65fcba12SAlexey Brodkin 	flush_dcache_range((unsigned long)bd,
117*65fcba12SAlexey Brodkin 			   (unsigned long)bd + sizeof(struct nand_bd));
118*65fcba12SAlexey Brodkin 
119*65fcba12SAlexey Brodkin 	/* Issue "write" command */
120*65fcba12SAlexey Brodkin 	NAND_REG_WRITE(AC_FIFO, B_CT_WRITE | B_WFR | B_IWC | B_LC | (len-1));
121*65fcba12SAlexey Brodkin 
122*65fcba12SAlexey Brodkin 	/* Wait for NAND command and DMA to complete */
123*65fcba12SAlexey Brodkin 	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
124*65fcba12SAlexey Brodkin 		;
125*65fcba12SAlexey Brodkin 	while (!nand_flag_is_set(NAND_ISR_TXDMACOMPLETE))
126*65fcba12SAlexey Brodkin 		;
127*65fcba12SAlexey Brodkin 
128*65fcba12SAlexey Brodkin 	bounce_buffer_stop(&bbstate);
129*65fcba12SAlexey Brodkin }
130*65fcba12SAlexey Brodkin 
131*65fcba12SAlexey Brodkin /**
132*65fcba12SAlexey Brodkin  * axs101_nand_read_buf -  read chip data into buffer
133*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
134*65fcba12SAlexey Brodkin  * @buf:	buffer to store data
135*65fcba12SAlexey Brodkin  * @len:	number of bytes to read
136*65fcba12SAlexey Brodkin  */
axs101_nand_read_buf(struct mtd_info * mtd,u_char * buf,int len)137*65fcba12SAlexey Brodkin static void axs101_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
138*65fcba12SAlexey Brodkin {
139*65fcba12SAlexey Brodkin 	struct bounce_buffer bbstate;
140*65fcba12SAlexey Brodkin 
141*65fcba12SAlexey Brodkin 	bounce_buffer_start(&bbstate, buf, len, GEN_BB_WRITE);
142*65fcba12SAlexey Brodkin 
143*65fcba12SAlexey Brodkin 	/* Setup buffer descriptor */
144*65fcba12SAlexey Brodkin 	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
145*65fcba12SAlexey Brodkin 	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
146*65fcba12SAlexey Brodkin 	writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
147*65fcba12SAlexey Brodkin 	writel(0, &bd->buffer_ptr1);
148*65fcba12SAlexey Brodkin 
149*65fcba12SAlexey Brodkin 	/* Flush modified buffer descriptor */
150*65fcba12SAlexey Brodkin 	flush_dcache_range((unsigned long)bd,
151*65fcba12SAlexey Brodkin 			   (unsigned long)bd + sizeof(struct nand_bd));
152*65fcba12SAlexey Brodkin 
153*65fcba12SAlexey Brodkin 	/* Issue "read" command */
154*65fcba12SAlexey Brodkin 	NAND_REG_WRITE(AC_FIFO, B_CT_READ | B_WFR | B_IWC | B_LC | (len - 1));
155*65fcba12SAlexey Brodkin 
156*65fcba12SAlexey Brodkin 	/* Wait for NAND command and DMA to complete */
157*65fcba12SAlexey Brodkin 	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
158*65fcba12SAlexey Brodkin 		;
159*65fcba12SAlexey Brodkin 	while (!nand_flag_is_set(NAND_ISR_RXDMACOMPLETE))
160*65fcba12SAlexey Brodkin 		;
161*65fcba12SAlexey Brodkin 
162*65fcba12SAlexey Brodkin 	bounce_buffer_stop(&bbstate);
163*65fcba12SAlexey Brodkin }
164*65fcba12SAlexey Brodkin 
165*65fcba12SAlexey Brodkin /**
166*65fcba12SAlexey Brodkin  * axs101_nand_read_byte -  read one byte from the chip
167*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
168*65fcba12SAlexey Brodkin  */
axs101_nand_read_byte(struct mtd_info * mtd)169*65fcba12SAlexey Brodkin static u_char axs101_nand_read_byte(struct mtd_info *mtd)
170*65fcba12SAlexey Brodkin {
171*65fcba12SAlexey Brodkin 	u8 byte;
172*65fcba12SAlexey Brodkin 
173*65fcba12SAlexey Brodkin 	axs101_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
174*65fcba12SAlexey Brodkin 	return byte;
175*65fcba12SAlexey Brodkin }
176*65fcba12SAlexey Brodkin 
177*65fcba12SAlexey Brodkin /**
178*65fcba12SAlexey Brodkin  * axs101_nand_read_word -  read one word from the chip
179*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
180*65fcba12SAlexey Brodkin  */
axs101_nand_read_word(struct mtd_info * mtd)181*65fcba12SAlexey Brodkin static u16 axs101_nand_read_word(struct mtd_info *mtd)
182*65fcba12SAlexey Brodkin {
183*65fcba12SAlexey Brodkin 	u16 word;
184*65fcba12SAlexey Brodkin 
185*65fcba12SAlexey Brodkin 	axs101_nand_read_buf(mtd, (uchar *)&word, sizeof(word));
186*65fcba12SAlexey Brodkin 	return word;
187*65fcba12SAlexey Brodkin }
188*65fcba12SAlexey Brodkin 
189*65fcba12SAlexey Brodkin /**
190*65fcba12SAlexey Brodkin  * axs101_nand_hwcontrol - NAND control functions wrapper.
191*65fcba12SAlexey Brodkin  * @mtd:	MTD device structure
192*65fcba12SAlexey Brodkin  * @cmd:	Command
193*65fcba12SAlexey Brodkin  */
axs101_nand_hwcontrol(struct mtd_info * mtdinfo,int cmd,unsigned int ctrl)194*65fcba12SAlexey Brodkin static void axs101_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd,
195*65fcba12SAlexey Brodkin 				   unsigned int ctrl)
196*65fcba12SAlexey Brodkin {
197*65fcba12SAlexey Brodkin 	if (cmd == NAND_CMD_NONE)
198*65fcba12SAlexey Brodkin 		return;
199*65fcba12SAlexey Brodkin 
200*65fcba12SAlexey Brodkin 	cmd = cmd & 0xff;
201*65fcba12SAlexey Brodkin 
202*65fcba12SAlexey Brodkin 	switch (ctrl & (NAND_ALE | NAND_CLE)) {
203*65fcba12SAlexey Brodkin 	/* Address */
204*65fcba12SAlexey Brodkin 	case NAND_ALE:
205*65fcba12SAlexey Brodkin 		cmd |= B_CT_ADDRESS;
206*65fcba12SAlexey Brodkin 		break;
207*65fcba12SAlexey Brodkin 
208*65fcba12SAlexey Brodkin 	/* Command */
209*65fcba12SAlexey Brodkin 	case NAND_CLE:
210*65fcba12SAlexey Brodkin 		cmd |= B_CT_COMMAND | B_WFR;
211*65fcba12SAlexey Brodkin 
212*65fcba12SAlexey Brodkin 		break;
213*65fcba12SAlexey Brodkin 
214*65fcba12SAlexey Brodkin 	default:
215*65fcba12SAlexey Brodkin 		debug("%s: unknown ctrl %#x\n", __func__, ctrl);
216*65fcba12SAlexey Brodkin 	}
217*65fcba12SAlexey Brodkin 
218*65fcba12SAlexey Brodkin 	NAND_REG_WRITE(AC_FIFO, cmd | B_LC);
219*65fcba12SAlexey Brodkin 	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
220*65fcba12SAlexey Brodkin 		;
221*65fcba12SAlexey Brodkin }
222*65fcba12SAlexey Brodkin 
board_nand_init(struct nand_chip * nand)223*65fcba12SAlexey Brodkin int board_nand_init(struct nand_chip *nand)
224*65fcba12SAlexey Brodkin {
225*65fcba12SAlexey Brodkin 	bd = (struct nand_bd *)memalign(ARCH_DMA_MINALIGN,
226*65fcba12SAlexey Brodkin 					sizeof(struct nand_bd));
227*65fcba12SAlexey Brodkin 
228*65fcba12SAlexey Brodkin 	/* Set buffer descriptor address in IDMAC */
229*65fcba12SAlexey Brodkin 	NAND_REG_WRITE(IDMAC_BDADDR, bd);
230*65fcba12SAlexey Brodkin 
231*65fcba12SAlexey Brodkin 	nand->ecc.mode = NAND_ECC_SOFT;
232*65fcba12SAlexey Brodkin 	nand->cmd_ctrl = axs101_nand_hwcontrol;
233*65fcba12SAlexey Brodkin 	nand->read_byte = axs101_nand_read_byte;
234*65fcba12SAlexey Brodkin 	nand->read_word = axs101_nand_read_word;
235*65fcba12SAlexey Brodkin 	nand->write_buf = axs101_nand_write_buf;
236*65fcba12SAlexey Brodkin 	nand->read_buf = axs101_nand_read_buf;
237*65fcba12SAlexey Brodkin 
238*65fcba12SAlexey Brodkin 	/* MBv3 has NAND IC with 16-bit data bus */
239*65fcba12SAlexey Brodkin 	if (gd->board_type == AXS_MB_V3)
240*65fcba12SAlexey Brodkin 		nand->options |= NAND_BUSWIDTH_16;
241*65fcba12SAlexey Brodkin 
242*65fcba12SAlexey Brodkin 	return 0;
243*65fcba12SAlexey Brodkin }
244