linux/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c
<<
>>
Prefs
   1/*
   2 * BCM47XX NAND flash driver
   3 *
   4 * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11
  12#include "bcm47xxnflash.h"
  13
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/slab.h>
  17#include <linux/delay.h>
  18#include <linux/bcma/bcma.h>
  19
  20/* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has
  21 * shown ~1000 retries as maxiumum. */
  22#define NFLASH_READY_RETRIES            10000
  23
  24#define NFLASH_SECTOR_SIZE              512
  25
  26#define NCTL_CMD0                       0x00010000
  27#define NCTL_COL                        0x00020000      /* Update column with value from BCMA_CC_NFLASH_COL_ADDR */
  28#define NCTL_ROW                        0x00040000      /* Update row (page) with value from BCMA_CC_NFLASH_ROW_ADDR */
  29#define NCTL_CMD1W                      0x00080000
  30#define NCTL_READ                       0x00100000
  31#define NCTL_WRITE                      0x00200000
  32#define NCTL_SPECADDR                   0x01000000
  33#define NCTL_READY                      0x04000000
  34#define NCTL_ERR                        0x08000000
  35#define NCTL_CSA                        0x40000000
  36#define NCTL_START                      0x80000000
  37
  38/**************************************************
  39 * Various helpers
  40 **************************************************/
  41
  42static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock)
  43{
  44        return ((ns * 1000 * clock) / 1000000) + 1;
  45}
  46
  47static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code)
  48{
  49        int i = 0;
  50
  51        bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code);
  52        for (i = 0; i < NFLASH_READY_RETRIES; i++) {
  53                if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) {
  54                        i = 0;
  55                        break;
  56                }
  57        }
  58        if (i) {
  59                pr_err("NFLASH control command not ready!\n");
  60                return -EBUSY;
  61        }
  62        return 0;
  63}
  64
  65static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc)
  66{
  67        int i;
  68
  69        for (i = 0; i < NFLASH_READY_RETRIES; i++) {
  70                if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) {
  71                        if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) &
  72                            BCMA_CC_NFLASH_CTL_ERR) {
  73                                pr_err("Error on polling\n");
  74                                return -EBUSY;
  75                        } else {
  76                                return 0;
  77                        }
  78                }
  79        }
  80
  81        pr_err("Polling timeout!\n");
  82        return -EBUSY;
  83}
  84
  85/**************************************************
  86 * R/W
  87 **************************************************/
  88
  89static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf,
  90                                           int len)
  91{
  92        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
  93        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
  94
  95        u32 ctlcode;
  96        u32 *dest = (u32 *)buf;
  97        int i;
  98        int toread;
  99
 100        BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask);
 101        /* Don't validate column using nand_chip->page_shift, it may be bigger
 102         * when accessing OOB */
 103
 104        while (len) {
 105                /* We can read maximum of 0x200 bytes at once */
 106                toread = min(len, 0x200);
 107
 108                /* Set page and column */
 109                bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR,
 110                                b47n->curr_column);
 111                bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR,
 112                                b47n->curr_page_addr);
 113
 114                /* Prepare to read */
 115                ctlcode = NCTL_CSA | NCTL_CMD1W | NCTL_ROW | NCTL_COL |
 116                          NCTL_CMD0;
 117                ctlcode |= NAND_CMD_READSTART << 8;
 118                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode))
 119                        return;
 120                if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc))
 121                        return;
 122
 123                /* Eventually read some data :) */
 124                for (i = 0; i < toread; i += 4, dest++) {
 125                        ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ;
 126                        if (i == toread - 4) /* Last read goes without that */
 127                                ctlcode &= ~NCTL_CSA;
 128                        if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
 129                                                              ctlcode))
 130                                return;
 131                        *dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA);
 132                }
 133
 134                b47n->curr_column += toread;
 135                len -= toread;
 136        }
 137}
 138
 139static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd,
 140                                            const uint8_t *buf, int len)
 141{
 142        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 143        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 144        struct bcma_drv_cc *cc = b47n->cc;
 145
 146        u32 ctlcode;
 147        const u32 *data = (u32 *)buf;
 148        int i;
 149
 150        BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask);
 151        /* Don't validate column using nand_chip->page_shift, it may be bigger
 152         * when accessing OOB */
 153
 154        for (i = 0; i < len; i += 4, data++) {
 155                bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data);
 156
 157                ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE;
 158                if (i == len - 4) /* Last read goes without that */
 159                        ctlcode &= ~NCTL_CSA;
 160                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) {
 161                        pr_err("%s ctl_cmd didn't work!\n", __func__);
 162                        return;
 163                }
 164        }
 165
 166        b47n->curr_column += len;
 167}
 168
 169/**************************************************
 170 * NAND chip ops
 171 **************************************************/
 172
 173static void bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct mtd_info *mtd, int cmd,
 174                                               unsigned int ctrl)
 175{
 176        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 177        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 178        u32 code = 0;
 179
 180        if (cmd == NAND_CMD_NONE)
 181                return;
 182
 183        if (cmd & NAND_CTRL_CLE)
 184                code = cmd | NCTL_CMD0;
 185
 186        /* nCS is not needed for reset command */
 187        if (cmd != NAND_CMD_RESET)
 188                code |= NCTL_CSA;
 189
 190        bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, code);
 191}
 192
 193/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */
 194static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd,
 195                                                  int chip)
 196{
 197        return;
 198}
 199
 200static int bcm47xxnflash_ops_bcm4706_dev_ready(struct mtd_info *mtd)
 201{
 202        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 203        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 204
 205        return !!(bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_CTL) & NCTL_READY);
 206}
 207
 208/*
 209 * Default nand_command and nand_command_lp don't match BCM4706 hardware layout.
 210 * For example, reading chip id is performed in a non-standard way.
 211 * Setting column and page is also handled differently, we use a special
 212 * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert
 213 * standard commands would be much more complicated.
 214 */
 215static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd,
 216                                              unsigned command, int column,
 217                                              int page_addr)
 218{
 219        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 220        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 221        struct bcma_drv_cc *cc = b47n->cc;
 222        u32 ctlcode;
 223        int i;
 224
 225        if (column != -1)
 226                b47n->curr_column = column;
 227        if (page_addr != -1)
 228                b47n->curr_page_addr = page_addr;
 229
 230        switch (command) {
 231        case NAND_CMD_RESET:
 232                nand_chip->cmd_ctrl(mtd, command, NAND_CTRL_CLE);
 233
 234                ndelay(100);
 235                nand_wait_ready(mtd);
 236                break;
 237        case NAND_CMD_READID:
 238                ctlcode = NCTL_CSA | 0x01000000 | NCTL_CMD1W | NCTL_CMD0;
 239                ctlcode |= NAND_CMD_READID;
 240                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) {
 241                        pr_err("READID error\n");
 242                        break;
 243                }
 244
 245                /*
 246                 * Reading is specific, last one has to go without NCTL_CSA
 247                 * bit. We don't know how many reads NAND subsystem is going
 248                 * to perform, so cache everything.
 249                 */
 250                for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) {
 251                        ctlcode = NCTL_CSA | NCTL_READ;
 252                        if (i == ARRAY_SIZE(b47n->id_data) - 1)
 253                                ctlcode &= ~NCTL_CSA;
 254                        if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
 255                                                              ctlcode)) {
 256                                pr_err("READID error\n");
 257                                break;
 258                        }
 259                        b47n->id_data[i] =
 260                                bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA)
 261                                & 0xFF;
 262                }
 263
 264                break;
 265        case NAND_CMD_STATUS:
 266                ctlcode = NCTL_CSA | NCTL_CMD0 | NAND_CMD_STATUS;
 267                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
 268                        pr_err("STATUS command error\n");
 269                break;
 270        case NAND_CMD_READ0:
 271                break;
 272        case NAND_CMD_READOOB:
 273                if (page_addr != -1)
 274                        b47n->curr_column += mtd->writesize;
 275                break;
 276        case NAND_CMD_ERASE1:
 277                bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR,
 278                                b47n->curr_page_addr);
 279                ctlcode = NCTL_ROW | NCTL_CMD1W | NCTL_CMD0 |
 280                          NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8);
 281                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
 282                        pr_err("ERASE1 failed\n");
 283                break;
 284        case NAND_CMD_ERASE2:
 285                break;
 286        case NAND_CMD_SEQIN:
 287                /* Set page and column */
 288                bcma_cc_write32(cc, BCMA_CC_NFLASH_COL_ADDR,
 289                                b47n->curr_column);
 290                bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR,
 291                                b47n->curr_page_addr);
 292
 293                /* Prepare to write */
 294                ctlcode = 0x40000000 | NCTL_ROW | NCTL_COL | NCTL_CMD0;
 295                ctlcode |= NAND_CMD_SEQIN;
 296                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode))
 297                        pr_err("SEQIN failed\n");
 298                break;
 299        case NAND_CMD_PAGEPROG:
 300                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_CMD0 |
 301                                                          NAND_CMD_PAGEPROG))
 302                        pr_err("PAGEPROG failed\n");
 303                if (bcm47xxnflash_ops_bcm4706_poll(cc))
 304                        pr_err("PAGEPROG not ready\n");
 305                break;
 306        default:
 307                pr_err("Command 0x%X unsupported\n", command);
 308                break;
 309        }
 310        b47n->curr_command = command;
 311}
 312
 313static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd)
 314{
 315        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 316        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 317        struct bcma_drv_cc *cc = b47n->cc;
 318        u32 tmp = 0;
 319
 320        switch (b47n->curr_command) {
 321        case NAND_CMD_READID:
 322                if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) {
 323                        pr_err("Requested invalid id_data: %d\n",
 324                               b47n->curr_column);
 325                        return 0;
 326                }
 327                return b47n->id_data[b47n->curr_column++];
 328        case NAND_CMD_STATUS:
 329                if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_READ))
 330                        return 0;
 331                return bcma_cc_read32(cc, BCMA_CC_NFLASH_DATA) & 0xff;
 332        case NAND_CMD_READOOB:
 333                bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4);
 334                return tmp & 0xFF;
 335        }
 336
 337        pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command);
 338        return 0;
 339}
 340
 341static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd,
 342                                               uint8_t *buf, int len)
 343{
 344        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 345        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 346
 347        switch (b47n->curr_command) {
 348        case NAND_CMD_READ0:
 349        case NAND_CMD_READOOB:
 350                bcm47xxnflash_ops_bcm4706_read(mtd, buf, len);
 351                return;
 352        }
 353
 354        pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command);
 355}
 356
 357static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd,
 358                                                const uint8_t *buf, int len)
 359{
 360        struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv;
 361        struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv;
 362
 363        switch (b47n->curr_command) {
 364        case NAND_CMD_SEQIN:
 365                bcm47xxnflash_ops_bcm4706_write(mtd, buf, len);
 366                return;
 367        }
 368
 369        pr_err("Invalid command for buf write: 0x%X\n", b47n->curr_command);
 370}
 371
 372/**************************************************
 373 * Init
 374 **************************************************/
 375
 376int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
 377{
 378        struct nand_chip *nand_chip = (struct nand_chip *)&b47n->nand_chip;
 379        int err;
 380        u32 freq;
 381        u16 clock;
 382        u8 w0, w1, w2, w3, w4;
 383
 384        unsigned long chipsize; /* MiB */
 385        u8 tbits, col_bits, col_size, row_bits, row_bsize;
 386        u32 val;
 387
 388        b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip;
 389        nand_chip->cmd_ctrl = bcm47xxnflash_ops_bcm4706_cmd_ctrl;
 390        nand_chip->dev_ready = bcm47xxnflash_ops_bcm4706_dev_ready;
 391        b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc;
 392        b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte;
 393        b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf;
 394        b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf;
 395
 396        nand_chip->chip_delay = 50;
 397        b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH;
 398        b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */
 399
 400        /* Enable NAND flash access */
 401        bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG,
 402                      BCMA_CC_4706_FLASHSCFG_NF1);
 403
 404        /* Configure wait counters */
 405        if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) {
 406                /* 400 MHz */
 407                freq = 400000000 / 4;
 408        } else {
 409                freq = bcma_chipco_pll_read(b47n->cc, 4);
 410                freq = (freq & 0xFFF) >> 3;
 411                /* Fixed reference clock 25 MHz and m = 2 */
 412                freq = (freq * 25000000 / 2) / 4;
 413        }
 414        clock = freq / 1000000;
 415        w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock);
 416        w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock);
 417        w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);
 418        w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);
 419        w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock);
 420        bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0,
 421                        (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0));
 422
 423        /* Scan NAND */
 424        err = nand_scan(&b47n->mtd, 1);
 425        if (err) {
 426                pr_err("Could not scan NAND flash: %d\n", err);
 427                goto exit;
 428        }
 429
 430        /* Configure FLASH */
 431        chipsize = b47n->nand_chip.chipsize >> 20;
 432        tbits = ffs(chipsize); /* find first bit set */
 433        if (!tbits || tbits != fls(chipsize)) {
 434                pr_err("Invalid flash size: 0x%lX\n", chipsize);
 435                err = -ENOTSUPP;
 436                goto exit;
 437        }
 438        tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */
 439
 440        col_bits = b47n->nand_chip.page_shift + 1;
 441        col_size = (col_bits + 7) / 8;
 442
 443        row_bits = tbits - col_bits + 1;
 444        row_bsize = (row_bits + 7) / 8;
 445
 446        val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2;
 447        bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val);
 448
 449exit:
 450        if (err)
 451                bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG,
 452                               ~BCMA_CC_4706_FLASHSCFG_NF1);
 453        return err;
 454}
 455