X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fmtd%2Fnand%2Fam335x_spl_bch.c;h=e68b4a5b19612ab5fee44f57b1270afef5cb73de;hb=6f84b26b53afa207092a8906fa08f4c78d65afb6;hp=f8770e0ad8e767bbd7e31cb84311f9310bbd7371;hpb=ffd859979e2a84bccc14188d9fa760b2e4813515;p=oweals%2Fu-boot.git diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c index f8770e0ad8..e68b4a5b19 100644 --- a/drivers/mtd/nand/am335x_spl_bch.c +++ b/drivers/mtd/nand/am335x_spl_bch.c @@ -49,6 +49,13 @@ static int nand_command(int block, int page, uint32_t offs, if (cmd == NAND_CMD_RESET) { hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + + /* + * Apply this short delay always to ensure that we do wait + * tWB in any case on any machine. + */ + ndelay(150); + while (!this->dev_ready(mtd)) ; return 0; @@ -78,23 +85,44 @@ static int nand_command(int block, int page, uint32_t offs, hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - if (cmd == NAND_CMD_READ0) { - /* Latch in address */ - hwctrl(mtd, NAND_CMD_READSTART, - NAND_CTRL_CLE | NAND_CTRL_CHANGE); - hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - /* - * Wait a while for the data to be ready - */ - while (!this->dev_ready(mtd)) - ; - } else if (cmd == NAND_CMD_RNDOUT) { + /* + * Program and erase have their own busy handlers status, sequential + * in and status need no delay. + */ + switch (cmd) { + case NAND_CMD_CACHEDPROG: + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE1: + case NAND_CMD_ERASE2: + case NAND_CMD_SEQIN: + case NAND_CMD_RNDIN: + case NAND_CMD_STATUS: + return 0; + + case NAND_CMD_RNDOUT: + /* No ready / busy check necessary */ hwctrl(mtd, NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE | - NAND_CTRL_CHANGE); + NAND_CTRL_CHANGE); + hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + return 0; + + case NAND_CMD_READ0: + /* Latch in address */ + hwctrl(mtd, NAND_CMD_READSTART, + NAND_CTRL_CLE | NAND_CTRL_CHANGE); hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); } + /* + * Apply this short delay always to ensure that we do wait tWB in + * any case on any machine. + */ + ndelay(150); + + while (!this->dev_ready(mtd)) + ; + return 0; } @@ -170,60 +198,13 @@ static int nand_read_page(int block, int page, void *dst) return 0; } -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) -{ - unsigned int block, lastblock; - unsigned int page, page_offset; - - /* - * offs has to be aligned to a page address! - */ - block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; - lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; - page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; - page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE; - - while (block <= lastblock) { - if (!nand_is_bad_block(block)) { - /* - * Skip bad blocks - */ - while (page < CONFIG_SYS_NAND_PAGE_COUNT) { - nand_read_page(block, page, dst); - /* - * When offs is not aligned to page address the - * extra offset is copied to dst as well. Copy - * the image such that its first byte will be - * at the dst. - */ - if (unlikely(page_offset)) { - memmove(dst, dst + page_offset, - CONFIG_SYS_NAND_PAGE_SIZE); - dst = (void *)((int)dst - page_offset); - page_offset = 0; - } - dst += CONFIG_SYS_NAND_PAGE_SIZE; - page++; - } - - page = 0; - } else { - lastblock++; - } - - block++; - } - - return 0; -} - /* nand_init() - initialize data to make nand usable by SPL */ void nand_init(void) { /* * Init board specific nand support */ - mtd = &nand_chip.mtd; + mtd = nand_to_mtd(&nand_chip); nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W = (void __iomem *)CONFIG_SYS_NAND_BASE; board_nand_init(&nand_chip); @@ -241,3 +222,5 @@ void nand_deselect(void) if (nand_chip.select_chip) nand_chip.select_chip(mtd, -1); } + +#include "nand_spl_loaders.c"