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