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