staticint bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code)
{ int i = 0;
bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code); for (i = 0; i < NFLASH_READY_RETRIES; i++) { if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) {
i = 0; break;
}
} if (i) {
pr_err("NFLASH control command not ready!\n"); return -EBUSY;
} return0;
}
staticint bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc)
{ int i;
for (i = 0; i < NFLASH_READY_RETRIES; i++) { if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) { if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) &
BCMA_CC_NFLASH_CTL_ERR) {
pr_err("Error on polling\n"); return -EBUSY;
} else { return0;
}
}
}
u32 ctlcode;
u32 *dest = (u32 *)buf; int i; int toread;
BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); /* Don't validate column using nand_chip->page_shift, it may be bigger
* when accessing OOB */
while (len) { /* We can read maximum of 0x200 bytes at once */
toread = min(len, 0x200);
/* Set page and column */
bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR,
b47n->curr_column);
bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR,
b47n->curr_page_addr);
/* Prepare to read */
ctlcode = NCTL_CSA | NCTL_CMD1W | NCTL_ROW | NCTL_COL |
NCTL_CMD0;
ctlcode |= NAND_CMD_READSTART << 8; if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) return; if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc)) return;
/* Eventually read some data :) */ for (i = 0; i < toread; i += 4, dest++) {
ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ; if (i == toread - 4) /* Last read goes without that */
ctlcode &= ~NCTL_CSA; if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc,
ctlcode)) return;
*dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA);
}
BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); /* Don't validate column using nand_chip->page_shift, it may be bigger
* when accessing OOB */
for (i = 0; i < len; i += 4, data++) {
bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data);
ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE; if (i == len - 4) /* Last read goes without that */
ctlcode &= ~NCTL_CSA; if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) {
pr_err("%s ctl_cmd didn't work!\n", __func__); return;
}
}
staticvoid bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct nand_chip *nand_chip, int cmd, unsignedint ctrl)
{ struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip);
u32 code = 0; int rc;
if (cmd == NAND_CMD_NONE) return;
if (cmd & NAND_CTRL_CLE)
code = cmd | NCTL_CMD0;
/* nCS is not needed for reset command */ if (cmd != NAND_CMD_RESET)
code |= NCTL_CSA;
rc = bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, code); if (rc)
pr_err("ctl_cmd didn't work with error %d\n", rc);
}
/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */ staticvoid bcm47xxnflash_ops_bcm4706_select_chip(struct nand_chip *chip, int cs)
{ return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.