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