OMAP: NAND: increase system partition size to 180MB
[pandaboard:u-boot-4460.git] / cpu / omap3 / nand.c
1 /*
2  * (C) Copyright 2004-2009 Texas Instruments, <www.ti.com>
3  * Rohit Choraria <rohitkc@ti.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25
26 #include <asm/io.h>
27
28 #include <asm/arch/cpu.h>
29 #include <asm/arch/mem.h>
30 #include <linux/mtd/nand_ecc.h>
31
32 #if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
33
34 #include <nand.h>
35
36 #if (CONFIG_FASTBOOT)
37 #include <fastboot.h>
38 #endif
39
40 unsigned char cs;
41 volatile unsigned long gpmc_cs_base_add;
42
43 #define GPMC_BUF_EMPTY 0
44 #define GPMC_BUF_FULL 1
45
46 #define ECC_P1_128_E(val)    ((val)  & 0x000000FF)         /* Bit 0 to 7 */
47 #define ECC_P512_2048_E(val) (((val) & 0x00000F00)>>8)     /* Bit 8 to 11 */
48 #define ECC_P1_128_O(val)    (((val) & 0x00FF0000)>>16)    /* Bit 16 to Bit 23 */
49 #define ECC_P512_2048_O(val) (((val) & 0x0F000000)>>24)    /* Bit 24 to Bit 27 */
50
51 void omap_nand_switch_ecc(struct mtd_info *, int );
52
53 int nand_unlock(struct mtd_info *mtd, unsigned long off, unsigned long size)
54 {
55         register struct nand_chip *this = mtd->priv;
56         unsigned long start_block, end_block;
57
58         printk("\nUnlocking %x - %x. locking rest..\n", off, off + size);
59
60         if (off + size == this->chipsize)
61                 size -= mtd->erasesize;
62         start_block = (unsigned long) (off >> this->page_shift);
63         end_block = (unsigned long) ((off + size) >> this->page_shift);
64
65         this->cmdfunc(mtd, 0x23, -1, start_block);
66         this->cmdfunc(mtd, 0x24, -1, end_block);
67         ndelay (100);
68
69         return 0;
70 }
71 /*
72  * omap_nand_hwcontrol - Set the address pointers corretly for the 
73  *                      following address/data/command operation
74  * @mtd:        MTD device structure
75  * @ctrl:       Says whether Address or Command or Data is following.
76  */
77
78 static void omap_nand_hwcontrol(struct mtd_info *mtd, int ctrl)
79 {
80         register struct nand_chip *this = mtd->priv;
81
82
83 /*
84  * Point the IO_ADDR to DATA and ADDRESS registers instead of chip address
85  */
86         switch (ctrl) {
87          case NAND_CTL_SETCLE:
88                 this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD;
89                 this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
90                 break;
91          case NAND_CTL_SETALE:
92                 this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_ADR;
93                 this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
94                 break;
95          case NAND_CTL_CLRCLE:
96                 this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
97                 this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
98                 break;
99          case NAND_CTL_CLRALE:
100                 this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
101                 this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
102                 break;
103         }
104 }
105
106 /*
107  * omap_nand_wait - called primarily after a program/erase operation
108  *                      so that we access NAND again only after the device
109  *                      is ready again. 
110  * @mtd:        MTD device structure
111  * @chip:       nand_chip structure
112  * @state:      State from which wait function is being called i.e write/erase.
113  */
114 static int omap_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, int state)
115 {
116         register struct nand_chip *this = mtd->priv;
117         int status = 0;
118         void *nand_ptr_r, *nand_ptr_w;
119
120         this->IO_ADDR_W = (void *) gpmc_cs_base_add + GPMC_NAND_CMD;
121         this->IO_ADDR_R = (void *) gpmc_cs_base_add + GPMC_NAND_DAT;
122         nand_ptr_w = this->IO_ADDR_W;
123         nand_ptr_r = this->IO_ADDR_R;
124
125         /* Send the status command and loop until the device is free */
126         while(!(status & 0x40)){
127                 __raw_writeb(NAND_CMD_STATUS & 0xFF, nand_ptr_w);
128                 status = __raw_readb(nand_ptr_r);
129         }
130         return status;  
131 }
132
133 #ifdef CFG_NAND_WIDTH_16
134 /**
135  * omap_nand_write_buf16 - [DEFAULT] write buffer to chip
136  * @mtd:        MTD device structure
137  * @buf:        data buffer
138  * @len:        number of bytes to write
139  *
140  * Default write function for 16bit buswith
141  */
142 static void omap_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
143 {
144         int i;
145         struct nand_chip *this = mtd->priv;
146         u16 *p = (u16 *) buf;
147         void *nand_ptr_w = this->IO_ADDR_W;
148
149         len >>= 1;
150
151         for (i=0; i<len; i++){
152                 writew(p[i], nand_ptr_w);
153                 while (GPMC_BUF_EMPTY == (readl(GPMC_STATUS) & GPMC_BUF_FULL));
154         }
155 }
156
157 /**
158  * nand_read_buf16 - [DEFAULT] read chip data into buffer
159  * @mtd:        MTD device structure
160  * @buf:        buffer to store date
161  * @len:        number of bytes to read
162  *
163  * Default read function for 16bit buswith
164  */
165
166 static void omap_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
167 {
168         int i;
169         struct nand_chip *this = mtd->priv;
170         u16 *p = (u16 *) buf;
171         void *nand_ptr_r = this->IO_ADDR_R;
172
173         len >>= 1;
174
175         for (i=0; i<len; i++)
176                 p[i] = readw(nand_ptr_r);
177 }
178
179 #else
180 /*
181  * omap_nand_write_buf -  write buffer to NAND controller
182  * @mtd:        MTD device structure
183  * @buf:        data buffer
184  * @len:        number of bytes to write
185  *
186  */
187
188 static void omap_nand_write_buf(struct mtd_info *mtd, const uint8_t * buf,
189                                 int len)
190 {
191         int i;
192         int j=0;
193         struct nand_chip *this = mtd->priv;
194         void *nand_ptr_w = this->IO_ADDR_W;
195
196         for (i = 0; i < len; i++) {
197                 writeb(buf[i], nand_ptr_w);
198                 for(j=0;j<10;j++);
199         }
200
201 }
202
203 /*
204  * omap_nand_read_buf - read data from NAND controller into buffer
205  * @mtd:        MTD device structure
206  * @buf:        buffer to store date
207  * @len:        number of bytes to read
208  *
209  */
210
211 static void omap_nand_read_buf(struct mtd_info *mtd, uint8_t * buf, int len)
212 {
213         int i;
214         int j=0;
215         struct nand_chip *this = mtd->priv;
216         void *nand_ptr_r = this->IO_ADDR_R;
217
218         for (i = 0; i < len; i++) {
219                 buf[i] = readb(nand_ptr_r);
220                 while (GPMC_BUF_EMPTY == (readl(GPMC_STATUS) & GPMC_BUF_FULL));
221         }
222 }
223 #endif
224
225 /*
226  * omap_hwecc_init -  Initialize the Hardware ECC for NAND flash in GPMC controller
227  * @mtd:        MTD device structure
228  *
229  */
230 static void omap_hwecc_init(struct nand_chip *chip)
231 {
232         unsigned long val = 0x0;
233
234         /* Init ECC Control Register */
235         /*       Clear all ECC  | Enable Reg1 */
236         val = ( (0x00000001<<8) | 0x00000001 );
237         __raw_writel(val, GPMC_BASE + GPMC_ECC_CONTROL);
238         __raw_writel(0x3fcff000, GPMC_BASE + GPMC_ECC_SIZE_CONFIG);
239 }
240
241 /*
242  * omap_correct_data - Compares the ecc read from nand spare area with ECC registers values
243  *                      and corrects one bit error if it has occured 
244  * @mtd:                 MTD device structure
245  * @dat:                 page data
246  * @read_ecc:            ecc read from nand flash
247  * @calc_ecc:            ecc read from ECC registers
248  */
249 static int omap_correct_data(struct mtd_info *mtd,u_char *dat,
250                              u_char *read_ecc, u_char *calc_ecc)
251 {
252         return 0;
253 }
254
255 /*
256  *  omap_calculate_ecc - Generate non-inverted ECC bytes.
257  *
258  *  Using noninverted ECC can be considered ugly since writing a blank
259  *  page ie. padding will clear the ECC bytes. This is no problem as 
260  *  long nobody is trying to write data on the seemingly unused page.
261  *  Reading an erased page will produce an ECC mismatch between
262  *  generated and read ECC bytes that has to be dealt with separately.
263  *  @mtd:       MTD structure
264  *  @dat:       unused
265  *  @ecc_code:  ecc_code buffer
266 */
267 static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, 
268                               u_char *ecc_code)
269 {
270         unsigned long val = 0x0;
271         unsigned long reg;
272
273         /* Start Reading from HW ECC1_Result = 0x200 */
274         reg = (unsigned long)(GPMC_BASE + GPMC_ECC1_RESULT);  
275         val = __raw_readl(reg);
276
277         *ecc_code++ = ECC_P1_128_E(val);
278         *ecc_code++ = ECC_P1_128_O(val);
279         *ecc_code++ = ECC_P512_2048_E(val) | ECC_P512_2048_O(val) << 4;
280
281         return 0;
282 }
283
284 /*
285  * omap_enable_ecc - This function enables the hardware ecc functionality
286  * @mtd:        MTD device structure
287  * @mode:       Read/Write mode
288  */
289 static void omap_enable_hwecc(struct mtd_info *mtd , int mode)
290 {
291         struct nand_chip *chip = mtd->priv;
292         unsigned int val = __raw_readl(GPMC_BASE + GPMC_ECC_CONFIG);
293         unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; 
294
295         switch (mode) {
296                 case NAND_ECC_READ    :
297                         __raw_writel(0x101, GPMC_BASE + GPMC_ECC_CONTROL);
298                         /* ECC col width) | ( CS )  | ECC Enable */
299                         val = (dev_width << 7) | (cs << 1) | (0x1) ;
300                         break;
301                 case NAND_ECC_READSYN :
302                         __raw_writel(0x100, GPMC_BASE + GPMC_ECC_CONTROL);
303                         /* ECC col width) | ( CS )  | ECC Enable */
304                         val = (dev_width << 7) | (cs << 1) | (0x1) ;
305                         break;
306                 case NAND_ECC_WRITE   :
307                         __raw_writel(0x101, GPMC_BASE + GPMC_ECC_CONTROL);
308                         /* ECC col width) | ( CS )  | ECC Enable */
309                         val = (dev_width << 7) | (cs << 1) | (0x1) ;
310                         break;
311                 default:
312                         printf("Error: Unrecognized Mode[%d]!\n", mode);
313                         break;
314         }
315
316         __raw_writel(val, GPMC_BASE + GPMC_ECC_CONFIG);
317 }
318
319 static struct nand_oobinfo hw_nand_oob_64 = {
320         .useecc = MTD_NANDECC_AUTOPLACE,
321         .eccbytes = 12,
322         .eccpos = {     
323                         2, 3, 4, 5,
324                         6, 7, 8, 9, 
325                         10, 11, 12, 13
326                 },
327         .oobfree = { {14, 50} }  /* don't care */
328 };
329
330 static struct nand_oobinfo sw_nand_oob_64 = {
331         .useecc = MTD_NANDECC_AUTOPLACE,
332         .eccbytes = 24,
333         .eccpos = {
334                         40, 41, 42, 43, 44, 45, 46, 47,
335                         48, 49, 50, 51, 52, 53, 54, 55,
336                         56, 57, 58, 59, 60, 61, 62, 63
337                 },
338         .oobfree = { {2, 38} }
339 };
340
341
342 void omap_nand_switch_ecc(struct mtd_info *mtd, int hardware)
343 {
344         struct nand_chip *nand = mtd->priv;
345
346         if (!hardware) {
347                 nand->eccmode           = NAND_ECC_SOFT;
348                 nand->autooob           = &sw_nand_oob_64;
349 #if (CFG_SW_ECC_512)
350                 nand->eccsize           = 512;
351 #else
352                 nand->eccsize           = 256;
353 #endif
354                 nand->eccbytes          = 3;
355                 nand->eccsteps          = mtd->oobblock / nand->eccsize;
356                 nand->enable_hwecc      = 0;
357                 nand->calculate_ecc     = nand_calculate_ecc;
358                 nand->correct_data      = nand_correct_data;
359         } else {
360                 nand->eccmode           = NAND_ECC_HW3_512;
361                 nand->autooob           = &hw_nand_oob_64;
362                 nand->eccsize           = 512;
363                 nand->eccbytes          = 3;
364                 nand->eccsteps          = 4;
365                 nand->enable_hwecc      = omap_enable_hwecc;
366                 nand->correct_data      = omap_correct_data;
367                 nand->calculate_ecc     = omap_calculate_ecc;
368
369                 omap_hwecc_init(nand);
370         }
371
372         mtd->eccsize = nand->eccsize;
373         nand->oobdirty = 1;
374
375         if (nand->options & NAND_BUSWIDTH_16) {
376                 mtd->oobavail = mtd->oobsize - (nand->autooob->eccbytes + 2);
377                 if (nand->autooob->eccbytes & 0x01)
378                         mtd->oobavail--;
379         } else
380                 mtd->oobavail = mtd->oobsize - (nand->autooob->eccbytes + 1);
381 }
382
383 /*
384  * Board-specific NAND initialization. The following members of the
385  * argument are board-specific (per include/linux/mtd/nand_new.h):
386  * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
387  * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
388  * - hwcontrol: hardwarespecific function for accesing control-lines
389  * - dev_ready: hardwarespecific function for  accesing device ready/busy line
390  * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
391  *   only be provided if a hardware ECC is available
392  * - eccmode: mode of ecc, see defines
393  * - chip_delay: chip dependent delay for transfering data from array to
394  *   read regs (tR)
395  * - options: various chip options. They can partly be set to inform
396  *   nand_scan about special functionality. See the defines for further
397  *   explanation
398  * Members with a "?" were not set in the merged testing-NAND branch,
399  * so they are not set here either.
400  */
401 void board_nand_init(struct nand_chip *nand)
402 {
403         int gpmc_config=0;
404         cs = 0;
405         while (cs <= GPMC_MAX_CS) {
406                 /* Each GPMC set for a single CS is at offset 0x30 */
407                 /* already remapped for us */
408                 gpmc_cs_base_add = (GPMC_CONFIG_CS0 + (cs*0x30));
409                 /* xloader/Uboot would have written the NAND type for us
410                  * -NOTE This is a temporary measure and cannot handle ONENAND.
411                  * The proper way of doing this is to pass the setup of u-boot up to kernel
412                  * using kernel params - something on the lines of machineID
413                  */
414                 /* Check if NAND type is set */
415                 if ((__raw_readl(gpmc_cs_base_add + GPMC_CONFIG1) & 0xC00)==0x800) {
416                 /* Found it!! */
417                         break;
418                 }
419                 cs++;
420         }
421         if (cs > GPMC_MAX_CS) {
422                 printk ("NAND: Unable to find NAND settings in GPMC Configuration - quitting\n");
423         }
424        
425         gpmc_config = __raw_readl(GPMC_CONFIG);
426         /* Disable Write protect */
427         gpmc_config |= 0x10;
428         __raw_writel(gpmc_config, GPMC_CONFIG);
429
430
431         nand->IO_ADDR_R         = (void *)gpmc_cs_base_add + GPMC_NAND_DAT;
432         nand->IO_ADDR_W         = (void *)gpmc_cs_base_add + GPMC_NAND_CMD;
433
434         nand->hwcontrol         = omap_nand_hwcontrol;
435         nand->options           = NAND_NO_PADDING | NAND_CACHEPRG | NAND_NO_AUTOINCR | 
436                                         NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR;
437         nand->read_buf          = omap_nand_read_buf;
438         nand->write_buf         = omap_nand_write_buf;
439
440 #if (CFG_HW_ECC_ROMCODE)
441         nand->eccmode           = NAND_ECC_HW3_512;
442         nand->autooob           = &hw_nand_oob_64;
443         nand->eccsize           = 512;
444         nand->eccbytes          = 3;
445         nand->eccsteps          = 4;
446         nand->enable_hwecc      = omap_enable_hwecc;
447         nand->correct_data      = omap_correct_data;
448         nand->calculate_ecc     = omap_calculate_ecc;
449
450         omap_hwecc_init(nand);
451 #else
452         nand->eccmode           = NAND_ECC_SOFT;
453 #if (CFG_SW_ECC_512)
454         nand->eccsize           = 512;
455 #else
456         nand->eccsize           = 256;
457 #endif
458 #endif
459 /* if RDY/BSY line is connected to OMAP then use the omap ready funcrtion
460  * and the generic nand_wait function which reads the status register after
461  * monitoring the RDY/BSY line. Otherwise use a standard chip delay which
462  * is slightly more than tR (AC Timing) of the NAND device and read the
463  * status register until you get a failure or success
464  */
465
466 #if 0
467         nand->dev_ready         = omap_nand_dev_ready;
468 #else
469         nand->waitfunc          = omap_nand_wait;
470         nand->chip_delay        = 50*2;
471 #endif
472
473 #if (CONFIG_FASTBOOT)
474         /* Initialize the name of fastboot flash name mappings */
475         fastboot_ptentry ptn[7] = {
476                 {
477                         .name   = "xloader",
478                         .start  = 0x0000000,
479                         .length = 0x0020000,
480                         /* Written into the first 4 0x20000 blocks 
481                            Use HW ECC */
482                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
483                                   FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC, 
484                 },
485
486                 {
487                         .name   = "bootloader",
488                         .start  = 0x0080000,
489                         .length = 0x0180000, /* 1.5 M */
490                         /* Skip bad blocks on write 
491                            Use HW ECC */
492                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
493                                   FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC,
494                 },
495                 {
496                         .name   = "environment",
497                         .start  = SMNAND_ENV_OFFSET,  /* set in config file */
498                         .length = 0x0040000,
499                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC |
500                         FASTBOOT_PTENTRY_FLAGS_WRITE_ENV,
501                 },
502
503                 {
504                         .name   = "kernel",
505                         /* Test with start close to bad block
506                            The is dependent on the individual board.
507                            Change to what is required */
508                         /* .start  = 0x0a00000, */
509
510                         /* The real start */
511                         .start  = 0x0200000,
512                         .length = 0x1D00000, /* 30M */
513                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC |
514                         FASTBOOT_PTENTRY_FLAGS_WRITE_I,
515                 },
516 #ifndef CFG_NAND_YAFFS_WRITE
517 #warn "CFG_NAND_YAFFS_WRITE must be defined"
518 #endif
519                 {
520                         .name   = "system",
521                         .start  = 0x2000000,
522                         .length = 0xB400000, /* 180M */
523                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC |
524                         FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS,
525                 },
526                 {
527                         .name   = "userdata",
528                         .start  = 0xD400000,
529                         .length = 0x2000000, /* 32M */
530                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC |
531                         FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS,
532                 },
533                 {
534                         .name   = "cache",
535                         .start  = 0xF400000,
536                         .length = 0x2000000, /* 32M */
537                         .flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC |
538                         FASTBOOT_PTENTRY_FLAGS_WRITE_YAFFS,
539                 },
540         };
541         int i;
542         for (i = 0; i < 7; i++)
543                 fastboot_flash_add_ptn (&ptn[i]);
544         
545 #endif
546
547 }
548
549
550 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
551