]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/nand/davinci_nand.c
9e7b9dd9b155b0770585f76d08b6862ca41ede5c
[karo-tx-uboot.git] / drivers / mtd / nand / davinci_nand.c
1 /*
2  * NAND driver for TI DaVinci based boards.
3  *
4  * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
5  *
6  * Based on Linux DaVinci NAND driver by TI. Original copyright follows:
7  */
8
9 /*
10  *
11  * linux/drivers/mtd/nand/nand_davinci.c
12  *
13  * NAND Flash Driver
14  *
15  * Copyright (C) 2006 Texas Instruments.
16  *
17  * ----------------------------------------------------------------------------
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with this program; if not, write to the Free Software
31  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32  * ----------------------------------------------------------------------------
33  *
34  *  Overview:
35  *   This is a device driver for the NAND flash device found on the
36  *   DaVinci board which utilizes the Samsung k9k2g08 part.
37  *
38  Modifications:
39  ver. 1.0: Feb 2005, Vinod/Sudhakar
40  -
41  *
42  */
43
44 #include <common.h>
45 #include <asm/io.h>
46 #include <nand.h>
47 #include <asm/arch/nand_defs.h>
48 #include <asm/arch/emif_defs.h>
49
50 extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE];
51
52 static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
53
54 static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
55 {
56         struct          nand_chip *this = mtd->priv;
57         u_int32_t       IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
58
59         IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
60
61         if (ctrl & NAND_CTRL_CHANGE) {
62                 if ( ctrl & NAND_CLE )
63                         IO_ADDR_W |= MASK_CLE;
64                 if ( ctrl & NAND_ALE )
65                         IO_ADDR_W |= MASK_ALE;
66                 this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
67         }
68
69         if (cmd != NAND_CMD_NONE)
70                 writeb(cmd, this->IO_ADDR_W);
71 }
72
73 /* Set WP on deselect, write enable on select */
74 static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
75 {
76 #define GPIO_SET_DATA01 0x01c67018
77 #define GPIO_CLR_DATA01 0x01c6701c
78 #define GPIO_NAND_WP    (1 << 4)
79 #ifdef SONATA_BOARD_GPIOWP
80         if (chip < 0) {
81                 REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP;
82         } else {
83                 REG(GPIO_SET_DATA01) |= GPIO_NAND_WP;
84         }
85 #endif
86 }
87
88 #ifdef CONFIG_SYS_NAND_HW_ECC
89
90 static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
91 {
92         int             dummy;
93
94         dummy = emif_regs->NANDF1ECC;
95
96         /* FIXME:  only chipselect 0 is supported for now */
97         emif_regs->NANDFCR |= 1 << 8;
98 }
99
100 static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
101 {
102         u_int32_t       ecc = 0;
103
104         if (region == 1)
105                 ecc = emif_regs->NANDF1ECC;
106         else if (region == 2)
107                 ecc = emif_regs->NANDF2ECC;
108         else if (region == 3)
109                 ecc = emif_regs->NANDF3ECC;
110         else if (region == 4)
111                 ecc = emif_regs->NANDF4ECC;
112
113         return(ecc);
114 }
115
116 static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
117 {
118         u_int32_t               tmp;
119         const int region = 1;
120
121         tmp = nand_davinci_readecc(mtd, region);
122
123         /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
124          * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
125         tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
126
127         /* Invert so that erased block ECC is correct */
128         tmp = ~tmp;
129
130         *ecc_code++ = tmp;
131         *ecc_code++ = tmp >>  8;
132         *ecc_code++ = tmp >> 16;
133
134         /* NOTE:  the above code matches mainline Linux:
135          *      .PQR.stu ==> ~PQRstu
136          *
137          * MontaVista/TI kernels encode those bytes differently, use
138          * complicated (and allegedly sometimes-wrong) correction code,
139          * and usually shipped with U-Boot that uses software ECC:
140          *      .PQR.stu ==> PsQRtu
141          *
142          * If you need MV/TI compatible NAND I/O in U-Boot, it should
143          * be possible to (a) change the mangling above, (b) reverse
144          * that mangling in nand_davinci_correct_data() below.
145          */
146
147         return 0;
148 }
149
150 static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
151 {
152         struct nand_chip *this = mtd->priv;
153         u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
154                                           (read_ecc[2] << 16);
155         u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
156                                           (calc_ecc[2] << 16);
157         u_int32_t diff = ecc_calc ^ ecc_nand;
158
159         if (diff) {
160                 if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
161                         /* Correctable error */
162                         if ((diff >> (12 + 3)) < this->ecc.size) {
163                                 uint8_t find_bit = 1 << ((diff >> 12) & 7);
164                                 uint32_t find_byte = diff >> (12 + 3);
165
166                                 dat[find_byte] ^= find_bit;
167                                 MTDDEBUG(MTD_DEBUG_LEVEL0, "Correcting single "
168                                          "bit ECC error at offset: %d, bit: "
169                                          "%d\n", find_byte, find_bit);
170                                 return 1;
171                         } else {
172                                 return -1;
173                         }
174                 } else if (!(diff & (diff - 1))) {
175                         /* Single bit ECC error in the ECC itself,
176                            nothing to fix */
177                         MTDDEBUG(MTD_DEBUG_LEVEL0, "Single bit ECC error in "
178                                  "ECC.\n");
179                         return 1;
180                 } else {
181                         /* Uncorrectable error */
182                         MTDDEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
183                         return -1;
184                 }
185         }
186         return(0);
187 }
188 #endif /* CONFIG_SYS_NAND_HW_ECC */
189
190 static int nand_davinci_dev_ready(struct mtd_info *mtd)
191 {
192         return emif_regs->NANDFSR & 0x1;
193 }
194
195 static void nand_flash_init(void)
196 {
197         /* This is for DM6446 EVM and *very* similar.  DO NOT GROW THIS!
198          * Instead, have your board_init() set EMIF timings, based on its
199          * knowledge of the clocks and what devices are hooked up ... and
200          * don't even do that unless no UBL handled it.
201          */
202 #ifdef CONFIG_SOC_DM6446
203         u_int32_t       acfg1 = 0x3ffffffc;
204
205         /*------------------------------------------------------------------*
206          *  NAND FLASH CHIP TIMEOUT @ 459 MHz                               *
207          *                                                                  *
208          *  AEMIF.CLK freq   = PLL1/6 = 459/6 = 76.5 MHz                    *
209          *  AEMIF.CLK period = 1/76.5 MHz = 13.1 ns                         *
210          *                                                                  *
211          *------------------------------------------------------------------*/
212          acfg1 = 0
213                 | (0 << 31 )    /* selectStrobe */
214                 | (0 << 30 )    /* extWait */
215                 | (1 << 26 )    /* writeSetup   10 ns */
216                 | (3 << 20 )    /* writeStrobe  40 ns */
217                 | (1 << 17 )    /* writeHold    10 ns */
218                 | (1 << 13 )    /* readSetup    10 ns */
219                 | (5 << 7 )     /* readStrobe   60 ns */
220                 | (1 << 4 )     /* readHold     10 ns */
221                 | (3 << 2 )     /* turnAround   ?? ns */
222                 | (0 << 0 )     /* asyncSize    8-bit bus */
223                 ;
224
225         emif_regs->AB1CR = acfg1; /* CS2 */
226
227         emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */
228 #endif
229 }
230
231 int board_nand_init(struct nand_chip *nand)
232 {
233         nand->chip_delay  = 0;
234         nand->select_chip = nand_davinci_select_chip;
235 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
236         nand->options     = NAND_USE_FLASH_BBT;
237 #endif
238 #ifdef CONFIG_SYS_NAND_HW_ECC
239         nand->ecc.mode = NAND_ECC_HW;
240         nand->ecc.size = 512;
241         nand->ecc.bytes = 3;
242         nand->ecc.calculate = nand_davinci_calculate_ecc;
243         nand->ecc.correct  = nand_davinci_correct_data;
244         nand->ecc.hwctl  = nand_davinci_enable_hwecc;
245 #else
246         nand->ecc.mode = NAND_ECC_SOFT;
247 #endif /* CONFIG_SYS_NAND_HW_ECC */
248
249         /* Set address of hardware control function */
250         nand->cmd_ctrl = nand_davinci_hwcontrol;
251
252         nand->dev_ready = nand_davinci_dev_ready;
253
254         nand_flash_init();
255
256         return(0);
257 }