linux/drivers/mtd/nand/onenand/onenand_samsung.c
<<
>>
Prefs
   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
  27enum 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
 122struct 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
 143static struct s3c_onenand *onenand;
 144
 145static inline int s3c_read_reg(int offset)
 146{
 147        return readl(onenand->base + offset);
 148}
 149
 150static inline void s3c_write_reg(int value, int offset)
 151{
 152        writel(value, onenand->base + offset);
 153}
 154
 155static inline int s3c_read_cmd(unsigned int cmd)
 156{
 157        return readl(onenand->ahb_addr + cmd);
 158}
 159
 160static inline void s3c_write_cmd(int value, unsigned int cmd)
 161{
 162        writel(value, onenand->ahb_addr + cmd);
 163}
 164
 165#ifdef SAMSUNG_DEBUG
 166static 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
 179static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val)
 180{
 181        return (type << S3C64XX_CMD_MAP_SHIFT) | val;
 182}
 183
 184static 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
 190static 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
 196static 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
 216static 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 long)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
 266static 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 long)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
 310static 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
 376static 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
 474static 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
 493static 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
 504static 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
 515static int (*s5pc110_dma_ops)(dma_addr_t dst, dma_addr_t src, size_t count, int direction);
 516
 517static 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
 561static 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
 583static 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
 615static 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 %zu 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
 675normal:
 676        if (count != mtd->writesize) {
 677                /* Copy the bufferram to memory to prevent unaligned access */
 678                memcpy_fromio(this->page_buf, p, mtd->writesize);
 679                memcpy(buffer, this->page_buf + offset, count);
 680        } else {
 681                memcpy_fromio(buffer, p, count);
 682        }
 683
 684        return 0;
 685}
 686
 687static int s5pc110_chip_probe(struct mtd_info *mtd)
 688{
 689        /* Now just return 0 */
 690        return 0;
 691}
 692
 693static 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
 726static 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
 732        end = this->chipsize >> this->erase_shift;
 733
 734        for (block = 0; block < end; block++) {
 735                unsigned int mem_addr = onenand->mem_addr(block, 0, 0);
 736                s3c_read_cmd(CMD_MAP_01(onenand, mem_addr));
 737
 738                if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) {
 739                        dev_err(dev, "block %d is write-protected!\n", block);
 740                        s3c_write_reg(LOCKED_BLK, INT_ERR_ACK_OFFSET);
 741                }
 742        }
 743}
 744
 745static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
 746                                    size_t len, int cmd)
 747{
 748        struct onenand_chip *this = mtd->priv;
 749        int start, end, start_mem_addr, end_mem_addr;
 750
 751        start = ofs >> this->erase_shift;
 752        start_mem_addr = onenand->mem_addr(start, 0, 0);
 753        end = start + (len >> this->erase_shift) - 1;
 754        end_mem_addr = onenand->mem_addr(end, 0, 0);
 755
 756        if (cmd == ONENAND_CMD_LOCK) {
 757                s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(onenand,
 758                                                             start_mem_addr));
 759                s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(onenand,
 760                                                           end_mem_addr));
 761        } else {
 762                s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(onenand,
 763                                                               start_mem_addr));
 764                s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(onenand,
 765                                                             end_mem_addr));
 766        }
 767
 768        this->wait(mtd, FL_LOCKING);
 769}
 770
 771static void s3c_unlock_all(struct mtd_info *mtd)
 772{
 773        struct onenand_chip *this = mtd->priv;
 774        loff_t ofs = 0;
 775        size_t len = this->chipsize;
 776
 777        if (this->options & ONENAND_HAS_UNLOCK_ALL) {
 778                /* Write unlock command */
 779                this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
 780
 781                /* No need to check return value */
 782                this->wait(mtd, FL_LOCKING);
 783
 784                /* Workaround for all block unlock in DDP */
 785                if (!ONENAND_IS_DDP(this)) {
 786                        s3c_onenand_check_lock_status(mtd);
 787                        return;
 788                }
 789
 790                /* All blocks on another chip */
 791                ofs = this->chipsize >> 1;
 792                len = this->chipsize >> 1;
 793        }
 794
 795        s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
 796
 797        s3c_onenand_check_lock_status(mtd);
 798}
 799
 800static void s3c_onenand_setup(struct mtd_info *mtd)
 801{
 802        struct onenand_chip *this = mtd->priv;
 803
 804        onenand->mtd = mtd;
 805
 806        if (onenand->type == TYPE_S3C6400) {
 807                onenand->mem_addr = s3c6400_mem_addr;
 808                onenand->cmd_map = s3c64xx_cmd_map;
 809        } else if (onenand->type == TYPE_S3C6410) {
 810                onenand->mem_addr = s3c6410_mem_addr;
 811                onenand->cmd_map = s3c64xx_cmd_map;
 812        } else if (onenand->type == TYPE_S5PC110) {
 813                /* Use generic onenand functions */
 814                this->read_bufferram = s5pc110_read_bufferram;
 815                this->chip_probe = s5pc110_chip_probe;
 816                return;
 817        } else {
 818                BUG();
 819        }
 820
 821        this->read_word = s3c_onenand_readw;
 822        this->write_word = s3c_onenand_writew;
 823
 824        this->wait = s3c_onenand_wait;
 825        this->bbt_wait = s3c_onenand_bbt_wait;
 826        this->unlock_all = s3c_unlock_all;
 827        this->command = s3c_onenand_command;
 828
 829        this->read_bufferram = onenand_read_bufferram;
 830        this->write_bufferram = onenand_write_bufferram;
 831}
 832
 833static int s3c_onenand_probe(struct platform_device *pdev)
 834{
 835        struct onenand_platform_data *pdata;
 836        struct onenand_chip *this;
 837        struct mtd_info *mtd;
 838        struct resource *r;
 839        int size, err;
 840
 841        pdata = dev_get_platdata(&pdev->dev);
 842        /* No need to check pdata. the platform data is optional */
 843
 844        size = sizeof(struct mtd_info) + sizeof(struct onenand_chip);
 845        mtd = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
 846        if (!mtd)
 847                return -ENOMEM;
 848
 849        onenand = devm_kzalloc(&pdev->dev, sizeof(struct s3c_onenand),
 850                               GFP_KERNEL);
 851        if (!onenand)
 852                return -ENOMEM;
 853
 854        this = (struct onenand_chip *) &mtd[1];
 855        mtd->priv = this;
 856        mtd->dev.parent = &pdev->dev;
 857        onenand->pdev = pdev;
 858        onenand->type = platform_get_device_id(pdev)->driver_data;
 859
 860        s3c_onenand_setup(mtd);
 861
 862        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 863        onenand->base = devm_ioremap_resource(&pdev->dev, r);
 864        if (IS_ERR(onenand->base))
 865                return PTR_ERR(onenand->base);
 866
 867        onenand->phys_base = r->start;
 868
 869        /* Set onenand_chip also */
 870        this->base = onenand->base;
 871
 872        /* Use runtime badblock check */
 873        this->options |= ONENAND_SKIP_UNLOCK_CHECK;
 874
 875        if (onenand->type != TYPE_S5PC110) {
 876                r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 877                onenand->ahb_addr = devm_ioremap_resource(&pdev->dev, r);
 878                if (IS_ERR(onenand->ahb_addr))
 879                        return PTR_ERR(onenand->ahb_addr);
 880
 881                /* Allocate 4KiB BufferRAM */
 882                onenand->page_buf = devm_kzalloc(&pdev->dev, SZ_4K,
 883                                                 GFP_KERNEL);
 884                if (!onenand->page_buf)
 885                        return -ENOMEM;
 886
 887                /* Allocate 128 SpareRAM */
 888                onenand->oob_buf = devm_kzalloc(&pdev->dev, 128, GFP_KERNEL);
 889                if (!onenand->oob_buf)
 890                        return -ENOMEM;
 891
 892                /* S3C doesn't handle subpage write */
 893                mtd->subpage_sft = 0;
 894                this->subpagesize = mtd->writesize;
 895
 896        } else { /* S5PC110 */
 897                r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 898                onenand->dma_addr = devm_ioremap_resource(&pdev->dev, r);
 899                if (IS_ERR(onenand->dma_addr))
 900                        return PTR_ERR(onenand->dma_addr);
 901
 902                s5pc110_dma_ops = s5pc110_dma_poll;
 903                /* Interrupt support */
 904                r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 905                if (r) {
 906                        init_completion(&onenand->complete);
 907                        s5pc110_dma_ops = s5pc110_dma_irq;
 908                        err = devm_request_irq(&pdev->dev, r->start,
 909                                               s5pc110_onenand_irq,
 910                                               IRQF_SHARED, "onenand",
 911                                               &onenand);
 912                        if (err) {
 913                                dev_err(&pdev->dev, "failed to get irq\n");
 914                                return err;
 915                        }
 916                }
 917        }
 918
 919        err = onenand_scan(mtd, 1);
 920        if (err)
 921                return err;
 922
 923        if (onenand->type != TYPE_S5PC110) {
 924                /* S3C doesn't handle subpage write */
 925                mtd->subpage_sft = 0;
 926                this->subpagesize = mtd->writesize;
 927        }
 928
 929        if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
 930                dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
 931
 932        err = mtd_device_register(mtd, pdata ? pdata->parts : NULL,
 933                                  pdata ? pdata->nr_parts : 0);
 934        if (err) {
 935                dev_err(&pdev->dev, "failed to parse partitions and register the MTD device\n");
 936                onenand_release(mtd);
 937                return err;
 938        }
 939
 940        platform_set_drvdata(pdev, mtd);
 941
 942        return 0;
 943}
 944
 945static int s3c_onenand_remove(struct platform_device *pdev)
 946{
 947        struct mtd_info *mtd = platform_get_drvdata(pdev);
 948
 949        onenand_release(mtd);
 950
 951        return 0;
 952}
 953
 954static int s3c_pm_ops_suspend(struct device *dev)
 955{
 956        struct mtd_info *mtd = dev_get_drvdata(dev);
 957        struct onenand_chip *this = mtd->priv;
 958
 959        this->wait(mtd, FL_PM_SUSPENDED);
 960        return 0;
 961}
 962
 963static  int s3c_pm_ops_resume(struct device *dev)
 964{
 965        struct mtd_info *mtd = dev_get_drvdata(dev);
 966        struct onenand_chip *this = mtd->priv;
 967
 968        this->unlock_all(mtd);
 969        return 0;
 970}
 971
 972static const struct dev_pm_ops s3c_pm_ops = {
 973        .suspend        = s3c_pm_ops_suspend,
 974        .resume         = s3c_pm_ops_resume,
 975};
 976
 977static const struct platform_device_id s3c_onenand_driver_ids[] = {
 978        {
 979                .name           = "s3c6400-onenand",
 980                .driver_data    = TYPE_S3C6400,
 981        }, {
 982                .name           = "s3c6410-onenand",
 983                .driver_data    = TYPE_S3C6410,
 984        }, {
 985                .name           = "s5pc110-onenand",
 986                .driver_data    = TYPE_S5PC110,
 987        }, { },
 988};
 989MODULE_DEVICE_TABLE(platform, s3c_onenand_driver_ids);
 990
 991static struct platform_driver s3c_onenand_driver = {
 992        .driver         = {
 993                .name   = "samsung-onenand",
 994                .pm     = &s3c_pm_ops,
 995        },
 996        .id_table       = s3c_onenand_driver_ids,
 997        .probe          = s3c_onenand_probe,
 998        .remove         = s3c_onenand_remove,
 999};
1000
1001module_platform_driver(s3c_onenand_driver);
1002
1003MODULE_LICENSE("GPL");
1004MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1005MODULE_DESCRIPTION("Samsung OneNAND controller support");
1006