arm, kirkwood: added kw_gpio_set_valid() in gpio.h
[platform/kernel/u-boot.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 static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE;
51
52 static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
53 {
54         struct          nand_chip *this = mtd->priv;
55         u_int32_t       IO_ADDR_W = (u_int32_t)this->IO_ADDR_W;
56
57         IO_ADDR_W &= ~(MASK_ALE|MASK_CLE);
58
59         if (ctrl & NAND_CTRL_CHANGE) {
60                 if ( ctrl & NAND_CLE )
61                         IO_ADDR_W |= MASK_CLE;
62                 if ( ctrl & NAND_ALE )
63                         IO_ADDR_W |= MASK_ALE;
64                 this->IO_ADDR_W = (void __iomem *) IO_ADDR_W;
65         }
66
67         if (cmd != NAND_CMD_NONE)
68                 writeb(cmd, this->IO_ADDR_W);
69 }
70
71 #ifdef CONFIG_SYS_NAND_HW_ECC
72
73 static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
74 {
75         int             dummy;
76
77         dummy = emif_regs->NANDF1ECC;
78
79         /* FIXME:  only chipselect 0 is supported for now */
80         emif_regs->NANDFCR |= 1 << 8;
81 }
82
83 static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
84 {
85         u_int32_t       ecc = 0;
86
87         if (region == 1)
88                 ecc = emif_regs->NANDF1ECC;
89         else if (region == 2)
90                 ecc = emif_regs->NANDF2ECC;
91         else if (region == 3)
92                 ecc = emif_regs->NANDF3ECC;
93         else if (region == 4)
94                 ecc = emif_regs->NANDF4ECC;
95
96         return(ecc);
97 }
98
99 static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
100 {
101         u_int32_t               tmp;
102         const int region = 1;
103
104         tmp = nand_davinci_readecc(mtd, region);
105
106         /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
107          * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
108         tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);
109
110         /* Invert so that erased block ECC is correct */
111         tmp = ~tmp;
112
113         *ecc_code++ = tmp;
114         *ecc_code++ = tmp >>  8;
115         *ecc_code++ = tmp >> 16;
116
117         /* NOTE:  the above code matches mainline Linux:
118          *      .PQR.stu ==> ~PQRstu
119          *
120          * MontaVista/TI kernels encode those bytes differently, use
121          * complicated (and allegedly sometimes-wrong) correction code,
122          * and usually shipped with U-Boot that uses software ECC:
123          *      .PQR.stu ==> PsQRtu
124          *
125          * If you need MV/TI compatible NAND I/O in U-Boot, it should
126          * be possible to (a) change the mangling above, (b) reverse
127          * that mangling in nand_davinci_correct_data() below.
128          */
129
130         return 0;
131 }
132
133 static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
134 {
135         struct nand_chip *this = mtd->priv;
136         u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
137                                           (read_ecc[2] << 16);
138         u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
139                                           (calc_ecc[2] << 16);
140         u_int32_t diff = ecc_calc ^ ecc_nand;
141
142         if (diff) {
143                 if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
144                         /* Correctable error */
145                         if ((diff >> (12 + 3)) < this->ecc.size) {
146                                 uint8_t find_bit = 1 << ((diff >> 12) & 7);
147                                 uint32_t find_byte = diff >> (12 + 3);
148
149                                 dat[find_byte] ^= find_bit;
150                                 MTDDEBUG(MTD_DEBUG_LEVEL0, "Correcting single "
151                                          "bit ECC error at offset: %d, bit: "
152                                          "%d\n", find_byte, find_bit);
153                                 return 1;
154                         } else {
155                                 return -1;
156                         }
157                 } else if (!(diff & (diff - 1))) {
158                         /* Single bit ECC error in the ECC itself,
159                            nothing to fix */
160                         MTDDEBUG(MTD_DEBUG_LEVEL0, "Single bit ECC error in "
161                                  "ECC.\n");
162                         return 1;
163                 } else {
164                         /* Uncorrectable error */
165                         MTDDEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
166                         return -1;
167                 }
168         }
169         return(0);
170 }
171 #endif /* CONFIG_SYS_NAND_HW_ECC */
172
173 static int nand_davinci_dev_ready(struct mtd_info *mtd)
174 {
175         return emif_regs->NANDFSR & 0x1;
176 }
177
178 static void nand_flash_init(void)
179 {
180         /* This is for DM6446 EVM and *very* similar.  DO NOT GROW THIS!
181          * Instead, have your board_init() set EMIF timings, based on its
182          * knowledge of the clocks and what devices are hooked up ... and
183          * don't even do that unless no UBL handled it.
184          */
185 #ifdef CONFIG_SOC_DM6446
186         u_int32_t       acfg1 = 0x3ffffffc;
187
188         /*------------------------------------------------------------------*
189          *  NAND FLASH CHIP TIMEOUT @ 459 MHz                               *
190          *                                                                  *
191          *  AEMIF.CLK freq   = PLL1/6 = 459/6 = 76.5 MHz                    *
192          *  AEMIF.CLK period = 1/76.5 MHz = 13.1 ns                         *
193          *                                                                  *
194          *------------------------------------------------------------------*/
195          acfg1 = 0
196                 | (0 << 31 )    /* selectStrobe */
197                 | (0 << 30 )    /* extWait */
198                 | (1 << 26 )    /* writeSetup   10 ns */
199                 | (3 << 20 )    /* writeStrobe  40 ns */
200                 | (1 << 17 )    /* writeHold    10 ns */
201                 | (1 << 13 )    /* readSetup    10 ns */
202                 | (5 << 7 )     /* readStrobe   60 ns */
203                 | (1 << 4 )     /* readHold     10 ns */
204                 | (3 << 2 )     /* turnAround   ?? ns */
205                 | (0 << 0 )     /* asyncSize    8-bit bus */
206                 ;
207
208         emif_regs->AB1CR = acfg1; /* CS2 */
209
210         emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */
211 #endif
212 }
213
214 void davinci_nand_init(struct nand_chip *nand)
215 {
216         nand->chip_delay  = 0;
217 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
218         nand->options     = NAND_USE_FLASH_BBT;
219 #endif
220 #ifdef CONFIG_SYS_NAND_HW_ECC
221         nand->ecc.mode = NAND_ECC_HW;
222         nand->ecc.size = 512;
223         nand->ecc.bytes = 3;
224         nand->ecc.calculate = nand_davinci_calculate_ecc;
225         nand->ecc.correct  = nand_davinci_correct_data;
226         nand->ecc.hwctl  = nand_davinci_enable_hwecc;
227 #else
228         nand->ecc.mode = NAND_ECC_SOFT;
229 #endif /* CONFIG_SYS_NAND_HW_ECC */
230
231         /* Set address of hardware control function */
232         nand->cmd_ctrl = nand_davinci_hwcontrol;
233
234         nand->dev_ready = nand_davinci_dev_ready;
235
236         nand_flash_init();
237 }
238
239 int board_nand_init(struct nand_chip *chip) __attribute__((weak));
240
241 int board_nand_init(struct nand_chip *chip)
242 {
243         davinci_nand_init(chip);
244         return 0;
245 }