linux/drivers/mtd/onenand/samsung.c
<<
>>
Prefs
   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        onenand->pdev = pdev;
 868        onenand->type = platform_get_device_id(pdev)->driver_data;
 869
 870        s3c_onenand_setup(mtd);
 871
 872        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 873        if (!r) {
 874                dev_err(&pdev->dev, "no memory resource defined\n");
 875                return -ENOENT;
 876                goto ahb_resource_failed;
 877        }
 878
 879        onenand->base_res = request_mem_region(r->start, resource_size(r),
 880                                               pdev->name);
 881        if (!onenand->base_res) {
 882                dev_err(&pdev->dev, "failed to request memory resource\n");
 883                err = -EBUSY;
 884                goto resource_failed;
 885        }
 886
 887        onenand->base = ioremap(r->start, resource_size(r));
 888        if (!onenand->base) {
 889                dev_err(&pdev->dev, "failed to map memory resource\n");
 890                err = -EFAULT;
 891                goto ioremap_failed;
 892        }
 893        /* Set onenand_chip also */
 894        this->base = onenand->base;
 895
 896        /* Use runtime badblock check */
 897        this->options |= ONENAND_SKIP_UNLOCK_CHECK;
 898
 899        if (onenand->type != TYPE_S5PC110) {
 900                r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 901                if (!r) {
 902                        dev_err(&pdev->dev, "no buffer memory resource defined\n");
 903                        err = -ENOENT;
 904                        goto ahb_resource_failed;
 905                }
 906
 907                onenand->ahb_res = request_mem_region(r->start, resource_size(r),
 908                                                      pdev->name);
 909                if (!onenand->ahb_res) {
 910                        dev_err(&pdev->dev, "failed to request buffer memory resource\n");
 911                        err = -EBUSY;
 912                        goto ahb_resource_failed;
 913                }
 914
 915                onenand->ahb_addr = ioremap(r->start, resource_size(r));
 916                if (!onenand->ahb_addr) {
 917                        dev_err(&pdev->dev, "failed to map buffer memory resource\n");
 918                        err = -EINVAL;
 919                        goto ahb_ioremap_failed;
 920                }
 921
 922                /* Allocate 4KiB BufferRAM */
 923                onenand->page_buf = kzalloc(SZ_4K, GFP_KERNEL);
 924                if (!onenand->page_buf) {
 925                        err = -ENOMEM;
 926                        goto page_buf_fail;
 927                }
 928
 929                /* Allocate 128 SpareRAM */
 930                onenand->oob_buf = kzalloc(128, GFP_KERNEL);
 931                if (!onenand->oob_buf) {
 932                        err = -ENOMEM;
 933                        goto oob_buf_fail;
 934                }
 935
 936                /* S3C doesn't handle subpage write */
 937                mtd->subpage_sft = 0;
 938                this->subpagesize = mtd->writesize;
 939
 940        } else { /* S5PC110 */
 941                r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 942                if (!r) {
 943                        dev_err(&pdev->dev, "no dma memory resource defined\n");
 944                        err = -ENOENT;
 945                        goto dma_resource_failed;
 946                }
 947
 948                onenand->dma_res = request_mem_region(r->start, resource_size(r),
 949                                                      pdev->name);
 950                if (!onenand->dma_res) {
 951                        dev_err(&pdev->dev, "failed to request dma memory resource\n");
 952                        err = -EBUSY;
 953                        goto dma_resource_failed;
 954                }
 955
 956                onenand->dma_addr = ioremap(r->start, resource_size(r));
 957                if (!onenand->dma_addr) {
 958                        dev_err(&pdev->dev, "failed to map dma memory resource\n");
 959                        err = -EINVAL;
 960                        goto dma_ioremap_failed;
 961                }
 962
 963                onenand->phys_base = onenand->base_res->start;
 964
 965                s5pc110_dma_ops = s5pc110_dma_poll;
 966                /* Interrupt support */
 967                r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 968                if (r) {
 969                        init_completion(&onenand->complete);
 970                        s5pc110_dma_ops = s5pc110_dma_irq;
 971                        err = request_irq(r->start, s5pc110_onenand_irq,
 972                                        IRQF_SHARED, "onenand", &onenand);
 973                        if (err) {
 974                                dev_err(&pdev->dev, "failed to get irq\n");
 975                                goto scan_failed;
 976                        }
 977                }
 978        }
 979
 980        if (onenand_scan(mtd, 1)) {
 981                err = -EFAULT;
 982                goto scan_failed;
 983        }
 984
 985        if (onenand->type != TYPE_S5PC110) {
 986                /* S3C doesn't handle subpage write */
 987                mtd->subpage_sft = 0;
 988                this->subpagesize = mtd->writesize;
 989        }
 990
 991        if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
 992                dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
 993
 994        err = mtd_device_parse_register(mtd, NULL, NULL,
 995                                        pdata ? pdata->parts : NULL,
 996                                        pdata ? pdata->nr_parts : 0);
 997
 998        platform_set_drvdata(pdev, mtd);
 999
1000        return 0;
1001
1002scan_failed:
1003        if (onenand->dma_addr)
1004                iounmap(onenand->dma_addr);
1005dma_ioremap_failed:
1006        if (onenand->dma_res)
1007                release_mem_region(onenand->dma_res->start,
1008                                   resource_size(onenand->dma_res));
1009        kfree(onenand->oob_buf);
1010oob_buf_fail:
1011        kfree(onenand->page_buf);
1012page_buf_fail:
1013        if (onenand->ahb_addr)
1014                iounmap(onenand->ahb_addr);
1015ahb_ioremap_failed:
1016        if (onenand->ahb_res)
1017                release_mem_region(onenand->ahb_res->start,
1018                                   resource_size(onenand->ahb_res));
1019dma_resource_failed:
1020ahb_resource_failed:
1021        iounmap(onenand->base);
1022ioremap_failed:
1023        if (onenand->base_res)
1024                release_mem_region(onenand->base_res->start,
1025                                   resource_size(onenand->base_res));
1026resource_failed:
1027        kfree(onenand);
1028onenand_fail:
1029        kfree(mtd);
1030        return err;
1031}
1032
1033static int s3c_onenand_remove(struct platform_device *pdev)
1034{
1035        struct mtd_info *mtd = platform_get_drvdata(pdev);
1036
1037        onenand_release(mtd);
1038        if (onenand->ahb_addr)
1039                iounmap(onenand->ahb_addr);
1040        if (onenand->ahb_res)
1041                release_mem_region(onenand->ahb_res->start,
1042                                   resource_size(onenand->ahb_res));
1043        if (onenand->dma_addr)
1044                iounmap(onenand->dma_addr);
1045        if (onenand->dma_res)
1046                release_mem_region(onenand->dma_res->start,
1047                                   resource_size(onenand->dma_res));
1048
1049        iounmap(onenand->base);
1050        release_mem_region(onenand->base_res->start,
1051                           resource_size(onenand->base_res));
1052
1053        kfree(onenand->oob_buf);
1054        kfree(onenand->page_buf);
1055        kfree(onenand);
1056        kfree(mtd);
1057        return 0;
1058}
1059
1060static int s3c_pm_ops_suspend(struct device *dev)
1061{
1062        struct platform_device *pdev = to_platform_device(dev);
1063        struct mtd_info *mtd = platform_get_drvdata(pdev);
1064        struct onenand_chip *this = mtd->priv;
1065
1066        this->wait(mtd, FL_PM_SUSPENDED);
1067        return 0;
1068}
1069
1070static  int s3c_pm_ops_resume(struct device *dev)
1071{
1072        struct platform_device *pdev = to_platform_device(dev);
1073        struct mtd_info *mtd = platform_get_drvdata(pdev);
1074        struct onenand_chip *this = mtd->priv;
1075
1076        this->unlock_all(mtd);
1077        return 0;
1078}
1079
1080static const struct dev_pm_ops s3c_pm_ops = {
1081        .suspend        = s3c_pm_ops_suspend,
1082        .resume         = s3c_pm_ops_resume,
1083};
1084
1085static const struct platform_device_id s3c_onenand_driver_ids[] = {
1086        {
1087                .name           = "s3c6400-onenand",
1088                .driver_data    = TYPE_S3C6400,
1089        }, {
1090                .name           = "s3c6410-onenand",
1091                .driver_data    = TYPE_S3C6410,
1092        }, {
1093                .name           = "s5pc110-onenand",
1094                .driver_data    = TYPE_S5PC110,
1095        }, { },
1096};
1097MODULE_DEVICE_TABLE(platform, s3c_onenand_driver_ids);
1098
1099static struct platform_driver s3c_onenand_driver = {
1100        .driver         = {
1101                .name   = "samsung-onenand",
1102                .pm     = &s3c_pm_ops,
1103        },
1104        .id_table       = s3c_onenand_driver_ids,
1105        .probe          = s3c_onenand_probe,
1106        .remove         = s3c_onenand_remove,
1107};
1108
1109module_platform_driver(s3c_onenand_driver);
1110
1111MODULE_LICENSE("GPL");
1112MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1113MODULE_DESCRIPTION("Samsung OneNAND controller support");
1114