root/drivers/mtd/nand/onenand/samsung.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. s3c_read_reg
  2. s3c_write_reg
  3. s3c_read_cmd
  4. s3c_write_cmd
  5. s3c_dump_reg
  6. s3c64xx_cmd_map
  7. s3c6400_mem_addr
  8. s3c6410_mem_addr
  9. s3c_onenand_reset
  10. s3c_onenand_readw
  11. s3c_onenand_writew
  12. s3c_onenand_wait
  13. s3c_onenand_command
  14. s3c_get_bufferram
  15. onenand_read_bufferram
  16. onenand_write_bufferram
  17. s5pc110_dma_poll
  18. s5pc110_onenand_irq
  19. s5pc110_dma_irq
  20. s5pc110_read_bufferram
  21. s5pc110_chip_probe
  22. s3c_onenand_bbt_wait
  23. s3c_onenand_check_lock_status
  24. s3c_onenand_do_lock_cmd
  25. s3c_unlock_all
  26. s3c_onenand_setup
  27. s3c_onenand_probe
  28. s3c_onenand_remove
  29. s3c_pm_ops_suspend
  30. s3c_pm_ops_resume

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

/* [<][>][^][v][top][bottom][index][help] */