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