452 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * BCM47XX NAND flash driver4 *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 has17 * shown ~1000 retries as maximum. */18#define NFLASH_READY_RETRIES 1000019 20#define NFLASH_SECTOR_SIZE 51221 22#define NCTL_CMD0 0x0001000023#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 0x0008000026#define NCTL_READ 0x0010000027#define NCTL_WRITE 0x0020000028#define NCTL_SPECADDR 0x0100000029#define NCTL_READY 0x0400000030#define NCTL_ERR 0x0800000031#define NCTL_CSA 0x4000000032#define NCTL_START 0x8000000033 34/**************************************************35 * Various helpers36 **************************************************/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/W83 **************************************************/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 bigger98 * 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 bigger148 * 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 ops167 **************************************************/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 special206 * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert207 * 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_CSA241 * bit. We don't know how many reads NAND subsystem is going242 * 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 * Init368 **************************************************/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 /* TODO: implement ECC */395 b47n->nand_chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_NONE;396 397 /* Enable NAND flash access */398 bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG,399 BCMA_CC_4706_FLASHSCFG_NF1);400 401 /* Configure wait counters */402 if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) {403 /* 400 MHz */404 freq = 400000000 / 4;405 } else {406 freq = bcma_chipco_pll_read(b47n->cc, 4);407 freq = (freq & 0xFFF) >> 3;408 /* Fixed reference clock 25 MHz and m = 2 */409 freq = (freq * 25000000 / 2) / 4;410 }411 clock = freq / 1000000;412 w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock);413 w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock);414 w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);415 w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock);416 w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock);417 bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0,418 (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0));419 420 /* Scan NAND */421 err = nand_scan(&b47n->nand_chip, 1);422 if (err) {423 pr_err("Could not scan NAND flash: %d\n", err);424 goto exit;425 }426 427 /* Configure FLASH */428 chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20;429 tbits = ffs(chipsize); /* find first bit set */430 if (!tbits || tbits != fls(chipsize)) {431 pr_err("Invalid flash size: 0x%lX\n", chipsize);432 err = -ENOTSUPP;433 goto exit;434 }435 tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */436 437 col_bits = b47n->nand_chip.page_shift + 1;438 col_size = (col_bits + 7) / 8;439 440 row_bits = tbits - col_bits + 1;441 row_bsize = (row_bits + 7) / 8;442 443 val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2;444 bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val);445 446exit:447 if (err)448 bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG,449 ~BCMA_CC_4706_FLASHSCFG_NF1);450 return err;451}452