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