1/* 2 * Samsung S3C64XX/S5PC1XX OneNAND driver 3 * 4 * Copyright �� 2008-2010 Samsung Electronics 5 * Kyungmin Park <kyungmin.park@samsung.com> 6 * Marek Szyprowski <m.szyprowski@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * Implementation: 13 * S3C64XX and S5PC100: emulate the pseudo BufferRAM 14 * S5PC110: use DMA 15 */ 16 17#include <linux/module.h> 18#include <linux/platform_device.h> 19#include <linux/sched.h> 20#include <linux/slab.h> 21#include <linux/mtd/mtd.h> 22#include <linux/mtd/onenand.h> 23#include <linux/mtd/partitions.h> 24#include <linux/dma-mapping.h> 25 26#include <asm/mach/flash.h> 27#include <plat/regs-onenand.h> 28 29#include <linux/io.h> 30 31enum soc_type { 32 TYPE_S3C6400, 33 TYPE_S3C6410, 34 TYPE_S5PC100, 35 TYPE_S5PC110, 36}; 37 38#define ONENAND_ERASE_STATUS 0x00 39#define ONENAND_MULTI_ERASE_SET 0x01 40#define ONENAND_ERASE_START 0x03 41#define ONENAND_UNLOCK_START 0x08 42#define ONENAND_UNLOCK_END 0x09 43#define ONENAND_LOCK_START 0x0A 44#define ONENAND_LOCK_END 0x0B 45#define ONENAND_LOCK_TIGHT_START 0x0C 46#define ONENAND_LOCK_TIGHT_END 0x0D 47#define ONENAND_UNLOCK_ALL 0x0E 48#define ONENAND_OTP_ACCESS 0x12 49#define ONENAND_SPARE_ACCESS_ONLY 0x13 50#define ONENAND_MAIN_ACCESS_ONLY 0x14 51#define ONENAND_ERASE_VERIFY 0x15 52#define ONENAND_MAIN_SPARE_ACCESS 0x16 53#define ONENAND_PIPELINE_READ 0x4000 54 55#define MAP_00 (0x0) 56#define MAP_01 (0x1) 57#define MAP_10 (0x2) 58#define MAP_11 (0x3) 59 60#define S3C64XX_CMD_MAP_SHIFT 24 61#define S5PC1XX_CMD_MAP_SHIFT 26 62 63#define S3C6400_FBA_SHIFT 10 64#define S3C6400_FPA_SHIFT 4 65#define S3C6400_FSA_SHIFT 2 66 67#define S3C6410_FBA_SHIFT 12 68#define S3C6410_FPA_SHIFT 6 69#define S3C6410_FSA_SHIFT 4 70 71#define S5PC100_FBA_SHIFT 13 72#define S5PC100_FPA_SHIFT 7 73#define S5PC100_FSA_SHIFT 5 74 75/* S5PC110 specific definitions */ 76#define S5PC110_DMA_SRC_ADDR 0x400 77#define S5PC110_DMA_SRC_CFG 0x404 78#define S5PC110_DMA_DST_ADDR 0x408 79#define S5PC110_DMA_DST_CFG 0x40C 80#define S5PC110_DMA_TRANS_SIZE 0x414 81#define S5PC110_DMA_TRANS_CMD 0x418 82#define S5PC110_DMA_TRANS_STATUS 0x41C 83#define S5PC110_DMA_TRANS_DIR 0x420 84 85#define S5PC110_DMA_CFG_SINGLE (0x0 << 16) 86#define S5PC110_DMA_CFG_4BURST (0x2 << 16) 87#define S5PC110_DMA_CFG_8BURST (0x3 << 16) 88#define S5PC110_DMA_CFG_16BURST (0x4 << 16) 89 90#define S5PC110_DMA_CFG_INC (0x0 << 8) 91#define S5PC110_DMA_CFG_CNT (0x1 << 8) 92 93#define S5PC110_DMA_CFG_8BIT (0x0 << 0) 94#define S5PC110_DMA_CFG_16BIT (0x1 << 0) 95#define S5PC110_DMA_CFG_32BIT (0x2 << 0) 96 97#define S5PC110_DMA_SRC_CFG_READ (S5PC110_DMA_CFG_16BURST | \ 98 S5PC110_DMA_CFG_INC | \ 99 S5PC110_DMA_CFG_16BIT) 100#define S5PC110_DMA_DST_CFG_READ (S5PC110_DMA_CFG_16BURST | \ 101 S5PC110_DMA_CFG_INC | \ 102 S5PC110_DMA_CFG_32BIT) 103#define S5PC110_DMA_SRC_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \ 104 S5PC110_DMA_CFG_INC | \ 105 S5PC110_DMA_CFG_32BIT) 106#define S5PC110_DMA_DST_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \ 107 S5PC110_DMA_CFG_INC | \ 108 S5PC110_DMA_CFG_16BIT) 109 110#define S5PC110_DMA_TRANS_CMD_TDC (0x1 << 18) 111#define S5PC110_DMA_TRANS_CMD_TEC (0x1 << 16) 112#define S5PC110_DMA_TRANS_CMD_TR (0x1 << 0) 113 114#define S5PC110_DMA_TRANS_STATUS_TD (0x1 << 18) 115#define S5PC110_DMA_TRANS_STATUS_TB (0x1 << 17) 116#define S5PC110_DMA_TRANS_STATUS_TE (0x1 << 16) 117 118#define S5PC110_DMA_DIR_READ 0x0 119#define S5PC110_DMA_DIR_WRITE 0x1 120 121struct s3c_onenand { 122 struct mtd_info *mtd; 123 struct platform_device *pdev; 124 enum soc_type type; 125 void __iomem *base; 126 struct resource *base_res; 127 void __iomem *ahb_addr; 128 struct resource *ahb_res; 129 int bootram_command; 130 void __iomem *page_buf; 131 void __iomem *oob_buf; 132 unsigned int (*mem_addr)(int fba, int fpa, int fsa); 133 unsigned int (*cmd_map)(unsigned int type, unsigned int val); 134 void __iomem *dma_addr; 135 struct resource *dma_res; 136 unsigned long phys_base; 137#ifdef CONFIG_MTD_PARTITIONS 138 struct mtd_partition *parts; 139#endif 140}; 141 142#define CMD_MAP_00(dev, addr) (dev->cmd_map(MAP_00, ((addr) << 1))) 143#define CMD_MAP_01(dev, mem_addr) (dev->cmd_map(MAP_01, (mem_addr))) 144#define CMD_MAP_10(dev, mem_addr) (dev->cmd_map(MAP_10, (mem_addr))) 145#define CMD_MAP_11(dev, addr) (dev->cmd_map(MAP_11, ((addr) << 2))) 146 147static struct s3c_onenand *onenand; 148 149#ifdef CONFIG_MTD_PARTITIONS 150static const char *part_probes[] = { "cmdlinepart", NULL, }; 151#endif 152 153static inline int s3c_read_reg(int offset) 154{ 155 return readl(onenand->base + offset); 156} 157 158static inline void s3c_write_reg(int value, int offset) 159{ 160 writel(value, onenand->base + offset); 161} 162 163static inline int s3c_read_cmd(unsigned int cmd) 164{ 165 return readl(onenand->ahb_addr + cmd); 166} 167 168static inline void s3c_write_cmd(int value, unsigned int cmd) 169{ 170 writel(value, onenand->ahb_addr + cmd); 171} 172 173#ifdef SAMSUNG_DEBUG 174static void s3c_dump_reg(void) 175{ 176 int i; 177 178 for (i = 0; i < 0x400; i += 0x40) { 179 printk(KERN_INFO "0x%08X: 0x%08x 0x%08x 0x%08x 0x%08x\n", 180 (unsigned int) onenand->base + i, 181 s3c_read_reg(i), s3c_read_reg(i + 0x10), 182 s3c_read_reg(i + 0x20), s3c_read_reg(i + 0x30)); 183 } 184} 185#endif 186 187static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val) 188{ 189 return (type << S3C64XX_CMD_MAP_SHIFT) | val; 190} 191 192static unsigned int s5pc1xx_cmd_map(unsigned type, unsigned val) 193{ 194 return (type << S5PC1XX_CMD_MAP_SHIFT) | val; 195} 196 197static unsigned int s3c6400_mem_addr(int fba, int fpa, int fsa) 198{ 199 return (fba << S3C6400_FBA_SHIFT) | (fpa << S3C6400_FPA_SHIFT) | 200 (fsa << S3C6400_FSA_SHIFT); 201} 202 203static unsigned int s3c6410_mem_addr(int fba, int fpa, int fsa) 204{ 205 return (fba << S3C6410_FBA_SHIFT) | (fpa << S3C6410_FPA_SHIFT) | 206 (fsa << S3C6410_FSA_SHIFT); 207} 208 209static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa) 210{ 211 return (fba << S5PC100_FBA_SHIFT) | (fpa << S5PC100_FPA_SHIFT) | 212 (fsa << S5PC100_FSA_SHIFT); 213} 214 215static void s3c_onenand_reset(void) 216{ 217 unsigned long timeout = 0x10000; 218 int stat; 219 220 s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET); 221 while (1 && timeout--) { 222 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 223 if (stat & RST_CMP) 224 break; 225 } 226 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 227 s3c_write_reg(stat, INT_ERR_ACK_OFFSET); 228 229 /* Clear interrupt */ 230 s3c_write_reg(0x0, INT_ERR_ACK_OFFSET); 231 /* Clear the ECC status */ 232 s3c_write_reg(0x0, ECC_ERR_STAT_OFFSET); 233} 234 235static unsigned short s3c_onenand_readw(void __iomem *addr) 236{ 237 struct onenand_chip *this = onenand->mtd->priv; 238 struct device *dev = &onenand->pdev->dev; 239 int reg = addr - this->base; 240 int word_addr = reg >> 1; 241 int value; 242 243 /* It's used for probing time */ 244 switch (reg) { 245 case ONENAND_REG_MANUFACTURER_ID: 246 return s3c_read_reg(MANUFACT_ID_OFFSET); 247 case ONENAND_REG_DEVICE_ID: 248 return s3c_read_reg(DEVICE_ID_OFFSET); 249 case ONENAND_REG_VERSION_ID: 250 return s3c_read_reg(FLASH_VER_ID_OFFSET); 251 case ONENAND_REG_DATA_BUFFER_SIZE: 252 return s3c_read_reg(DATA_BUF_SIZE_OFFSET); 253 case ONENAND_REG_TECHNOLOGY: 254 return s3c_read_reg(TECH_OFFSET); 255 case ONENAND_REG_SYS_CFG1: 256 return s3c_read_reg(MEM_CFG_OFFSET); 257 258 /* Used at unlock all status */ 259 case ONENAND_REG_CTRL_STATUS: 260 return 0; 261 262 case ONENAND_REG_WP_STATUS: 263 return ONENAND_WP_US; 264 265 default: 266 break; 267 } 268 269 /* BootRAM access control */ 270 if ((unsigned int) addr < ONENAND_DATARAM && onenand->bootram_command) { 271 if (word_addr == 0) 272 return s3c_read_reg(MANUFACT_ID_OFFSET); 273 if (word_addr == 1) 274 return s3c_read_reg(DEVICE_ID_OFFSET); 275 if (word_addr == 2) 276 return s3c_read_reg(FLASH_VER_ID_OFFSET); 277 } 278 279 value = s3c_read_cmd(CMD_MAP_11(onenand, word_addr)) & 0xffff; 280 dev_info(dev, "%s: Illegal access at reg 0x%x, value 0x%x\n", __func__, 281 word_addr, value); 282 return value; 283} 284 285static void s3c_onenand_writew(unsigned short value, void __iomem *addr) 286{ 287 struct onenand_chip *this = onenand->mtd->priv; 288 struct device *dev = &onenand->pdev->dev; 289 unsigned int reg = addr - this->base; 290 unsigned int word_addr = reg >> 1; 291 292 /* It's used for probing time */ 293 switch (reg) { 294 case ONENAND_REG_SYS_CFG1: 295 s3c_write_reg(value, MEM_CFG_OFFSET); 296 return; 297 298 case ONENAND_REG_START_ADDRESS1: 299 case ONENAND_REG_START_ADDRESS2: 300 return; 301 302 /* Lock/lock-tight/unlock/unlock_all */ 303 case ONENAND_REG_START_BLOCK_ADDRESS: 304 return; 305 306 default: 307 break; 308 } 309 310 /* BootRAM access control */ 311 if ((unsigned int)addr < ONENAND_DATARAM) { 312 if (value == ONENAND_CMD_READID) { 313 onenand->bootram_command = 1; 314 return; 315 } 316 if (value == ONENAND_CMD_RESET) { 317 s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET); 318 onenand->bootram_command = 0; 319 return; 320 } 321 } 322 323 dev_info(dev, "%s: Illegal access at reg 0x%x, value 0x%x\n", __func__, 324 word_addr, value); 325 326 s3c_write_cmd(value, CMD_MAP_11(onenand, word_addr)); 327} 328 329static int s3c_onenand_wait(struct mtd_info *mtd, int state) 330{ 331 struct device *dev = &onenand->pdev->dev; 332 unsigned int flags = INT_ACT; 333 unsigned int stat, ecc; 334 unsigned long timeout; 335 336 switch (state) { 337 case FL_READING: 338 flags |= BLK_RW_CMP | LOAD_CMP; 339 break; 340 case FL_WRITING: 341 flags |= BLK_RW_CMP | PGM_CMP; 342 break; 343 case FL_ERASING: 344 flags |= BLK_RW_CMP | ERS_CMP; 345 break; 346 case FL_LOCKING: 347 flags |= BLK_RW_CMP; 348 break; 349 default: 350 break; 351 } 352 353 /* The 20 msec is enough */ 354 timeout = jiffies + msecs_to_jiffies(20); 355 while (time_before(jiffies, timeout)) { 356 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 357 if (stat & flags) 358 break; 359 360 if (state != FL_READING) 361 cond_resched(); 362 } 363 /* To get correct interrupt status in timeout case */ 364 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 365 s3c_write_reg(stat, INT_ERR_ACK_OFFSET); 366 367 /* 368 * In the Spec. it checks the controller status first 369 * However if you get the correct information in case of 370 * power off recovery (POR) test, it should read ECC status first 371 */ 372 if (stat & LOAD_CMP) { 373 ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET); 374 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) { 375 dev_info(dev, "%s: ECC error = 0x%04x\n", __func__, 376 ecc); 377 mtd->ecc_stats.failed++; 378 return -EBADMSG; 379 } 380 } 381 382 if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) { 383 dev_info(dev, "%s: controller error = 0x%04x\n", __func__, 384 stat); 385 if (stat & LOCKED_BLK) 386 dev_info(dev, "%s: it's locked error = 0x%04x\n", 387 __func__, stat); 388 389 return -EIO; 390 } 391 392 return 0; 393} 394 395static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, 396 size_t len) 397{ 398 struct onenand_chip *this = mtd->priv; 399 unsigned int *m, *s; 400 int fba, fpa, fsa = 0; 401 unsigned int mem_addr, cmd_map_01, cmd_map_10; 402 int i, mcount, scount; 403 int index; 404 405 fba = (int) (addr >> this->erase_shift); 406 fpa = (int) (addr >> this->page_shift); 407 fpa &= this->page_mask; 408 409 mem_addr = onenand->mem_addr(fba, fpa, fsa); 410 cmd_map_01 = CMD_MAP_01(onenand, mem_addr); 411 cmd_map_10 = CMD_MAP_10(onenand, mem_addr); 412 413 switch (cmd) { 414 case ONENAND_CMD_READ: 415 case ONENAND_CMD_READOOB: 416 case ONENAND_CMD_BUFFERRAM: 417 ONENAND_SET_NEXT_BUFFERRAM(this); 418 default: 419 break; 420 } 421 422 index = ONENAND_CURRENT_BUFFERRAM(this); 423 424 /* 425 * Emulate Two BufferRAMs and access with 4 bytes pointer 426 */ 427 m = (unsigned int *) onenand->page_buf; 428 s = (unsigned int *) onenand->oob_buf; 429 430 if (index) { 431 m += (this->writesize >> 2); 432 s += (mtd->oobsize >> 2); 433 } 434 435 mcount = mtd->writesize >> 2; 436 scount = mtd->oobsize >> 2; 437 438 switch (cmd) { 439 case ONENAND_CMD_READ: 440 /* Main */ 441 for (i = 0; i < mcount; i++) 442 *m++ = s3c_read_cmd(cmd_map_01); 443 return 0; 444 445 case ONENAND_CMD_READOOB: 446 s3c_write_reg(TSRF, TRANS_SPARE_OFFSET); 447 /* Main */ 448 for (i = 0; i < mcount; i++) 449 *m++ = s3c_read_cmd(cmd_map_01); 450 451 /* Spare */ 452 for (i = 0; i < scount; i++) 453 *s++ = s3c_read_cmd(cmd_map_01); 454 455 s3c_write_reg(0, TRANS_SPARE_OFFSET); 456 return 0; 457 458 case ONENAND_CMD_PROG: 459 /* Main */ 460 for (i = 0; i < mcount; i++) 461 s3c_write_cmd(*m++, cmd_map_01); 462 return 0; 463 464 case ONENAND_CMD_PROGOOB: 465 s3c_write_reg(TSRF, TRANS_SPARE_OFFSET); 466 467 /* Main - dummy write */ 468 for (i = 0; i < mcount; i++) 469 s3c_write_cmd(0xffffffff, cmd_map_01); 470 471 /* Spare */ 472 for (i = 0; i < scount; i++) 473 s3c_write_cmd(*s++, cmd_map_01); 474 475 s3c_write_reg(0, TRANS_SPARE_OFFSET); 476 return 0; 477 478 case ONENAND_CMD_UNLOCK_ALL: 479 s3c_write_cmd(ONENAND_UNLOCK_ALL, cmd_map_10); 480 return 0; 481 482 case ONENAND_CMD_ERASE: 483 s3c_write_cmd(ONENAND_ERASE_START, cmd_map_10); 484 return 0; 485 486 default: 487 break; 488 } 489 490 return 0; 491} 492 493static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area) 494{ 495 struct onenand_chip *this = mtd->priv; 496 int index = ONENAND_CURRENT_BUFFERRAM(this); 497 unsigned char *p; 498 499 if (area == ONENAND_DATARAM) { 500 p = (unsigned char *) onenand->page_buf; 501 if (index == 1) 502 p += this->writesize; 503 } else { 504 p = (unsigned char *) onenand->oob_buf; 505 if (index == 1) 506 p += mtd->oobsize; 507 } 508 509 return p; 510} 511 512static int onenand_read_bufferram(struct mtd_info *mtd, int area, 513 unsigned char *buffer, int offset, 514 size_t count) 515{ 516 unsigned char *p; 517 518 p = s3c_get_bufferram(mtd, area); 519 memcpy(buffer, p + offset, count); 520 return 0; 521} 522 523static int onenand_write_bufferram(struct mtd_info *mtd, int area, 524 const unsigned char *buffer, int offset, 525 size_t count) 526{ 527 unsigned char *p; 528 529 p = s3c_get_bufferram(mtd, area); 530 memcpy(p + offset, buffer, count); 531 return 0; 532} 533 534static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction) 535{ 536 void __iomem *base = onenand->dma_addr; 537 int status; 538 539 writel(src, base + S5PC110_DMA_SRC_ADDR); 540 writel(dst, base + S5PC110_DMA_DST_ADDR); 541 542 if (direction == S5PC110_DMA_DIR_READ) { 543 writel(S5PC110_DMA_SRC_CFG_READ, base + S5PC110_DMA_SRC_CFG); 544 writel(S5PC110_DMA_DST_CFG_READ, base + S5PC110_DMA_DST_CFG); 545 } else { 546 writel(S5PC110_DMA_SRC_CFG_WRITE, base + S5PC110_DMA_SRC_CFG); 547 writel(S5PC110_DMA_DST_CFG_WRITE, base + S5PC110_DMA_DST_CFG); 548 } 549 550 writel(count, base + S5PC110_DMA_TRANS_SIZE); 551 writel(direction, base + S5PC110_DMA_TRANS_DIR); 552 553 writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD); 554 555 do { 556 status = readl(base + S5PC110_DMA_TRANS_STATUS); 557 if (status & S5PC110_DMA_TRANS_STATUS_TE) { 558 writel(S5PC110_DMA_TRANS_CMD_TEC, 559 base + S5PC110_DMA_TRANS_CMD); 560 return -EIO; 561 } 562 } while (!(status & S5PC110_DMA_TRANS_STATUS_TD)); 563 564 writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); 565 566 return 0; 567} 568 569static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, 570 unsigned char *buffer, int offset, size_t count) 571{ 572 struct onenand_chip *this = mtd->priv; 573 void __iomem *p; 574 void *buf = (void *) buffer; 575 dma_addr_t dma_src, dma_dst; 576 int err; 577 578 p = this->base + area; 579 if (ONENAND_CURRENT_BUFFERRAM(this)) { 580 if (area == ONENAND_DATARAM) 581 p += this->writesize; 582 else 583 p += mtd->oobsize; 584 } 585 586 if (offset & 3 || (size_t) buf & 3 || 587 !onenand->dma_addr || count != mtd->writesize) 588 goto normal; 589 590 /* Handle vmalloc address */ 591 if (buf >= high_memory) { 592 struct page *page; 593 594 if (((size_t) buf & PAGE_MASK) != 595 ((size_t) (buf + count - 1) & PAGE_MASK)) 596 goto normal; 597 page = vmalloc_to_page(buf); 598 if (!page) 599 goto normal; 600 buf = page_address(page) + ((size_t) buf & ~PAGE_MASK); 601 } 602 603 /* DMA routine */ 604 dma_src = onenand->phys_base + (p - this->base); 605 dma_dst = dma_map_single(&onenand->pdev->dev, 606 buf, count, DMA_FROM_DEVICE); 607 if (dma_mapping_error(&onenand->pdev->dev, dma_dst)) { 608 dev_err(&onenand->pdev->dev, 609 "Couldn't map a %d byte buffer for DMA\n", count); 610 goto normal; 611 } 612 err = s5pc110_dma_ops((void *) dma_dst, (void *) dma_src, 613 count, S5PC110_DMA_DIR_READ); 614 dma_unmap_single(&onenand->pdev->dev, dma_dst, count, DMA_FROM_DEVICE); 615 616 if (!err) 617 return 0; 618 619normal: 620 if (count != mtd->writesize) { 621 /* Copy the bufferram to memory to prevent unaligned access */ 622 memcpy(this->page_buf, p, mtd->writesize); 623 p = this->page_buf + offset; 624 } 625 626 memcpy(buffer, p, count); 627 628 return 0; 629} 630 631static int s5pc110_chip_probe(struct mtd_info *mtd) 632{ 633 /* Now just return 0 */ 634 return 0; 635} 636 637static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state) 638{ 639 unsigned int flags = INT_ACT | LOAD_CMP; 640 unsigned int stat; 641 unsigned long timeout; 642 643 /* The 20 msec is enough */ 644 timeout = jiffies + msecs_to_jiffies(20); 645 while (time_before(jiffies, timeout)) { 646 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 647 if (stat & flags) 648 break; 649 } 650 /* To get correct interrupt status in timeout case */ 651 stat = s3c_read_reg(INT_ERR_STAT_OFFSET); 652 s3c_write_reg(stat, INT_ERR_ACK_OFFSET); 653 654 if (stat & LD_FAIL_ECC_ERR) { 655 s3c_onenand_reset(); 656 return ONENAND_BBT_READ_ERROR; 657 } 658 659 if (stat & LOAD_CMP) { 660 int ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET); 661 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) { 662 s3c_onenand_reset(); 663 return ONENAND_BBT_READ_ERROR; 664 } 665 } 666 667 return 0; 668} 669 670static void s3c_onenand_check_lock_status(struct mtd_info *mtd) 671{ 672 struct onenand_chip *this = mtd->priv; 673 struct device *dev = &onenand->pdev->dev; 674 unsigned int block, end; 675 int tmp; 676 677 end = this->chipsize >> this->erase_shift; 678 679 for (block = 0; block < end; block++) { 680 unsigned int mem_addr = onenand->mem_addr(block, 0, 0); 681 tmp = s3c_read_cmd(CMD_MAP_01(onenand, mem_addr)); 682 683 if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) { 684 dev_err(dev, "block %d is write-protected!\n", block); 685 s3c_write_reg(LOCKED_BLK, INT_ERR_ACK_OFFSET); 686 } 687 } 688} 689 690static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, 691 size_t len, int cmd) 692{ 693 struct onenand_chip *this = mtd->priv; 694 int start, end, start_mem_addr, end_mem_addr; 695 696 start = ofs >> this->erase_shift; 697 start_mem_addr = onenand->mem_addr(start, 0, 0); 698 end = start + (len >> this->erase_shift) - 1; 699 end_mem_addr = onenand->mem_addr(end, 0, 0); 700 701 if (cmd == ONENAND_CMD_LOCK) { 702 s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(onenand, 703 start_mem_addr)); 704 s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(onenand, 705 end_mem_addr)); 706 } else { 707 s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(onenand, 708 start_mem_addr)); 709 s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(onenand, 710 end_mem_addr)); 711 } 712 713 this->wait(mtd, FL_LOCKING); 714} 715 716static void s3c_unlock_all(struct mtd_info *mtd) 717{ 718 struct onenand_chip *this = mtd->priv; 719 loff_t ofs = 0; 720 size_t len = this->chipsize; 721 722 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 723 /* Write unlock command */ 724 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); 725 726 /* No need to check return value */ 727 this->wait(mtd, FL_LOCKING); 728 729 if (!ONENAND_IS_DDP(this)) { 730 s3c_onenand_check_lock_status(mtd); 731 return; 732 } 733 734 /* All blocks on another chip */ 735 ofs = this->chipsize >> 1; 736 len = this->chipsize >> 1; 737 } 738 739 s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); 740 741 s3c_onenand_check_lock_status(mtd); 742} 743 744static void s3c_onenand_setup(struct mtd_info *mtd) 745{ 746 struct onenand_chip *this = mtd->priv; 747 748 onenand->mtd = mtd; 749 750 if (onenand->type == TYPE_S3C6400) { 751 onenand->mem_addr = s3c6400_mem_addr; 752 onenand->cmd_map = s3c64xx_cmd_map; 753 } else if (onenand->type == TYPE_S3C6410) { 754 onenand->mem_addr = s3c6410_mem_addr; 755 onenand->cmd_map = s3c64xx_cmd_map; 756 } else if (onenand->type == TYPE_S5PC100) { 757 onenand->mem_addr = s5pc100_mem_addr; 758 onenand->cmd_map = s5pc1xx_cmd_map; 759 } else if (onenand->type == TYPE_S5PC110) { 760 /* Use generic onenand functions */ 761 onenand->cmd_map = s5pc1xx_cmd_map; 762 this->read_bufferram = s5pc110_read_bufferram; 763 this->chip_probe = s5pc110_chip_probe; 764 return; 765 } else { 766 BUG(); 767 } 768 769 this->read_word = s3c_onenand_readw; 770 this->write_word = s3c_onenand_writew; 771 772 this->wait = s3c_onenand_wait; 773 this->bbt_wait = s3c_onenand_bbt_wait; 774 this->unlock_all = s3c_unlock_all; 775 this->command = s3c_onenand_command; 776 777 this->read_bufferram = onenand_read_bufferram; 778 this->write_bufferram = onenand_write_bufferram; 779} 780 781static int s3c_onenand_probe(struct platform_device *pdev) 782{ 783 struct onenand_platform_data *pdata; 784 struct onenand_chip *this; 785 struct mtd_info *mtd; 786 struct resource *r; 787 int size, err; 788 789 pdata = pdev->dev.platform_data; 790 /* No need to check pdata. the platform data is optional */ 791 792 size = sizeof(struct mtd_info) + sizeof(struct onenand_chip); 793 mtd = kzalloc(size, GFP_KERNEL); 794 if (!mtd) { 795 dev_err(&pdev->dev, "failed to allocate memory\n"); 796 return -ENOMEM; 797 } 798 799 onenand = kzalloc(sizeof(struct s3c_onenand), GFP_KERNEL); 800 if (!onenand) { 801 err = -ENOMEM; 802 goto onenand_fail; 803 } 804 805 this = (struct onenand_chip *) &mtd[1]; 806 mtd->priv = this; 807 mtd->dev.parent = &pdev->dev; 808 mtd->owner = THIS_MODULE; 809 onenand->pdev = pdev; 810 onenand->type = platform_get_device_id(pdev)->driver_data; 811 812 s3c_onenand_setup(mtd); 813 814 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 815 if (!r) { 816 dev_err(&pdev->dev, "no memory resource defined\n"); 817 return -ENOENT; 818 goto ahb_resource_failed; 819 } 820 821 onenand->base_res = request_mem_region(r->start, resource_size(r), 822 pdev->name); 823 if (!onenand->base_res) { 824 dev_err(&pdev->dev, "failed to request memory resource\n"); 825 err = -EBUSY; 826 goto resource_failed; 827 } 828 829 onenand->base = ioremap(r->start, resource_size(r)); 830 if (!onenand->base) { 831 dev_err(&pdev->dev, "failed to map memory resource\n"); 832 err = -EFAULT; 833 goto ioremap_failed; 834 } 835 /* Set onenand_chip also */ 836 this->base = onenand->base; 837 838 /* Use runtime badblock check */ 839 this->options |= ONENAND_SKIP_UNLOCK_CHECK; 840 841 if (onenand->type != TYPE_S5PC110) { 842 r = platform_get_resource(pdev, IORESOURCE_MEM, 1); 843 if (!r) { 844 dev_err(&pdev->dev, "no buffer memory resource defined\n"); 845 return -ENOENT; 846 goto ahb_resource_failed; 847 } 848 849 onenand->ahb_res = request_mem_region(r->start, resource_size(r), 850 pdev->name); 851 if (!onenand->ahb_res) { 852 dev_err(&pdev->dev, "failed to request buffer memory resource\n"); 853 err = -EBUSY; 854 goto ahb_resource_failed; 855 } 856 857 onenand->ahb_addr = ioremap(r->start, resource_size(r)); 858 if (!onenand->ahb_addr) { 859 dev_err(&pdev->dev, "failed to map buffer memory resource\n"); 860 err = -EINVAL; 861 goto ahb_ioremap_failed; 862 } 863 864 /* Allocate 4KiB BufferRAM */ 865 onenand->page_buf = kzalloc(SZ_4K, GFP_KERNEL); 866 if (!onenand->page_buf) { 867 err = -ENOMEM; 868 goto page_buf_fail; 869 } 870 871 /* Allocate 128 SpareRAM */ 872 onenand->oob_buf = kzalloc(128, GFP_KERNEL); 873 if (!onenand->oob_buf) { 874 err = -ENOMEM; 875 goto oob_buf_fail; 876 } 877 878 /* S3C doesn't handle subpage write */ 879 mtd->subpage_sft = 0; 880 this->subpagesize = mtd->writesize; 881 882 } else { /* S5PC110 */ 883 r = platform_get_resource(pdev, IORESOURCE_MEM, 1); 884 if (!r) { 885 dev_err(&pdev->dev, "no dma memory resource defined\n"); 886 return -ENOENT; 887 goto dma_resource_failed; 888 } 889 890 onenand->dma_res = request_mem_region(r->start, resource_size(r), 891 pdev->name); 892 if (!onenand->dma_res) { 893 dev_err(&pdev->dev, "failed to request dma memory resource\n"); 894 err = -EBUSY; 895 goto dma_resource_failed; 896 } 897 898 onenand->dma_addr = ioremap(r->start, resource_size(r)); 899 if (!onenand->dma_addr) { 900 dev_err(&pdev->dev, "failed to map dma memory resource\n"); 901 err = -EINVAL; 902 goto dma_ioremap_failed; 903 } 904 905 onenand->phys_base = onenand->base_res->start; 906 } 907 908 if (onenand_scan(mtd, 1)) { 909 err = -EFAULT; 910 goto scan_failed; 911 } 912 913 if (onenand->type != TYPE_S5PC110) { 914 /* S3C doesn't handle subpage write */ 915 mtd->subpage_sft = 0; 916 this->subpagesize = mtd->writesize; 917 } 918 919 if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ) 920 dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n"); 921 922#ifdef CONFIG_MTD_PARTITIONS 923 err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0); 924 if (err > 0) 925 add_mtd_partitions(mtd, onenand->parts, err); 926 else if (err <= 0 && pdata && pdata->parts) 927 add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); 928 else 929#endif 930 err = add_mtd_device(mtd); 931 932 platform_set_drvdata(pdev, mtd); 933 934 return 0; 935 936scan_failed: 937 if (onenand->dma_addr) 938 iounmap(onenand->dma_addr); 939dma_ioremap_failed: 940 if (onenand->dma_res) 941 release_mem_region(onenand->dma_res->start, 942 resource_size(onenand->dma_res)); 943 kfree(onenand->oob_buf); 944oob_buf_fail: 945 kfree(onenand->page_buf); 946page_buf_fail: 947 if (onenand->ahb_addr) 948 iounmap(onenand->ahb_addr); 949ahb_ioremap_failed: 950 if (onenand->ahb_res) 951 release_mem_region(onenand->ahb_res->start, 952 resource_size(onenand->ahb_res)); 953dma_resource_failed: 954ahb_resource_failed: 955 iounmap(onenand->base); 956ioremap_failed: 957 if (onenand->base_res) 958 release_mem_region(onenand->base_res->start, 959 resource_size(onenand->base_res)); 960resource_failed: 961 kfree(onenand); 962onenand_fail: 963 kfree(mtd); 964 return err; 965} 966 967static int __devexit s3c_onenand_remove(struct platform_device *pdev) 968{ 969 struct mtd_info *mtd = platform_get_drvdata(pdev); 970 971 onenand_release(mtd); 972 if (onenand->ahb_addr) 973 iounmap(onenand->ahb_addr); 974 if (onenand->ahb_res) 975 release_mem_region(onenand->ahb_res->start, 976 resource_size(onenand->ahb_res)); 977 if (onenand->dma_addr) 978 iounmap(onenand->dma_addr); 979 if (onenand->dma_res) 980 release_mem_region(onenand->dma_res->start, 981 resource_size(onenand->dma_res)); 982 983 iounmap(onenand->base); 984 release_mem_region(onenand->base_res->start, 985 resource_size(onenand->base_res)); 986 987 platform_set_drvdata(pdev, NULL); 988 kfree(onenand->oob_buf); 989 kfree(onenand->page_buf); 990 kfree(onenand); 991 kfree(mtd); 992 return 0; 993} 994 995static int s3c_pm_ops_suspend(struct device *dev) 996{ 997 struct platform_device *pdev = to_platform_device(dev); 998 struct mtd_info *mtd = platform_get_drvdata(pdev); 999 struct onenand_chip *this = mtd->priv; 1000 1001 this->wait(mtd, FL_PM_SUSPENDED); 1002 return mtd->suspend(mtd); 1003} 1004 1005static int s3c_pm_ops_resume(struct device *dev) 1006{ 1007 struct platform_device *pdev = to_platform_device(dev); 1008 struct mtd_info *mtd = platform_get_drvdata(pdev); 1009 struct onenand_chip *this = mtd->priv; 1010 1011 mtd->resume(mtd); 1012 this->unlock_all(mtd); 1013 return 0; 1014} 1015 1016static const struct dev_pm_ops s3c_pm_ops = { 1017 .suspend = s3c_pm_ops_suspend, 1018 .resume = s3c_pm_ops_resume, 1019}; 1020 1021static struct platform_device_id s3c_onenand_driver_ids[] = { 1022 { 1023 .name = "s3c6400-onenand", 1024 .driver_data = TYPE_S3C6400, 1025 }, { 1026 .name = "s3c6410-onenand", 1027 .driver_data = TYPE_S3C6410, 1028 }, { 1029 .name = "s5pc100-onenand", 1030 .driver_data = TYPE_S5PC100, 1031 }, { 1032 .name = "s5pc110-onenand", 1033 .driver_data = TYPE_S5PC110, 1034 }, { }, 1035}; 1036MODULE_DEVICE_TABLE(platform, s3c_onenand_driver_ids); 1037 1038static struct platform_driver s3c_onenand_driver = { 1039 .driver = { 1040 .name = "samsung-onenand", 1041 .pm = &s3c_pm_ops, 1042 }, 1043 .id_table = s3c_onenand_driver_ids, 1044 .probe = s3c_onenand_probe, 1045 .remove = __devexit_p(s3c_onenand_remove), 1046}; 1047 1048static int __init s3c_onenand_init(void) 1049{ 1050 return platform_driver_register(&s3c_onenand_driver); 1051} 1052 1053static void __exit s3c_onenand_exit(void) 1054{ 1055 platform_driver_unregister(&s3c_onenand_driver); 1056} 1057 1058module_init(s3c_onenand_init); 1059module_exit(s3c_onenand_exit); 1060 1061MODULE_LICENSE("GPL"); 1062MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>"); 1063MODULE_DESCRIPTION("Samsung OneNAND controller support"); 1064