2 * S3C64XX/S5PC100 OneNAND driver at U-Boot
4 * Copyright (C) 2008-2009 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
8 * Emulate the pseudo BufferRAM
10 * See file CREDITS for list of people who contributed to this
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 #include <linux/mtd/compat.h>
32 #include <linux/mtd/mtd.h>
33 #include <linux/mtd/onenand.h>
34 #include <linux/mtd/samsung_onenand.h>
37 #include <asm/errno.h>
40 #define DPRINTK(format, args...) \
42 printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \
45 #define DPRINTK(...) do { } while (0)
48 #define ONENAND_ERASE_STATUS 0x00
49 #define ONENAND_MULTI_ERASE_SET 0x01
50 #define ONENAND_ERASE_START 0x03
51 #define ONENAND_UNLOCK_START 0x08
52 #define ONENAND_UNLOCK_END 0x09
53 #define ONENAND_LOCK_START 0x0A
54 #define ONENAND_LOCK_END 0x0B
55 #define ONENAND_LOCK_TIGHT_START 0x0C
56 #define ONENAND_LOCK_TIGHT_END 0x0D
57 #define ONENAND_UNLOCK_ALL 0x0E
58 #define ONENAND_OTP_ACCESS 0x12
59 #define ONENAND_SPARE_ACCESS_ONLY 0x13
60 #define ONENAND_MAIN_ACCESS_ONLY 0x14
61 #define ONENAND_ERASE_VERIFY 0x15
62 #define ONENAND_MAIN_SPARE_ACCESS 0x16
63 #define ONENAND_PIPELINE_READ 0x4000
65 #if defined(CONFIG_S3C64XX)
66 #define MAP_00 (0x0 << 24)
67 #define MAP_01 (0x1 << 24)
68 #define MAP_10 (0x2 << 24)
69 #define MAP_11 (0x3 << 24)
70 #elif defined(CONFIG_S5P)
71 #define MAP_00 (0x0 << 26)
72 #define MAP_01 (0x1 << 26)
73 #define MAP_10 (0x2 << 26)
74 #define MAP_11 (0x3 << 26)
77 /* read/write of XIP buffer */
78 #define CMD_MAP_00(mem_addr) (MAP_00 | ((mem_addr) << 1))
79 /* read/write to the memory device */
80 #define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr))
81 /* control special functions of the memory device */
82 #define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr))
83 /* direct interface(direct access) with the memory device */
84 #define CMD_MAP_11(mem_addr) (MAP_11 | ((mem_addr) << 2))
89 void __iomem *ahb_addr;
91 void __iomem *page_buf;
92 void __iomem *oob_buf;
93 unsigned int (*mem_addr)(int fba, int fpa, int fsa);
94 struct samsung_onenand *reg;
97 static struct s3c_onenand *onenand;
99 static int s3c_read_cmd(unsigned int cmd)
101 return readl(onenand->ahb_addr + cmd);
104 static void s3c_write_cmd(int value, unsigned int cmd)
106 writel(value, onenand->ahb_addr + cmd);
112 * fba: flash block address
113 * fpa: flash page address
114 * fsa: flash sector address
116 * return the buffer address on the memory device
117 * It will be combined with CMD_MAP_XX
119 #if defined(CONFIG_S3C64XX)
120 static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
122 return (fba << 12) | (fpa << 6) | (fsa << 4);
124 #elif defined(CONFIG_S5P)
125 static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
127 return (fba << 13) | (fpa << 7) | (fsa << 5);
131 static void s3c_onenand_reset(void)
133 unsigned long timeout = 0x10000;
136 writel(ONENAND_MEM_RESET_COLD, &onenand->reg->mem_reset);
138 stat = readl(&onenand->reg->int_err_stat);
142 stat = readl(&onenand->reg->int_err_stat);
143 writel(stat, &onenand->reg->int_err_ack);
145 /* Clear interrupt */
146 writel(0x0, &onenand->reg->int_err_ack);
147 /* Clear the ECC status */
148 writel(0x0, &onenand->reg->ecc_err_stat);
151 static unsigned short s3c_onenand_readw(void __iomem *addr)
153 struct onenand_chip *this = onenand->mtd->priv;
154 int reg = addr - this->base;
155 int word_addr = reg >> 1;
158 /* It's used for probing time */
160 case ONENAND_REG_MANUFACTURER_ID:
161 return readl(&onenand->reg->manufact_id);
162 case ONENAND_REG_DEVICE_ID:
163 return readl(&onenand->reg->device_id);
164 case ONENAND_REG_VERSION_ID:
165 return readl(&onenand->reg->flash_ver_id);
166 case ONENAND_REG_DATA_BUFFER_SIZE:
167 return readl(&onenand->reg->data_buf_size);
168 case ONENAND_REG_TECHNOLOGY:
169 return readl(&onenand->reg->tech);
170 case ONENAND_REG_SYS_CFG1:
171 return readl(&onenand->reg->mem_cfg);
173 /* Used at unlock all status */
174 case ONENAND_REG_CTRL_STATUS:
177 case ONENAND_REG_WP_STATUS:
178 return ONENAND_WP_US;
184 /* BootRAM access control */
185 if (reg < ONENAND_DATARAM && onenand->bootram_command) {
187 return readl(&onenand->reg->manufact_id);
189 return readl(&onenand->reg->device_id);
191 return readl(&onenand->reg->flash_ver_id);
194 value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff;
195 printk(KERN_INFO "s3c_onenand_readw: Illegal access"
196 " at reg 0x%x, value 0x%x\n", word_addr, value);
200 static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
202 struct onenand_chip *this = onenand->mtd->priv;
203 int reg = addr - this->base;
204 int word_addr = reg >> 1;
206 /* It's used for probing time */
208 case ONENAND_REG_SYS_CFG1:
209 writel(value, &onenand->reg->mem_cfg);
212 case ONENAND_REG_START_ADDRESS1:
213 case ONENAND_REG_START_ADDRESS2:
216 /* Lock/lock-tight/unlock/unlock_all */
217 case ONENAND_REG_START_BLOCK_ADDRESS:
224 /* BootRAM access control */
225 if (reg < ONENAND_DATARAM) {
226 if (value == ONENAND_CMD_READID) {
227 onenand->bootram_command = 1;
230 if (value == ONENAND_CMD_RESET) {
231 writel(ONENAND_MEM_RESET_COLD,
232 &onenand->reg->mem_reset);
233 onenand->bootram_command = 0;
238 printk(KERN_INFO "s3c_onenand_writew: Illegal access"
239 " at reg 0x%x, value 0x%x\n", word_addr, value);
241 s3c_write_cmd(value, CMD_MAP_11(word_addr));
244 static int s3c_onenand_wait(struct mtd_info *mtd, int state)
246 unsigned int flags = INT_ACT;
247 unsigned int stat, ecc;
248 unsigned long timeout = 0x100000;
252 flags |= BLK_RW_CMP | LOAD_CMP;
255 flags |= BLK_RW_CMP | PGM_CMP;
258 flags |= BLK_RW_CMP | ERS_CMP;
268 stat = readl(&onenand->reg->int_err_stat);
273 /* To get correct interrupt status in timeout case */
274 stat = readl(&onenand->reg->int_err_stat);
275 writel(stat, &onenand->reg->int_err_ack);
278 * In the Spec. it checks the controller status first
279 * However if you get the correct information in case of
280 * power off recovery (POR) test, it should read ECC status first
282 if (stat & LOAD_CMP) {
283 ecc = readl(&onenand->reg->ecc_err_stat);
284 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
285 printk(KERN_INFO "%s: ECC error = 0x%04x\n",
287 mtd->ecc_stats.failed++;
292 if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
293 printk(KERN_INFO "%s: controller error = 0x%04x\n",
295 if (stat & LOCKED_BLK)
296 printk(KERN_INFO "%s: it's locked error = 0x%04x\n",
305 static int s3c_onenand_command(struct mtd_info *mtd, int cmd,
306 loff_t addr, size_t len)
308 struct onenand_chip *this = mtd->priv;
310 int fba, fpa, fsa = 0;
311 unsigned int mem_addr;
312 int i, mcount, scount;
315 fba = (int) (addr >> this->erase_shift);
316 fpa = (int) (addr >> this->page_shift);
317 fpa &= this->page_mask;
319 mem_addr = onenand->mem_addr(fba, fpa, fsa);
322 case ONENAND_CMD_READ:
323 case ONENAND_CMD_READOOB:
324 case ONENAND_CMD_BUFFERRAM:
325 ONENAND_SET_NEXT_BUFFERRAM(this);
330 index = ONENAND_CURRENT_BUFFERRAM(this);
333 * Emulate Two BufferRAMs and access with 4 bytes pointer
335 m = (unsigned int *) onenand->page_buf;
336 s = (unsigned int *) onenand->oob_buf;
339 m += (this->writesize >> 2);
340 s += (mtd->oobsize >> 2);
343 mcount = mtd->writesize >> 2;
344 scount = mtd->oobsize >> 2;
347 case ONENAND_CMD_READ:
349 for (i = 0; i < mcount; i++)
350 *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
353 case ONENAND_CMD_READOOB:
354 writel(TSRF, &onenand->reg->trans_spare);
356 for (i = 0; i < mcount; i++)
357 *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
360 for (i = 0; i < scount; i++)
361 *s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
363 writel(0, &onenand->reg->trans_spare);
366 case ONENAND_CMD_PROG:
368 for (i = 0; i < mcount; i++)
369 s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
372 case ONENAND_CMD_PROGOOB:
373 writel(TSRF, &onenand->reg->trans_spare);
375 /* Main - dummy write */
376 for (i = 0; i < mcount; i++)
377 s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));
380 for (i = 0; i < scount; i++)
381 s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));
383 writel(0, &onenand->reg->trans_spare);
386 case ONENAND_CMD_UNLOCK_ALL:
387 s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
390 case ONENAND_CMD_ERASE:
391 s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
394 case ONENAND_CMD_MULTIBLOCK_ERASE:
395 s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr));
398 case ONENAND_CMD_ERASE_VERIFY:
399 s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr));
409 static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
411 struct onenand_chip *this = mtd->priv;
412 int index = ONENAND_CURRENT_BUFFERRAM(this);
415 if (area == ONENAND_DATARAM) {
416 p = (unsigned char *) onenand->page_buf;
418 p += this->writesize;
420 p = (unsigned char *) onenand->oob_buf;
428 static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
429 unsigned char *buffer, int offset,
434 p = s3c_get_bufferram(mtd, area);
435 memcpy(buffer, p + offset, count);
439 static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
440 const unsigned char *buffer, int offset,
445 p = s3c_get_bufferram(mtd, area);
446 memcpy(p + offset, buffer, count);
450 static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
452 struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base;
453 unsigned int flags = INT_ACT | LOAD_CMP;
455 unsigned long timeout = 0x10000;
458 stat = readl(®->int_err_stat);
462 /* To get correct interrupt status in timeout case */
463 stat = readl(&onenand->reg->int_err_stat);
464 writel(stat, &onenand->reg->int_err_ack);
466 if (stat & LD_FAIL_ECC_ERR) {
468 return ONENAND_BBT_READ_ERROR;
471 if (stat & LOAD_CMP) {
472 int ecc = readl(&onenand->reg->ecc_err_stat);
473 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
475 return ONENAND_BBT_READ_ERROR;
482 static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
484 struct onenand_chip *this = mtd->priv;
485 unsigned int block, end;
488 end = this->chipsize >> this->erase_shift;
490 for (block = 0; block < end; block++) {
491 tmp = s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));
493 if (readl(&onenand->reg->int_err_stat) & LOCKED_BLK) {
494 printf("block %d is write-protected!\n", block);
495 writel(LOCKED_BLK, &onenand->reg->int_err_ack);
500 static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
503 struct onenand_chip *this = mtd->priv;
504 int start, end, start_mem_addr, end_mem_addr;
506 start = ofs >> this->erase_shift;
507 start_mem_addr = onenand->mem_addr(start, 0, 0);
508 end = start + (len >> this->erase_shift) - 1;
509 end_mem_addr = onenand->mem_addr(end, 0, 0);
511 if (cmd == ONENAND_CMD_LOCK) {
512 s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr));
513 s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr));
515 s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr));
516 s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr));
519 this->wait(mtd, FL_LOCKING);
522 static void s3c_onenand_unlock_all(struct mtd_info *mtd)
524 struct onenand_chip *this = mtd->priv;
526 size_t len = this->chipsize;
528 /* FIXME workaround */
529 this->subpagesize = mtd->writesize;
530 mtd->subpage_sft = 0;
532 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
533 /* Write unlock command */
534 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
536 /* No need to check return value */
537 this->wait(mtd, FL_LOCKING);
539 /* Workaround for all block unlock in DDP */
540 if (!ONENAND_IS_DDP(this)) {
541 s3c_onenand_check_lock_status(mtd);
545 /* All blocks on another chip */
546 ofs = this->chipsize >> 1;
547 len = this->chipsize >> 1;
550 s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
551 s3c_onenand_check_lock_status(mtd);
554 #ifdef CONFIG_S3C64XX
555 static void s3c_set_width_regs(struct onenand_chip *this)
561 dev_id = DEVICE_ID0_REG;
563 density = (dev_id >> ONENAND_DEVICE_DENSITY_SHIFT) & 0xf;
564 dbs_dfs = !!(dev_id & ONENAND_DEVICE_IS_DDP);
568 fba--; /* Decrease the fba */
570 if (density >= ONENAND_DEVICE_DENSITY_512Mb)
575 DPRINTK("FBA %lu, FPA %lu, FSA %lu, DDP %lu",
576 FBA_WIDTH0_REG, FPA_WIDTH0_REG, FSA_WIDTH0_REG,
579 DPRINTK("mem_cfg0 0x%lx, sync mode %lu, "
580 "dev_page_size %lu, BURST LEN %lu",
581 MEM_CFG0_REG, SYNC_MODE_REG,
582 DEV_PAGE_SIZE_REG, BURST_LEN0_REG);
584 DEV_PAGE_SIZE_REG = 0x1;
586 FBA_WIDTH0_REG = fba;
587 FPA_WIDTH0_REG = fpa;
588 FSA_WIDTH0_REG = fsa;
589 DBS_DFS_WIDTH0_REG = dbs_dfs;
593 void s3c_onenand_init(struct mtd_info *mtd)
595 struct onenand_chip *this = mtd->priv;
596 u32 size = (4 << 10); /* 4 KiB */
598 onenand = malloc(sizeof(struct s3c_onenand));
602 onenand->page_buf = malloc(size * sizeof(char));
603 if (!onenand->page_buf)
605 memset(onenand->page_buf, 0xff, size);
607 onenand->oob_buf = malloc(128 * sizeof(char));
608 if (!onenand->oob_buf)
610 memset(onenand->oob_buf, 0xff, 128);
614 #if defined(CONFIG_S3C64XX)
615 onenand->base = (void *)0x70100000;
616 onenand->ahb_addr = (void *)0x20000000;
617 #elif defined(CONFIG_S5P)
618 onenand->base = (void *)0xE7100000;
619 onenand->ahb_addr = (void *)0xB0000000;
621 onenand->mem_addr = s3c_mem_addr;
622 onenand->reg = (struct samsung_onenand *)onenand->base;
624 this->read_word = s3c_onenand_readw;
625 this->write_word = s3c_onenand_writew;
627 this->wait = s3c_onenand_wait;
628 this->bbt_wait = s3c_onenand_bbt_wait;
629 this->unlock_all = s3c_onenand_unlock_all;
630 this->command = s3c_onenand_command;
632 this->read_bufferram = onenand_read_bufferram;
633 this->write_bufferram = onenand_write_bufferram;
635 this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;