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