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