uboot/drivers/mtd/nand/arasan_nfc.c
<<
>>
Prefs
   1/*
   2 * Arasan NAND Flash Controller Driver
   3 *
   4 * Copyright (C) 2014 - 2015 Xilinx, Inc.
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <malloc.h>
  11#include <asm/io.h>
  12#include <asm/errno.h>
  13#include <linux/mtd/mtd.h>
  14#include <linux/mtd/nand.h>
  15#include <linux/mtd/partitions.h>
  16#include <linux/mtd/nand_ecc.h>
  17#include <asm/arch/hardware.h>
  18#include <asm/arch/sys_proto.h>
  19#include <nand.h>
  20
  21struct arasan_nand_info {
  22        void __iomem *nand_base;
  23        u32 page;
  24};
  25
  26struct nand_regs {
  27        u32 pkt_reg;
  28        u32 memadr_reg1;
  29        u32 memadr_reg2;
  30        u32 cmd_reg;
  31        u32 pgm_reg;
  32        u32 intsts_enr;
  33        u32 intsig_enr;
  34        u32 intsts_reg;
  35        u32 rdy_busy;
  36        u32 cms_sysadr_reg;
  37        u32 flash_sts_reg;
  38        u32 tmg_reg;
  39        u32 buf_dataport;
  40        u32 ecc_reg;
  41        u32 ecc_errcnt_reg;
  42        u32 ecc_sprcmd_reg;
  43        u32 errcnt_1bitreg;
  44        u32 errcnt_2bitreg;
  45        u32 errcnt_3bitreg;
  46        u32 errcnt_4bitreg;
  47        u32 dma_sysadr0_reg;
  48        u32 dma_bufbdry_reg;
  49        u32 cpu_rls_reg;
  50        u32 errcnt_5bitreg;
  51        u32 errcnt_6bitreg;
  52        u32 errcnt_7bitreg;
  53        u32 errcnt_8bitreg;
  54        u32 data_if_reg;
  55};
  56
  57#define arasan_nand_base ((struct nand_regs __iomem *)ARASAN_NAND_BASEADDR)
  58
  59struct arasan_nand_command_format {
  60        u8 cmd1;
  61        u8 cmd2;
  62        u8 addr_cycles;
  63        u32 pgm;
  64};
  65
  66#define ONDIE_ECC_FEATURE_ADDR                  0x90
  67
  68#define ARASAN_PROG_RD_MASK                     0x00000001
  69#define ARASAN_PROG_BLK_ERS_MASK                0x00000004
  70#define ARASAN_PROG_RD_ID_MASK                  0x00000040
  71#define ARASAN_PROG_RD_STS_MASK                 0x00000008
  72#define ARASAN_PROG_PG_PROG_MASK                0x00000010
  73#define ARASAN_PROG_RD_PARAM_PG_MASK            0x00000080
  74#define ARASAN_PROG_RST_MASK                    0x00000100
  75#define ARASAN_PROG_GET_FTRS_MASK               0x00000200
  76#define ARASAN_PROG_SET_FTRS_MASK               0x00000400
  77#define ARASAN_PROG_CHNG_ROWADR_END_MASK        0x00400000
  78
  79#define ARASAN_NAND_CMD_ECC_ON_MASK             0x80000000
  80#define ARASAN_NAND_CMD_CMD12_MASK              0xFFFF
  81#define ARASAN_NAND_CMD_PG_SIZE_MASK            0x3800000
  82#define ARASAN_NAND_CMD_PG_SIZE_SHIFT           23
  83#define ARASAN_NAND_CMD_CMD2_SHIFT              8
  84#define ARASAN_NAND_CMD_ADDR_CYCL_MASK          0x70000000
  85#define ARASAN_NAND_CMD_ADDR_CYCL_SHIFT         28
  86
  87#define ARASAN_NAND_MEM_ADDR1_PAGE_MASK         0xFFFF0000
  88#define ARASAN_NAND_MEM_ADDR1_COL_MASK          0xFFFF
  89#define ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT        16
  90#define ARASAN_NAND_MEM_ADDR2_PAGE_MASK         0xFF
  91#define ARASAN_NAND_MEM_ADDR2_CS_MASK           0xC0000000
  92#define ARASAN_NAND_MEM_ADDR2_BCH_MASK          0xE000000
  93#define ARASAN_NAND_MEM_ADDR2_BCH_SHIFT         25
  94
  95#define ARASAN_NAND_INT_STS_ERR_EN_MASK         0x10
  96#define ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK    0x08
  97#define ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK     0x02
  98#define ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK     0x01
  99#define ARASAN_NAND_INT_STS_XFR_CMPLT_MASK      0x04
 100
 101#define ARASAN_NAND_PKT_REG_PKT_CNT_MASK        0xFFF000
 102#define ARASAN_NAND_PKT_REG_PKT_SIZE_MASK       0x7FF
 103#define ARASAN_NAND_PKT_REG_PKT_CNT_SHFT        12
 104
 105#define ARASAN_NAND_ROW_ADDR_CYCL_MASK          0x0F
 106#define ARASAN_NAND_COL_ADDR_CYCL_MASK          0xF0
 107#define ARASAN_NAND_COL_ADDR_CYCL_SHIFT         4
 108
 109#define ARASAN_NAND_ECC_SIZE_SHIFT              16
 110#define ARASAN_NAND_ECC_BCH_SHIFT               27
 111
 112#define ARASAN_NAND_PKTSIZE_1K                  1024
 113#define ARASAN_NAND_PKTSIZE_512                 512
 114
 115#define ARASAN_NAND_POLL_TIMEOUT                1000000
 116#define ARASAN_NAND_INVALID_ADDR_CYCL           0xFF
 117
 118#define ERR_ADDR_CYCLE                          -1
 119#define READ_BUFF_SIZE                          0x4000
 120
 121static struct arasan_nand_command_format *curr_cmd;
 122
 123enum addr_cycles {
 124        NAND_ADDR_CYCL_NONE,
 125        NAND_ADDR_CYCL_ONE,
 126        NAND_ADDR_CYCL_ROW,
 127        NAND_ADDR_CYCL_COL,
 128        NAND_ADDR_CYCL_BOTH,
 129};
 130
 131static struct arasan_nand_command_format arasan_nand_commands[] = {
 132        {NAND_CMD_READ0, NAND_CMD_READSTART, NAND_ADDR_CYCL_BOTH,
 133         ARASAN_PROG_RD_MASK},
 134        {NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, NAND_ADDR_CYCL_COL,
 135         ARASAN_PROG_RD_MASK},
 136        {NAND_CMD_READID, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
 137         ARASAN_PROG_RD_ID_MASK},
 138        {NAND_CMD_STATUS, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE,
 139         ARASAN_PROG_RD_STS_MASK},
 140        {NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, NAND_ADDR_CYCL_BOTH,
 141         ARASAN_PROG_PG_PROG_MASK},
 142        {NAND_CMD_RNDIN, NAND_CMD_NONE, NAND_ADDR_CYCL_COL,
 143         ARASAN_PROG_CHNG_ROWADR_END_MASK},
 144        {NAND_CMD_ERASE1, NAND_CMD_ERASE2, NAND_ADDR_CYCL_ROW,
 145         ARASAN_PROG_BLK_ERS_MASK},
 146        {NAND_CMD_RESET, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE,
 147         ARASAN_PROG_RST_MASK},
 148        {NAND_CMD_PARAM, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
 149         ARASAN_PROG_RD_PARAM_PG_MASK},
 150        {NAND_CMD_GET_FEATURES, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
 151         ARASAN_PROG_GET_FTRS_MASK},
 152        {NAND_CMD_SET_FEATURES, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
 153         ARASAN_PROG_SET_FTRS_MASK},
 154        {NAND_CMD_NONE, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE, 0},
 155};
 156
 157struct arasan_ecc_matrix {
 158        u32 pagesize;
 159        u32 ecc_codeword_size;
 160        u8 eccbits;
 161        u8 bch;
 162        u8 bchval;
 163        u16 eccaddr;
 164        u16 eccsize;
 165};
 166
 167static const struct arasan_ecc_matrix ecc_matrix[] = {
 168        {512, 512, 1, 0, 0, 0x20D, 0x3},
 169        {512, 512, 4, 1, 3, 0x209, 0x7},
 170        {512, 512, 8, 1, 2, 0x203, 0xD},
 171        /*
 172         * 2K byte page
 173         */
 174        {2048, 512, 1, 0, 0, 0x834, 0xC},
 175        {2048, 512, 4, 1, 3, 0x826, 0x1A},
 176        {2048, 512, 8, 1, 2, 0x80c, 0x34},
 177        {2048, 512, 12, 1, 1, 0x822, 0x4E},
 178        {2048, 512, 16, 1, 0, 0x808, 0x68},
 179        {2048, 1024, 24, 1, 4, 0x81c, 0x54},
 180        /*
 181         * 4K byte page
 182         */
 183        {4096, 512, 1, 0, 0, 0x1068, 0x18},
 184        {4096, 512, 4, 1, 3, 0x104c, 0x34},
 185        {4096, 512, 8, 1, 2, 0x1018, 0x68},
 186        {4096, 512, 12, 1, 1, 0x1044, 0x9C},
 187        {4096, 512, 16, 1, 0, 0x1010, 0xD0},
 188        {4096, 1024, 24, 1, 4, 0x1038, 0xA8},
 189        /*
 190         * 8K byte page
 191         */
 192        {8192, 512, 1, 0, 0, 0x20d0, 0x30},
 193        {8192, 512, 4, 1, 3, 0x2098, 0x68},
 194        {8192, 512, 8, 1, 2, 0x2030, 0xD0},
 195        {8192, 512, 12, 1, 1, 0x2088, 0x138},
 196        {8192, 512, 16, 1, 0, 0x2020, 0x1A0},
 197        {8192, 1024, 24, 1, 4, 0x2070, 0x150},
 198        /*
 199         * 16K byte page
 200         */
 201        {16384, 512, 1, 0, 0, 0x4460, 0x60},
 202        {16384, 512, 4, 1, 3, 0x43f0, 0xD0},
 203        {16384, 512, 8, 1, 2, 0x4320, 0x1A0},
 204        {16384, 512, 12, 1, 1, 0x4250, 0x270},
 205        {16384, 512, 16, 1, 0, 0x4180, 0x340},
 206        {16384, 1024, 24, 1, 4, 0x4220, 0x2A0}
 207};
 208
 209static u8 buf_data[READ_BUFF_SIZE];
 210static u32 buf_index;
 211
 212static struct nand_ecclayout nand_oob;
 213
 214static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
 215
 216static void arasan_nand_select_chip(struct mtd_info *mtd, int chip)
 217{
 218}
 219
 220static void arasan_nand_enable_ecc(void)
 221{
 222        u32 reg_val;
 223
 224        reg_val = readl(&arasan_nand_base->cmd_reg);
 225        reg_val |= ARASAN_NAND_CMD_ECC_ON_MASK;
 226
 227        writel(reg_val, &arasan_nand_base->cmd_reg);
 228}
 229
 230static u8 arasan_nand_get_addrcycle(struct mtd_info *mtd)
 231{
 232        u8 addrcycles;
 233        struct nand_chip *chip = mtd->priv;
 234
 235        switch (curr_cmd->addr_cycles) {
 236        case NAND_ADDR_CYCL_NONE:
 237                addrcycles = 0;
 238                break;
 239        case NAND_ADDR_CYCL_ONE:
 240                addrcycles = 1;
 241                break;
 242        case NAND_ADDR_CYCL_ROW:
 243                addrcycles = chip->onfi_params.addr_cycles &
 244                             ARASAN_NAND_ROW_ADDR_CYCL_MASK;
 245                break;
 246        case NAND_ADDR_CYCL_COL:
 247                addrcycles = (chip->onfi_params.addr_cycles &
 248                              ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
 249                              ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
 250                break;
 251        case NAND_ADDR_CYCL_BOTH:
 252                addrcycles = chip->onfi_params.addr_cycles &
 253                             ARASAN_NAND_ROW_ADDR_CYCL_MASK;
 254                addrcycles += (chip->onfi_params.addr_cycles &
 255                               ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
 256                               ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
 257                break;
 258        default:
 259                addrcycles = ARASAN_NAND_INVALID_ADDR_CYCL;
 260                break;
 261        }
 262        return addrcycles;
 263}
 264
 265static int arasan_nand_read_page(struct mtd_info *mtd, u8 *buf, u32 size)
 266{
 267        struct nand_chip *chip = mtd->priv;
 268        u32 reg_val, i, pktsize, pktnum;
 269        u32 *bufptr = (u32 *)buf;
 270        u32 timeout;
 271        u32  rdcount = 0;
 272        u8 addr_cycles;
 273
 274        if (chip->ecc_step_ds >= ARASAN_NAND_PKTSIZE_1K)
 275                pktsize = ARASAN_NAND_PKTSIZE_1K;
 276        else
 277                pktsize = ARASAN_NAND_PKTSIZE_512;
 278
 279        if (size % pktsize)
 280                pktnum = size/pktsize + 1;
 281        else
 282                pktnum = size/pktsize;
 283
 284        reg_val = readl(&arasan_nand_base->intsts_enr);
 285        reg_val |= ARASAN_NAND_INT_STS_ERR_EN_MASK |
 286                   ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK;
 287        writel(reg_val, &arasan_nand_base->intsts_enr);
 288
 289        reg_val = readl(&arasan_nand_base->pkt_reg);
 290        reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
 291                     ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
 292        reg_val |= (pktnum << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) |
 293                    pktsize;
 294        writel(reg_val, &arasan_nand_base->pkt_reg);
 295
 296        arasan_nand_enable_ecc();
 297        addr_cycles = arasan_nand_get_addrcycle(mtd);
 298        if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
 299                return ERR_ADDR_CYCLE;
 300
 301        writel((NAND_CMD_RNDOUTSTART << ARASAN_NAND_CMD_CMD2_SHIFT) |
 302               NAND_CMD_RNDOUT | (addr_cycles <<
 303               ARASAN_NAND_CMD_ADDR_CYCL_SHIFT),
 304               &arasan_nand_base->ecc_sprcmd_reg);
 305        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 306
 307        while (rdcount < pktnum) {
 308                timeout = ARASAN_NAND_POLL_TIMEOUT;
 309                while (!(readl(&arasan_nand_base->intsts_reg) &
 310                        ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK) && timeout) {
 311                        udelay(1);
 312                        timeout--;
 313                }
 314                if (!timeout) {
 315                        puts("arasan_read_page: timedout:Buff RDY\n");
 316                        return -ETIMEDOUT;
 317                }
 318
 319                rdcount++;
 320
 321                if (pktnum == rdcount) {
 322                        reg_val = readl(&arasan_nand_base->intsts_enr);
 323                        reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
 324                        writel(reg_val, &arasan_nand_base->intsts_enr);
 325                } else {
 326                        reg_val = readl(&arasan_nand_base->intsts_enr);
 327                        writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 328                               &arasan_nand_base->intsts_enr);
 329                }
 330                reg_val = readl(&arasan_nand_base->intsts_reg);
 331                writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 332                       &arasan_nand_base->intsts_reg);
 333
 334                for (i = 0; i < pktsize/4; i++)
 335                        bufptr[i] = readl(&arasan_nand_base->buf_dataport);
 336
 337
 338                bufptr += pktsize/4;
 339
 340                if (rdcount >= pktnum)
 341                        break;
 342
 343                writel(ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 344                       &arasan_nand_base->intsts_enr);
 345        }
 346
 347        timeout = ARASAN_NAND_POLL_TIMEOUT;
 348
 349        while (!(readl(&arasan_nand_base->intsts_reg) &
 350                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 351                udelay(1);
 352                timeout--;
 353        }
 354        if (!timeout) {
 355                puts("arasan rd_page timedout:Xfer CMPLT\n");
 356                return -ETIMEDOUT;
 357        }
 358
 359        reg_val = readl(&arasan_nand_base->intsts_enr);
 360        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 361               &arasan_nand_base->intsts_enr);
 362        reg_val = readl(&arasan_nand_base->intsts_reg);
 363        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 364               &arasan_nand_base->intsts_reg);
 365
 366        if (readl(&arasan_nand_base->intsts_reg) &
 367            ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK) {
 368                printf("arasan rd_page:sbiterror\n");
 369                return -1;
 370        }
 371
 372        if (readl(&arasan_nand_base->intsts_reg) &
 373            ARASAN_NAND_INT_STS_ERR_EN_MASK) {
 374                mtd->ecc_stats.failed++;
 375                printf("arasan rd_page:multibiterror\n");
 376                return -1;
 377        }
 378
 379        return 0;
 380}
 381
 382static int arasan_nand_read_page_hwecc(struct mtd_info *mtd,
 383                struct nand_chip *chip, u8 *buf, int oob_required, int page)
 384{
 385        int status;
 386
 387        status = arasan_nand_read_page(mtd, buf, (mtd->writesize));
 388
 389        if (oob_required)
 390                chip->ecc.read_oob(mtd, chip, page);
 391
 392        return status;
 393}
 394
 395static void arasan_nand_fill_tx(const u8 *buf, int len)
 396{
 397        u32 __iomem *nand = &arasan_nand_base->buf_dataport;
 398
 399        if (((unsigned long)buf & 0x3) != 0) {
 400                if (((unsigned long)buf & 0x1) != 0) {
 401                        if (len) {
 402                                writeb(*buf, nand);
 403                                buf += 1;
 404                                len--;
 405                        }
 406                }
 407
 408                if (((unsigned long)buf & 0x3) != 0) {
 409                        if (len >= 2) {
 410                                writew(*(u16 *)buf, nand);
 411                                buf += 2;
 412                                len -= 2;
 413                        }
 414                }
 415        }
 416
 417        while (len >= 4) {
 418                writel(*(u32 *)buf, nand);
 419                buf += 4;
 420                len -= 4;
 421        }
 422
 423        if (len) {
 424                if (len >= 2) {
 425                        writew(*(u16 *)buf, nand);
 426                        buf += 2;
 427                        len -= 2;
 428                }
 429
 430                if (len)
 431                        writeb(*buf, nand);
 432        }
 433}
 434
 435static int arasan_nand_write_page_hwecc(struct mtd_info *mtd,
 436                struct nand_chip *chip, const u8 *buf, int oob_required)
 437{
 438        u32 reg_val, i, pktsize, pktnum;
 439        const u32 *bufptr = (const u32 *)buf;
 440        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 441        u32 size = mtd->writesize;
 442        u32 rdcount = 0;
 443        u8 column_addr_cycles;
 444        struct arasan_nand_info *nand = chip->priv;
 445
 446        if (chip->ecc_step_ds >= ARASAN_NAND_PKTSIZE_1K)
 447                pktsize = ARASAN_NAND_PKTSIZE_1K;
 448        else
 449                pktsize = ARASAN_NAND_PKTSIZE_512;
 450
 451        if (size % pktsize)
 452                pktnum = size/pktsize + 1;
 453        else
 454                pktnum = size/pktsize;
 455
 456        reg_val = readl(&arasan_nand_base->pkt_reg);
 457        reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
 458                     ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
 459        reg_val |= (pktnum << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | pktsize;
 460        writel(reg_val, &arasan_nand_base->pkt_reg);
 461
 462        arasan_nand_enable_ecc();
 463        column_addr_cycles = (chip->onfi_params.addr_cycles &
 464                              ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
 465                              ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
 466        writel((NAND_CMD_RNDIN | (column_addr_cycles << 28)),
 467               &arasan_nand_base->ecc_sprcmd_reg);
 468        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 469
 470        while (rdcount < pktnum) {
 471                timeout = ARASAN_NAND_POLL_TIMEOUT;
 472                while (!(readl(&arasan_nand_base->intsts_reg) &
 473                        ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK) && timeout) {
 474                        udelay(1);
 475                        timeout--;
 476                }
 477
 478                if (!timeout) {
 479                        puts("arasan_write_page: timedout:Buff RDY\n");
 480                        return -ETIMEDOUT;
 481                }
 482
 483                rdcount++;
 484
 485                if (pktnum == rdcount) {
 486                        reg_val = readl(&arasan_nand_base->intsts_enr);
 487                        reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
 488                        writel(reg_val, &arasan_nand_base->intsts_enr);
 489                } else {
 490                        reg_val = readl(&arasan_nand_base->intsts_enr);
 491                        writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 492                               &arasan_nand_base->intsts_enr);
 493                }
 494
 495                reg_val = readl(&arasan_nand_base->intsts_reg);
 496                writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 497                       &arasan_nand_base->intsts_reg);
 498
 499                for (i = 0; i < pktsize/4; i++)
 500                        writel(bufptr[i], &arasan_nand_base->buf_dataport);
 501
 502                bufptr += pktsize/4;
 503
 504                if (rdcount >= pktnum)
 505                        break;
 506
 507                writel(ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 508                       &arasan_nand_base->intsts_enr);
 509        }
 510
 511        timeout = ARASAN_NAND_POLL_TIMEOUT;
 512
 513        while (!(readl(&arasan_nand_base->intsts_reg) &
 514                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 515                udelay(1);
 516                timeout--;
 517        }
 518        if (!timeout) {
 519                puts("arasan write_page timedout:Xfer CMPLT\n");
 520                return -ETIMEDOUT;
 521        }
 522
 523        reg_val = readl(&arasan_nand_base->intsts_enr);
 524        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 525               &arasan_nand_base->intsts_enr);
 526        reg_val = readl(&arasan_nand_base->intsts_reg);
 527        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 528               &arasan_nand_base->intsts_reg);
 529
 530        if (oob_required)
 531                chip->ecc.write_oob(mtd, chip, nand->page);
 532
 533        return 0;
 534}
 535
 536static int arasan_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 537                                int page)
 538{
 539        chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
 540        chip->read_buf(mtd, chip->oob_poi, (mtd->oobsize));
 541
 542        return 0;
 543}
 544
 545static int arasan_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 546                                 int page)
 547{
 548        int status = 0;
 549        const u8 *buf = chip->oob_poi;
 550
 551        chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
 552        chip->write_buf(mtd, buf, mtd->oobsize);
 553
 554        return status;
 555}
 556
 557static int arasan_nand_reset(struct arasan_nand_command_format *curr_cmd)
 558{
 559        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 560        u32 cmd_reg = 0;
 561
 562        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 563               &arasan_nand_base->intsts_enr);
 564        cmd_reg = readl(&arasan_nand_base->cmd_reg);
 565        cmd_reg &= ~ARASAN_NAND_CMD_CMD12_MASK;
 566
 567        cmd_reg |= curr_cmd->cmd1 |
 568                  (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
 569        writel(cmd_reg, &arasan_nand_base->cmd_reg);
 570        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 571
 572        while (!(readl(&arasan_nand_base->intsts_reg) &
 573                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 574                udelay(1);
 575                timeout--;
 576        }
 577        if (!timeout) {
 578                printf("ERROR:%s timedout\n", __func__);
 579                return -ETIMEDOUT;
 580        }
 581
 582        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 583               &arasan_nand_base->intsts_enr);
 584
 585        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 586               &arasan_nand_base->intsts_reg);
 587
 588        return 0;
 589}
 590
 591static u8 arasan_nand_page(struct mtd_info *mtd)
 592{
 593        u8 page_val = 0;
 594
 595        switch (mtd->writesize) {
 596        case 512:
 597                page_val = 0;
 598                break;
 599        case 2048:
 600                page_val = 1;
 601                break;
 602        case 4096:
 603                page_val = 2;
 604                break;
 605        case 8192:
 606                page_val = 3;
 607                break;
 608        case 16384:
 609                page_val = 4;
 610                break;
 611        case 1024:
 612                page_val = 5;
 613                break;
 614        default:
 615                printf("%s:Pagesize>16K\n", __func__);
 616                break;
 617        }
 618
 619        return page_val;
 620}
 621
 622static int arasan_nand_send_wrcmd(struct arasan_nand_command_format *curr_cmd,
 623                        int column, int page_addr, struct mtd_info *mtd)
 624{
 625        u32 reg_val, page;
 626        u8 page_val, addr_cycles;
 627
 628        writel(ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 629               &arasan_nand_base->intsts_enr);
 630        reg_val = readl(&arasan_nand_base->cmd_reg);
 631        reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
 632        reg_val |= curr_cmd->cmd1 |
 633                   (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
 634        if (curr_cmd->cmd1 == NAND_CMD_SEQIN) {
 635                reg_val &= ~ARASAN_NAND_CMD_PG_SIZE_MASK;
 636                page_val = arasan_nand_page(mtd);
 637                reg_val |= (page_val << ARASAN_NAND_CMD_PG_SIZE_SHIFT);
 638        }
 639
 640        reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
 641        addr_cycles = arasan_nand_get_addrcycle(mtd);
 642
 643        if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
 644                return ERR_ADDR_CYCLE;
 645
 646        reg_val |= (addr_cycles <<
 647                   ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
 648        writel(reg_val, &arasan_nand_base->cmd_reg);
 649
 650        if (page_addr == -1)
 651                page_addr = 0;
 652
 653        page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
 654                ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
 655        column &= ARASAN_NAND_MEM_ADDR1_COL_MASK;
 656        writel(page|column, &arasan_nand_base->memadr_reg1);
 657
 658        reg_val = readl(&arasan_nand_base->memadr_reg2);
 659        reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
 660        reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
 661        writel(reg_val, &arasan_nand_base->memadr_reg2);
 662        reg_val = readl(&arasan_nand_base->memadr_reg2);
 663        reg_val &= ~ARASAN_NAND_MEM_ADDR2_CS_MASK;
 664        writel(reg_val, &arasan_nand_base->memadr_reg2);
 665
 666        return 0;
 667}
 668
 669static void arasan_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
 670{
 671        u32 reg_val;
 672        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 673
 674        reg_val = readl(&arasan_nand_base->pkt_reg);
 675        reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
 676                     ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
 677
 678        reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | len;
 679        writel(reg_val, &arasan_nand_base->pkt_reg);
 680        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 681
 682        while (!(readl(&arasan_nand_base->intsts_reg) &
 683                ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK) && timeout) {
 684                udelay(1);
 685                timeout--;
 686        }
 687
 688        if (!timeout)
 689                puts("ERROR:arasan_nand_write_buf timedout:Buff RDY\n");
 690
 691        reg_val = readl(&arasan_nand_base->intsts_enr);
 692        reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
 693        writel(reg_val, &arasan_nand_base->intsts_enr);
 694        writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 695               &arasan_nand_base->intsts_enr);
 696        reg_val = readl(&arasan_nand_base->intsts_reg);
 697        writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
 698               &arasan_nand_base->intsts_reg);
 699
 700        arasan_nand_fill_tx(buf, len);
 701
 702        timeout = ARASAN_NAND_POLL_TIMEOUT;
 703        while (!(readl(&arasan_nand_base->intsts_reg) &
 704                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 705                udelay(1);
 706                timeout--;
 707        }
 708        if (!timeout)
 709                puts("ERROR:arasan_nand_write_buf timedout:Xfer CMPLT\n");
 710
 711        writel(readl(&arasan_nand_base->intsts_enr) |
 712               ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 713               &arasan_nand_base->intsts_enr);
 714        writel(readl(&arasan_nand_base->intsts_reg) |
 715               ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 716               &arasan_nand_base->intsts_reg);
 717}
 718
 719static int arasan_nand_erase(struct arasan_nand_command_format *curr_cmd,
 720                              int column, int page_addr, struct mtd_info *mtd)
 721{
 722        u32 reg_val, page;
 723        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 724        u8 row_addr_cycles;
 725
 726        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 727               &arasan_nand_base->intsts_enr);
 728        reg_val = readl(&arasan_nand_base->cmd_reg);
 729        reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
 730        reg_val |= curr_cmd->cmd1 |
 731                   (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
 732        row_addr_cycles = arasan_nand_get_addrcycle(mtd);
 733
 734        if (row_addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
 735                return ERR_ADDR_CYCLE;
 736
 737        reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
 738        reg_val |= (row_addr_cycles <<
 739                    ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
 740
 741        writel(reg_val, &arasan_nand_base->cmd_reg);
 742
 743        page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
 744                ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
 745        column = page_addr & ARASAN_NAND_MEM_ADDR1_COL_MASK;
 746        writel(page | column, &arasan_nand_base->memadr_reg1);
 747
 748        reg_val = readl(&arasan_nand_base->memadr_reg2);
 749        reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
 750        reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
 751        writel(reg_val, &arasan_nand_base->memadr_reg2);
 752        reg_val = readl(&arasan_nand_base->memadr_reg2);
 753        reg_val &= ~ARASAN_NAND_MEM_ADDR2_CS_MASK;
 754        writel(reg_val, &arasan_nand_base->memadr_reg2);
 755        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 756
 757        while (!(readl(&arasan_nand_base->intsts_reg) &
 758                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 759                udelay(1);
 760                timeout--;
 761        }
 762        if (!timeout) {
 763                printf("ERROR:%s timedout:Xfer CMPLT\n", __func__);
 764                return -ETIMEDOUT;
 765        }
 766
 767        reg_val = readl(&arasan_nand_base->intsts_enr);
 768        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 769               &arasan_nand_base->intsts_enr);
 770        reg_val = readl(&arasan_nand_base->intsts_reg);
 771        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 772               &arasan_nand_base->intsts_reg);
 773
 774        return 0;
 775}
 776
 777static int arasan_nand_read_status(struct arasan_nand_command_format *curr_cmd,
 778                                int column, int page_addr, struct mtd_info *mtd)
 779{
 780        u32 reg_val;
 781        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 782        u8 addr_cycles;
 783
 784        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 785               &arasan_nand_base->intsts_enr);
 786        reg_val = readl(&arasan_nand_base->cmd_reg);
 787        reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
 788        reg_val |= curr_cmd->cmd1 |
 789                   (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
 790        addr_cycles = arasan_nand_get_addrcycle(mtd);
 791
 792        if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
 793                return ERR_ADDR_CYCLE;
 794
 795        reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
 796        reg_val |= (addr_cycles <<
 797                    ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
 798
 799        writel(reg_val, &arasan_nand_base->cmd_reg);
 800
 801        reg_val = readl(&arasan_nand_base->pkt_reg);
 802        reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
 803                     ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
 804        reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | 1;
 805        writel(reg_val, &arasan_nand_base->pkt_reg);
 806
 807        reg_val = readl(&arasan_nand_base->memadr_reg2);
 808        reg_val &= ~ARASAN_NAND_MEM_ADDR2_CS_MASK;
 809        writel(reg_val, &arasan_nand_base->memadr_reg2);
 810
 811        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 812        while (!(readl(&arasan_nand_base->intsts_reg) &
 813                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 814                udelay(1);
 815                timeout--;
 816        }
 817
 818        if (!timeout) {
 819                printf("ERROR:%s: timedout:Xfer CMPLT\n", __func__);
 820                return -ETIMEDOUT;
 821        }
 822
 823        reg_val = readl(&arasan_nand_base->intsts_enr);
 824        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 825               &arasan_nand_base->intsts_enr);
 826        reg_val = readl(&arasan_nand_base->intsts_reg);
 827        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 828               &arasan_nand_base->intsts_reg);
 829
 830        return 0;
 831}
 832
 833static int arasan_nand_send_rdcmd(struct arasan_nand_command_format *curr_cmd,
 834                               int column, int page_addr, struct mtd_info *mtd)
 835{
 836        u32 reg_val, addr_cycles, page;
 837        u8 page_val;
 838
 839        reg_val = readl(&arasan_nand_base->intsts_enr);
 840        writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 841               &arasan_nand_base->intsts_enr);
 842
 843        reg_val = readl(&arasan_nand_base->cmd_reg);
 844        reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
 845        reg_val |= curr_cmd->cmd1 |
 846                   (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
 847
 848        if (curr_cmd->cmd1 == NAND_CMD_RNDOUT ||
 849            curr_cmd->cmd1 == NAND_CMD_READ0) {
 850                reg_val &= ~ARASAN_NAND_CMD_PG_SIZE_MASK;
 851                page_val = arasan_nand_page(mtd);
 852                reg_val |= (page_val << ARASAN_NAND_CMD_PG_SIZE_SHIFT);
 853        }
 854
 855        reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
 856
 857        addr_cycles = arasan_nand_get_addrcycle(mtd);
 858
 859        if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
 860                return ERR_ADDR_CYCLE;
 861
 862        reg_val |= (addr_cycles << 28);
 863        writel(reg_val, &arasan_nand_base->cmd_reg);
 864
 865        if (page_addr == -1)
 866                page_addr = 0;
 867
 868        page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
 869                ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
 870        column &= ARASAN_NAND_MEM_ADDR1_COL_MASK;
 871        writel(page | column, &arasan_nand_base->memadr_reg1);
 872
 873        reg_val = readl(&arasan_nand_base->memadr_reg2);
 874        reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
 875        reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
 876        writel(reg_val, &arasan_nand_base->memadr_reg2);
 877
 878        reg_val = readl(&arasan_nand_base->memadr_reg2);
 879        reg_val &= ~ARASAN_NAND_MEM_ADDR2_CS_MASK;
 880        writel(reg_val, &arasan_nand_base->memadr_reg2);
 881        buf_index = 0;
 882
 883        return 0;
 884}
 885
 886static void arasan_nand_read_buf(struct mtd_info *mtd, u8 *buf, int size)
 887{
 888        u32 reg_val, i;
 889        u32 *bufptr = (u32 *)buf;
 890        u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
 891
 892        reg_val = readl(&arasan_nand_base->pkt_reg);
 893        reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
 894                     ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
 895        reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | size;
 896        writel(reg_val, &arasan_nand_base->pkt_reg);
 897
 898        writel(curr_cmd->pgm, &arasan_nand_base->pgm_reg);
 899
 900        while (!(readl(&arasan_nand_base->intsts_reg) &
 901                ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK) && timeout) {
 902                udelay(1);
 903                timeout--;
 904        }
 905
 906        if (!timeout)
 907                puts("ERROR:arasan_nand_read_buf timedout:Buff RDY\n");
 908
 909        reg_val = readl(&arasan_nand_base->intsts_enr);
 910        reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
 911        writel(reg_val, &arasan_nand_base->intsts_enr);
 912
 913        writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 914               &arasan_nand_base->intsts_enr);
 915        reg_val = readl(&arasan_nand_base->intsts_reg);
 916        writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
 917               &arasan_nand_base->intsts_reg);
 918
 919        buf_index = 0;
 920        for (i = 0; i < size / 4; i++)
 921                bufptr[i] = readl(&arasan_nand_base->buf_dataport);
 922
 923        if (size & 0x03)
 924                bufptr[i] = readl(&arasan_nand_base->buf_dataport);
 925
 926        timeout = ARASAN_NAND_POLL_TIMEOUT;
 927
 928        while (!(readl(&arasan_nand_base->intsts_reg) &
 929                ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
 930                udelay(1);
 931                timeout--;
 932        }
 933
 934        if (!timeout)
 935                puts("ERROR:arasan_nand_read_buf timedout:Xfer CMPLT\n");
 936
 937        reg_val = readl(&arasan_nand_base->intsts_enr);
 938        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 939               &arasan_nand_base->intsts_enr);
 940        reg_val = readl(&arasan_nand_base->intsts_reg);
 941        writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 942               &arasan_nand_base->intsts_reg);
 943}
 944
 945static u8 arasan_nand_read_byte(struct mtd_info *mtd)
 946{
 947        struct nand_chip *chip = mtd->priv;
 948        u32 size;
 949        u8 val;
 950        struct nand_onfi_params *p;
 951
 952        if (buf_index == 0) {
 953                p = &chip->onfi_params;
 954                if (curr_cmd->cmd1 == NAND_CMD_READID)
 955                        size = 4;
 956                else if (curr_cmd->cmd1 == NAND_CMD_PARAM)
 957                        size = sizeof(struct nand_onfi_params);
 958                else if (curr_cmd->cmd1 == NAND_CMD_RNDOUT)
 959                        size = le16_to_cpu(p->ext_param_page_length) * 16;
 960                else if (curr_cmd->cmd1 == NAND_CMD_GET_FEATURES)
 961                        size = 4;
 962                else if (curr_cmd->cmd1 == NAND_CMD_STATUS)
 963                        return readb(&arasan_nand_base->flash_sts_reg);
 964                else
 965                        size = 8;
 966                chip->read_buf(mtd, &buf_data[0], size);
 967        }
 968
 969        val = *(&buf_data[0] + buf_index);
 970        buf_index++;
 971
 972        return val;
 973}
 974
 975static void arasan_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
 976                                     int column, int page_addr)
 977{
 978        u32 i, ret = 0;
 979        struct nand_chip *chip = mtd->priv;
 980        struct arasan_nand_info *nand = chip->priv;
 981
 982        curr_cmd = NULL;
 983        writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
 984               &arasan_nand_base->intsts_enr);
 985
 986        if ((command == NAND_CMD_READOOB) &&
 987            (mtd->writesize > 512)) {
 988                column += mtd->writesize;
 989                command = NAND_CMD_READ0;
 990        }
 991
 992        /* Get the command format */
 993        for (i = 0; (arasan_nand_commands[i].cmd1 != NAND_CMD_NONE ||
 994                     arasan_nand_commands[i].cmd2 != NAND_CMD_NONE); i++) {
 995                if (command == arasan_nand_commands[i].cmd1) {
 996                        curr_cmd = &arasan_nand_commands[i];
 997                        break;
 998                }
 999        }
1000
1001        if (curr_cmd == NULL) {
1002                printf("Unsupported Command; 0x%x\n", command);
1003                return;
1004        }
1005
1006        if (curr_cmd->cmd1 == NAND_CMD_RESET)
1007                ret = arasan_nand_reset(curr_cmd);
1008
1009        if ((curr_cmd->cmd1 == NAND_CMD_READID) ||
1010            (curr_cmd->cmd1 == NAND_CMD_PARAM) ||
1011            (curr_cmd->cmd1 == NAND_CMD_RNDOUT) ||
1012            (curr_cmd->cmd1 == NAND_CMD_GET_FEATURES) ||
1013            (curr_cmd->cmd1 == NAND_CMD_READ0))
1014                ret = arasan_nand_send_rdcmd(curr_cmd, column, page_addr, mtd);
1015
1016        if ((curr_cmd->cmd1 == NAND_CMD_SET_FEATURES) ||
1017            (curr_cmd->cmd1 == NAND_CMD_SEQIN)) {
1018                nand->page = page_addr;
1019                ret = arasan_nand_send_wrcmd(curr_cmd, column, page_addr, mtd);
1020        }
1021
1022        if (curr_cmd->cmd1 == NAND_CMD_ERASE1)
1023                ret = arasan_nand_erase(curr_cmd, column, page_addr, mtd);
1024
1025        if (curr_cmd->cmd1 == NAND_CMD_STATUS)
1026                ret = arasan_nand_read_status(curr_cmd, column, page_addr, mtd);
1027
1028        if (ret != 0)
1029                printf("ERROR:%s:command:0x%x\n", __func__, curr_cmd->cmd1);
1030}
1031
1032static int arasan_nand_ecc_init(struct mtd_info *mtd)
1033{
1034        int found = -1;
1035        u32 regval, eccpos_start, i;
1036        struct nand_chip *nand_chip = mtd->priv;
1037
1038        nand_chip->ecc.mode = NAND_ECC_HW;
1039        nand_chip->ecc.hwctl = NULL;
1040        nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
1041        nand_chip->ecc.write_page = arasan_nand_write_page_hwecc;
1042        nand_chip->ecc.read_oob = arasan_nand_read_oob;
1043        nand_chip->ecc.write_oob = arasan_nand_write_oob;
1044
1045        for (i = 0; i < ARRAY_SIZE(ecc_matrix); i++) {
1046                if ((ecc_matrix[i].pagesize == mtd->writesize) &&
1047                    (ecc_matrix[i].ecc_codeword_size >=
1048                     nand_chip->ecc_step_ds)) {
1049                        if (ecc_matrix[i].eccbits >=
1050                            nand_chip->ecc_strength_ds) {
1051                                found = i;
1052                                break;
1053                        }
1054                        found = i;
1055                }
1056        }
1057
1058        if (found < 0)
1059                return 1;
1060
1061        regval = ecc_matrix[i].eccaddr |
1062                 (ecc_matrix[i].eccsize << ARASAN_NAND_ECC_SIZE_SHIFT) |
1063                 (ecc_matrix[i].bch << ARASAN_NAND_ECC_BCH_SHIFT);
1064        writel(regval, &arasan_nand_base->ecc_reg);
1065
1066        if (ecc_matrix[i].bch) {
1067                regval = readl(&arasan_nand_base->memadr_reg2);
1068                regval &= ~ARASAN_NAND_MEM_ADDR2_BCH_MASK;
1069                regval |= (ecc_matrix[i].bchval <<
1070                           ARASAN_NAND_MEM_ADDR2_BCH_SHIFT);
1071                writel(regval, &arasan_nand_base->memadr_reg2);
1072        }
1073
1074        nand_oob.eccbytes = ecc_matrix[i].eccsize;
1075        eccpos_start = mtd->oobsize - nand_oob.eccbytes;
1076
1077        for (i = 0; i < nand_oob.eccbytes; i++)
1078                nand_oob.eccpos[i] = eccpos_start + i;
1079
1080        nand_oob.oobfree[0].offset = 2;
1081        nand_oob.oobfree[0].length = eccpos_start - 2;
1082
1083        nand_chip->ecc.size = ecc_matrix[i].ecc_codeword_size;
1084        nand_chip->ecc.strength = ecc_matrix[i].eccbits;
1085        nand_chip->ecc.bytes = ecc_matrix[i].eccsize;
1086        nand_chip->ecc.layout = &nand_oob;
1087
1088        return 0;
1089}
1090
1091static int arasan_nand_init(struct nand_chip *nand_chip, int devnum)
1092{
1093        struct arasan_nand_info *nand;
1094        struct mtd_info *mtd;
1095        int err = -1;
1096
1097        nand = calloc(1, sizeof(struct arasan_nand_info));
1098        if (!nand) {
1099                printf("%s: failed to allocate\n", __func__);
1100                return err;
1101        }
1102
1103        nand->nand_base = arasan_nand_base;
1104        mtd = &nand_info[0];
1105        nand_chip->priv = nand;
1106        mtd->priv = nand_chip;
1107
1108        /* Set the driver entry points for MTD */
1109        nand_chip->cmdfunc = arasan_nand_cmd_function;
1110        nand_chip->select_chip = arasan_nand_select_chip;
1111        nand_chip->read_byte = arasan_nand_read_byte;
1112
1113        /* Buffer read/write routines */
1114        nand_chip->read_buf = arasan_nand_read_buf;
1115        nand_chip->write_buf = arasan_nand_write_buf;
1116        nand_chip->bbt_options = NAND_BBT_USE_FLASH;
1117
1118        writel(0x0, &arasan_nand_base->cmd_reg);
1119        writel(0x0, &arasan_nand_base->pgm_reg);
1120
1121        /* first scan to find the device and get the page size */
1122        if (nand_scan_ident(mtd, 1, NULL)) {
1123                printf("%s: nand_scan_ident failed\n", __func__);
1124                goto fail;
1125        }
1126
1127        if (arasan_nand_ecc_init(mtd)) {
1128                printf("%s: nand_ecc_init failed\n", __func__);
1129                goto fail;
1130        }
1131
1132        if (nand_scan_tail(mtd)) {
1133                printf("%s: nand_scan_tail failed\n", __func__);
1134                goto fail;
1135        }
1136
1137        if (nand_register(devnum)) {
1138                printf("Nand Register Fail\n");
1139                goto fail;
1140        }
1141
1142        return 0;
1143fail:
1144        free(nand);
1145        return err;
1146}
1147
1148void board_nand_init(void)
1149{
1150        struct nand_chip *nand = &nand_chip[0];
1151
1152        if (arasan_nand_init(nand, 0))
1153                puts("NAND init failed\n");
1154}
1155