1 /* 2 * S5PC100 OneNAND driver at U-Boot 3 * 4 * Copyright (C) 2008-2009 Samsung Electronics 5 * Kyungmin Park <kyungmin.park@samsung.com> 6 * 7 * Implementation: 8 * Emulate the pseudo BufferRAM 9 * 10 * See file CREDITS for list of people who contributed to this 11 * project. 12 * 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. 17 * 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. 22 * 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, 26 * MA 02111-1307 USA 27 */ 28 29 #include <common.h> 30 #include <malloc.h> 31 #include <linux/compat.h> 32 #include <linux/mtd/mtd.h> 33 #include <linux/mtd/onenand.h> 34 #include <linux/mtd/samsung_onenand.h> 35 36 #include <asm/io.h> 37 #include <asm/errno.h> 38 39 #ifdef ONENAND_DEBUG 40 #define DPRINTK(format, args...) \ 41 do { \ 42 printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \ 43 } while (0) 44 #else 45 #define DPRINTK(...) do { } while (0) 46 #endif 47 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 64 65 #if defined(CONFIG_S5P) 66 #define MAP_00 (0x0 << 26) 67 #define MAP_01 (0x1 << 26) 68 #define MAP_10 (0x2 << 26) 69 #define MAP_11 (0x3 << 26) 70 #endif 71 72 /* read/write of XIP buffer */ 73 #define CMD_MAP_00(mem_addr) (MAP_00 | ((mem_addr) << 1)) 74 /* read/write to the memory device */ 75 #define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr)) 76 /* control special functions of the memory device */ 77 #define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr)) 78 /* direct interface(direct access) with the memory device */ 79 #define CMD_MAP_11(mem_addr) (MAP_11 | ((mem_addr) << 2)) 80 81 struct s3c_onenand { 82 struct mtd_info *mtd; 83 void __iomem *base; 84 void __iomem *ahb_addr; 85 int bootram_command; 86 void __iomem *page_buf; 87 void __iomem *oob_buf; 88 unsigned int (*mem_addr)(int fba, int fpa, int fsa); 89 struct samsung_onenand *reg; 90 }; 91 92 static struct s3c_onenand *onenand; 93 94 static int s3c_read_cmd(unsigned int cmd) 95 { 96 return readl(onenand->ahb_addr + cmd); 97 } 98 99 static void s3c_write_cmd(int value, unsigned int cmd) 100 { 101 writel(value, onenand->ahb_addr + cmd); 102 } 103 104 /* 105 * MEM_ADDR 106 * 107 * fba: flash block address 108 * fpa: flash page address 109 * fsa: flash sector address 110 * 111 * return the buffer address on the memory device 112 * It will be combined with CMD_MAP_XX 113 */ 114 #if defined(CONFIG_S5P) 115 static unsigned int s3c_mem_addr(int fba, int fpa, int fsa) 116 { 117 return (fba << 13) | (fpa << 7) | (fsa << 5); 118 } 119 #endif 120 121 static void s3c_onenand_reset(void) 122 { 123 unsigned long timeout = 0x10000; 124 int stat; 125 126 writel(ONENAND_MEM_RESET_COLD, &onenand->reg->mem_reset); 127 while (timeout--) { 128 stat = readl(&onenand->reg->int_err_stat); 129 if (stat & RST_CMP) 130 break; 131 } 132 stat = readl(&onenand->reg->int_err_stat); 133 writel(stat, &onenand->reg->int_err_ack); 134 135 /* Clear interrupt */ 136 writel(0x0, &onenand->reg->int_err_ack); 137 /* Clear the ECC status */ 138 writel(0x0, &onenand->reg->ecc_err_stat); 139 } 140 141 static unsigned short s3c_onenand_readw(void __iomem *addr) 142 { 143 struct onenand_chip *this = onenand->mtd->priv; 144 int reg = addr - this->base; 145 int word_addr = reg >> 1; 146 int value; 147 148 /* It's used for probing time */ 149 switch (reg) { 150 case ONENAND_REG_MANUFACTURER_ID: 151 return readl(&onenand->reg->manufact_id); 152 case ONENAND_REG_DEVICE_ID: 153 return readl(&onenand->reg->device_id); 154 case ONENAND_REG_VERSION_ID: 155 return readl(&onenand->reg->flash_ver_id); 156 case ONENAND_REG_DATA_BUFFER_SIZE: 157 return readl(&onenand->reg->data_buf_size); 158 case ONENAND_REG_TECHNOLOGY: 159 return readl(&onenand->reg->tech); 160 case ONENAND_REG_SYS_CFG1: 161 return readl(&onenand->reg->mem_cfg); 162 163 /* Used at unlock all status */ 164 case ONENAND_REG_CTRL_STATUS: 165 return 0; 166 167 case ONENAND_REG_WP_STATUS: 168 return ONENAND_WP_US; 169 170 default: 171 break; 172 } 173 174 /* BootRAM access control */ 175 if (reg < ONENAND_DATARAM && onenand->bootram_command) { 176 if (word_addr == 0) 177 return readl(&onenand->reg->manufact_id); 178 if (word_addr == 1) 179 return readl(&onenand->reg->device_id); 180 if (word_addr == 2) 181 return readl(&onenand->reg->flash_ver_id); 182 } 183 184 value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff; 185 printk(KERN_INFO "s3c_onenand_readw: Illegal access" 186 " at reg 0x%x, value 0x%x\n", word_addr, value); 187 return value; 188 } 189 190 static void s3c_onenand_writew(unsigned short value, void __iomem *addr) 191 { 192 struct onenand_chip *this = onenand->mtd->priv; 193 int reg = addr - this->base; 194 int word_addr = reg >> 1; 195 196 /* It's used for probing time */ 197 switch (reg) { 198 case ONENAND_REG_SYS_CFG1: 199 writel(value, &onenand->reg->mem_cfg); 200 return; 201 202 case ONENAND_REG_START_ADDRESS1: 203 case ONENAND_REG_START_ADDRESS2: 204 return; 205 206 /* Lock/lock-tight/unlock/unlock_all */ 207 case ONENAND_REG_START_BLOCK_ADDRESS: 208 return; 209 210 default: 211 break; 212 } 213 214 /* BootRAM access control */ 215 if (reg < ONENAND_DATARAM) { 216 if (value == ONENAND_CMD_READID) { 217 onenand->bootram_command = 1; 218 return; 219 } 220 if (value == ONENAND_CMD_RESET) { 221 writel(ONENAND_MEM_RESET_COLD, 222 &onenand->reg->mem_reset); 223 onenand->bootram_command = 0; 224 return; 225 } 226 } 227 228 printk(KERN_INFO "s3c_onenand_writew: Illegal access" 229 " at reg 0x%x, value 0x%x\n", word_addr, value); 230 231 s3c_write_cmd(value, CMD_MAP_11(word_addr)); 232 } 233 234 static int s3c_onenand_wait(struct mtd_info *mtd, int state) 235 { 236 unsigned int flags = INT_ACT; 237 unsigned int stat, ecc; 238 unsigned long timeout = 0x100000; 239 240 switch (state) { 241 case FL_READING: 242 flags |= BLK_RW_CMP | LOAD_CMP; 243 break; 244 case FL_WRITING: 245 flags |= BLK_RW_CMP | PGM_CMP; 246 break; 247 case FL_ERASING: 248 flags |= BLK_RW_CMP | ERS_CMP; 249 break; 250 case FL_LOCKING: 251 flags |= BLK_RW_CMP; 252 break; 253 default: 254 break; 255 } 256 257 while (timeout--) { 258 stat = readl(&onenand->reg->int_err_stat); 259 if (stat & flags) 260 break; 261 } 262 263 /* To get correct interrupt status in timeout case */ 264 stat = readl(&onenand->reg->int_err_stat); 265 writel(stat, &onenand->reg->int_err_ack); 266 267 /* 268 * In the Spec. it checks the controller status first 269 * However if you get the correct information in case of 270 * power off recovery (POR) test, it should read ECC status first 271 */ 272 if (stat & LOAD_CMP) { 273 ecc = readl(&onenand->reg->ecc_err_stat); 274 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) { 275 printk(KERN_INFO "%s: ECC error = 0x%04x\n", 276 __func__, ecc); 277 mtd->ecc_stats.failed++; 278 return -EBADMSG; 279 } 280 } 281 282 if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) { 283 printk(KERN_INFO "%s: controller error = 0x%04x\n", 284 __func__, stat); 285 if (stat & LOCKED_BLK) 286 printk(KERN_INFO "%s: it's locked error = 0x%04x\n", 287 __func__, stat); 288 289 return -EIO; 290 } 291 292 return 0; 293 } 294 295 static int s3c_onenand_command(struct mtd_info *mtd, int cmd, 296 loff_t addr, size_t len) 297 { 298 struct onenand_chip *this = mtd->priv; 299 unsigned int *m, *s; 300 int fba, fpa, fsa = 0; 301 unsigned int mem_addr; 302 int i, mcount, scount; 303 int index; 304 305 fba = (int) (addr >> this->erase_shift); 306 fpa = (int) (addr >> this->page_shift); 307 fpa &= this->page_mask; 308 309 mem_addr = onenand->mem_addr(fba, fpa, fsa); 310 311 switch (cmd) { 312 case ONENAND_CMD_READ: 313 case ONENAND_CMD_READOOB: 314 case ONENAND_CMD_BUFFERRAM: 315 ONENAND_SET_NEXT_BUFFERRAM(this); 316 default: 317 break; 318 } 319 320 index = ONENAND_CURRENT_BUFFERRAM(this); 321 322 /* 323 * Emulate Two BufferRAMs and access with 4 bytes pointer 324 */ 325 m = (unsigned int *) onenand->page_buf; 326 s = (unsigned int *) onenand->oob_buf; 327 328 if (index) { 329 m += (this->writesize >> 2); 330 s += (mtd->oobsize >> 2); 331 } 332 333 mcount = mtd->writesize >> 2; 334 scount = mtd->oobsize >> 2; 335 336 switch (cmd) { 337 case ONENAND_CMD_READ: 338 /* Main */ 339 for (i = 0; i < mcount; i++) 340 *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr)); 341 return 0; 342 343 case ONENAND_CMD_READOOB: 344 writel(TSRF, &onenand->reg->trans_spare); 345 /* Main */ 346 for (i = 0; i < mcount; i++) 347 *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr)); 348 349 /* Spare */ 350 for (i = 0; i < scount; i++) 351 *s++ = s3c_read_cmd(CMD_MAP_01(mem_addr)); 352 353 writel(0, &onenand->reg->trans_spare); 354 return 0; 355 356 case ONENAND_CMD_PROG: 357 /* Main */ 358 for (i = 0; i < mcount; i++) 359 s3c_write_cmd(*m++, CMD_MAP_01(mem_addr)); 360 return 0; 361 362 case ONENAND_CMD_PROGOOB: 363 writel(TSRF, &onenand->reg->trans_spare); 364 365 /* Main - dummy write */ 366 for (i = 0; i < mcount; i++) 367 s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr)); 368 369 /* Spare */ 370 for (i = 0; i < scount; i++) 371 s3c_write_cmd(*s++, CMD_MAP_01(mem_addr)); 372 373 writel(0, &onenand->reg->trans_spare); 374 return 0; 375 376 case ONENAND_CMD_UNLOCK_ALL: 377 s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr)); 378 return 0; 379 380 case ONENAND_CMD_ERASE: 381 s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr)); 382 return 0; 383 384 case ONENAND_CMD_MULTIBLOCK_ERASE: 385 s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr)); 386 return 0; 387 388 case ONENAND_CMD_ERASE_VERIFY: 389 s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr)); 390 return 0; 391 392 default: 393 break; 394 } 395 396 return 0; 397 } 398 399 static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area) 400 { 401 struct onenand_chip *this = mtd->priv; 402 int index = ONENAND_CURRENT_BUFFERRAM(this); 403 unsigned char *p; 404 405 if (area == ONENAND_DATARAM) { 406 p = (unsigned char *) onenand->page_buf; 407 if (index == 1) 408 p += this->writesize; 409 } else { 410 p = (unsigned char *) onenand->oob_buf; 411 if (index == 1) 412 p += mtd->oobsize; 413 } 414 415 return p; 416 } 417 418 static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area, 419 unsigned char *buffer, int offset, 420 size_t count) 421 { 422 unsigned char *p; 423 424 p = s3c_get_bufferram(mtd, area); 425 memcpy(buffer, p + offset, count); 426 return 0; 427 } 428 429 static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area, 430 const unsigned char *buffer, int offset, 431 size_t count) 432 { 433 unsigned char *p; 434 435 p = s3c_get_bufferram(mtd, area); 436 memcpy(p + offset, buffer, count); 437 return 0; 438 } 439 440 static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state) 441 { 442 struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base; 443 unsigned int flags = INT_ACT | LOAD_CMP; 444 unsigned int stat; 445 unsigned long timeout = 0x10000; 446 447 while (timeout--) { 448 stat = readl(®->int_err_stat); 449 if (stat & flags) 450 break; 451 } 452 /* To get correct interrupt status in timeout case */ 453 stat = readl(&onenand->reg->int_err_stat); 454 writel(stat, &onenand->reg->int_err_ack); 455 456 if (stat & LD_FAIL_ECC_ERR) { 457 s3c_onenand_reset(); 458 return ONENAND_BBT_READ_ERROR; 459 } 460 461 if (stat & LOAD_CMP) { 462 int ecc = readl(&onenand->reg->ecc_err_stat); 463 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) { 464 s3c_onenand_reset(); 465 return ONENAND_BBT_READ_ERROR; 466 } 467 } 468 469 return 0; 470 } 471 472 static void s3c_onenand_check_lock_status(struct mtd_info *mtd) 473 { 474 struct onenand_chip *this = mtd->priv; 475 unsigned int block, end; 476 477 end = this->chipsize >> this->erase_shift; 478 479 for (block = 0; block < end; block++) { 480 s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0))); 481 482 if (readl(&onenand->reg->int_err_stat) & LOCKED_BLK) { 483 printf("block %d is write-protected!\n", block); 484 writel(LOCKED_BLK, &onenand->reg->int_err_ack); 485 } 486 } 487 } 488 489 static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, 490 size_t len, int cmd) 491 { 492 struct onenand_chip *this = mtd->priv; 493 int start, end, start_mem_addr, end_mem_addr; 494 495 start = ofs >> this->erase_shift; 496 start_mem_addr = onenand->mem_addr(start, 0, 0); 497 end = start + (len >> this->erase_shift) - 1; 498 end_mem_addr = onenand->mem_addr(end, 0, 0); 499 500 if (cmd == ONENAND_CMD_LOCK) { 501 s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr)); 502 s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr)); 503 } else { 504 s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr)); 505 s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr)); 506 } 507 508 this->wait(mtd, FL_LOCKING); 509 } 510 511 static void s3c_onenand_unlock_all(struct mtd_info *mtd) 512 { 513 struct onenand_chip *this = mtd->priv; 514 loff_t ofs = 0; 515 size_t len = this->chipsize; 516 517 /* FIXME workaround */ 518 this->subpagesize = mtd->writesize; 519 mtd->subpage_sft = 0; 520 521 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 522 /* Write unlock command */ 523 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); 524 525 /* No need to check return value */ 526 this->wait(mtd, FL_LOCKING); 527 528 /* Workaround for all block unlock in DDP */ 529 if (!ONENAND_IS_DDP(this)) { 530 s3c_onenand_check_lock_status(mtd); 531 return; 532 } 533 534 /* All blocks on another chip */ 535 ofs = this->chipsize >> 1; 536 len = this->chipsize >> 1; 537 } 538 539 s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); 540 s3c_onenand_check_lock_status(mtd); 541 } 542 543 int s5pc110_chip_probe(struct mtd_info *mtd) 544 { 545 return 0; 546 } 547 548 int s5pc210_chip_probe(struct mtd_info *mtd) 549 { 550 return 0; 551 } 552 553 void s3c_onenand_init(struct mtd_info *mtd) 554 { 555 struct onenand_chip *this = mtd->priv; 556 u32 size = (4 << 10); /* 4 KiB */ 557 558 onenand = malloc(sizeof(struct s3c_onenand)); 559 if (!onenand) 560 return; 561 562 onenand->page_buf = malloc(size * sizeof(char)); 563 if (!onenand->page_buf) 564 return; 565 memset(onenand->page_buf, 0xff, size); 566 567 onenand->oob_buf = malloc(128 * sizeof(char)); 568 if (!onenand->oob_buf) 569 return; 570 memset(onenand->oob_buf, 0xff, 128); 571 572 onenand->mtd = mtd; 573 574 #if defined(CONFIG_S5P) 575 onenand->base = (void *)0xE7100000; 576 onenand->ahb_addr = (void *)0xB0000000; 577 #endif 578 onenand->mem_addr = s3c_mem_addr; 579 onenand->reg = (struct samsung_onenand *)onenand->base; 580 581 this->read_word = s3c_onenand_readw; 582 this->write_word = s3c_onenand_writew; 583 584 this->wait = s3c_onenand_wait; 585 this->bbt_wait = s3c_onenand_bbt_wait; 586 this->unlock_all = s3c_onenand_unlock_all; 587 this->command = s3c_onenand_command; 588 589 this->read_bufferram = onenand_read_bufferram; 590 this->write_bufferram = onenand_write_bufferram; 591 592 this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK; 593 } 594