]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/synopsys/axs101/nand.c
axs101: flush DMA buffer descriptors before DMA transactons starts
[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)    writel(v, CONFIG_SYS_NAND_BASE + r)
66 #define NAND_REG_READ(r)        readl(CONFIG_SYS_NAND_BASE + r)
67
68 static struct nand_bd *bd;      /* DMA buffer descriptors       */
69
70 /**
71  * axs101_nand_write_buf -  write buffer to chip
72  * @mtd:        MTD device structure
73  * @buf:        data buffer
74  * @len:        number of bytes to write
75  */
76 static uint32_t nand_flag_is_set(uint32_t flag)
77 {
78         uint32_t reg = NAND_REG_READ(INT_STATUS);
79
80         if (reg & (1 << NAND_ISR_CMDERROR))
81                 return 0;
82
83         if (reg & (1 << flag)) {
84                 NAND_REG_WRITE(INT_CLR_STATUS, 1 << flag);
85                 return 1;
86         }
87
88         return 0;
89 }
90
91 /**
92  * axs101_nand_write_buf -  write buffer to chip
93  * @mtd:        MTD device structure
94  * @buf:        data buffer
95  * @len:        number of bytes to write
96  */
97 static void axs101_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
98                                    int len)
99 {
100         struct bounce_buffer bbstate;
101
102         bounce_buffer_start(&bbstate, (void *)buf, len, GEN_BB_READ);
103
104         /* Setup buffer descriptor */
105         writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
106         writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
107         writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
108         writel(0, &bd->buffer_ptr1);
109
110         /* Flush modified buffer descriptor */
111         flush_dcache_range((unsigned long)bd,
112                            (unsigned long)bd + sizeof(struct nand_bd));
113
114         /* Issue "write" command */
115         NAND_REG_WRITE(AC_FIFO, B_CT_WRITE | B_WFR | B_IWC | B_LC | (len-1));
116
117         /* Wait for NAND command and DMA to complete */
118         while (!nand_flag_is_set(NAND_ISR_CMDDONE))
119                 ;
120         while (!nand_flag_is_set(NAND_ISR_TXDMACOMPLETE))
121                 ;
122
123         bounce_buffer_stop(&bbstate);
124 }
125
126 /**
127  * axs101_nand_read_buf -  read chip data into buffer
128  * @mtd:        MTD device structure
129  * @buf:        buffer to store data
130  * @len:        number of bytes to read
131  */
132 static void axs101_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
133 {
134         struct bounce_buffer bbstate;
135
136         bounce_buffer_start(&bbstate, buf, len, GEN_BB_WRITE);
137
138         /* Setup buffer descriptor */
139         writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
140         writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
141         writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
142         writel(0, &bd->buffer_ptr1);
143
144         /* Flush modified buffer descriptor */
145         flush_dcache_range((unsigned long)bd,
146                            (unsigned long)bd + sizeof(struct nand_bd));
147
148         /* Issue "read" command */
149         NAND_REG_WRITE(AC_FIFO, B_CT_READ | B_WFR | B_IWC | B_LC | (len - 1));
150
151         /* Wait for NAND command and DMA to complete */
152         while (!nand_flag_is_set(NAND_ISR_CMDDONE))
153                 ;
154         while (!nand_flag_is_set(NAND_ISR_RXDMACOMPLETE))
155                 ;
156
157         bounce_buffer_stop(&bbstate);
158 }
159
160 /**
161  * axs101_nand_read_byte -  read one byte from the chip
162  * @mtd:        MTD device structure
163  */
164 static u_char axs101_nand_read_byte(struct mtd_info *mtd)
165 {
166         u8 byte;
167
168         axs101_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
169         return byte;
170 }
171
172 /**
173  * axs101_nand_read_word -  read one word from the chip
174  * @mtd:        MTD device structure
175  */
176 static u16 axs101_nand_read_word(struct mtd_info *mtd)
177 {
178         u16 word;
179
180         axs101_nand_read_buf(mtd, (uchar *)&word, sizeof(word));
181         return word;
182 }
183
184 /**
185  * axs101_nand_hwcontrol - NAND control functions wrapper.
186  * @mtd:        MTD device structure
187  * @cmd:        Command
188  */
189 static void axs101_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd,
190                                    unsigned int ctrl)
191 {
192         if (cmd == NAND_CMD_NONE)
193                 return;
194
195         cmd = cmd & 0xff;
196
197         switch (ctrl & (NAND_ALE | NAND_CLE)) {
198         /* Address */
199         case NAND_ALE:
200                 cmd |= B_CT_ADDRESS;
201                 break;
202
203         /* Command */
204         case NAND_CLE:
205                 cmd |= B_CT_COMMAND | B_WFR;
206
207                 break;
208
209         default:
210                 debug("%s: unknown ctrl %#x\n", __func__, ctrl);
211         }
212
213         NAND_REG_WRITE(AC_FIFO, cmd | B_LC);
214         while (!nand_flag_is_set(NAND_ISR_CMDDONE))
215                 ;
216 }
217
218 int board_nand_init(struct nand_chip *nand)
219 {
220         bd = (struct nand_bd *)memalign(ARCH_DMA_MINALIGN,
221                                         sizeof(struct nand_bd));
222
223         /* Set buffer descriptor address in IDMAC */
224         NAND_REG_WRITE(IDMAC_BDADDR, bd);
225
226         nand->ecc.mode = NAND_ECC_SOFT;
227         nand->cmd_ctrl = axs101_nand_hwcontrol;
228         nand->read_byte = axs101_nand_read_byte;
229         nand->read_word = axs101_nand_read_word;
230         nand->write_buf = axs101_nand_write_buf;
231         nand->read_buf = axs101_nand_read_buf;
232
233         return 0;
234 }