mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
ipq40xx: Add SPI NAND support
Change-Id: I74de22fcea6455f73f263672b72b30b796f6c820 Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
This commit is contained in:
parent
adaaa17195
commit
f44fe93184
4 changed files with 69 additions and 26 deletions
|
|
@ -135,6 +135,11 @@ void board_nand_init(void)
|
|||
qca_gpio_init(gpio_node);
|
||||
ipq_spi_init(CONFIG_IPQ_SPI_NOR_INFO_IDX);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_NAND
|
||||
if (fdtdec_get_uint(gd->fdt_blob, 0, "spi_nand_available", 0))
|
||||
spi_nand_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ipq40xx_edma_common_init(void)
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o sf_params.o sf.o
|
|||
obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
|
||||
obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
|
||||
obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
|
||||
obj-$(CONFIG_SPI_NAND) += spi_nand.o
|
||||
|
|
|
|||
|
|
@ -957,6 +957,14 @@ int spi_flash_scan(struct spi_flash *flash)
|
|||
}
|
||||
|
||||
if (!params->name) {
|
||||
#ifdef CONFIG_SPI_NAND
|
||||
ret = spi_nand_flash_probe(spi, flash, idcode);
|
||||
|
||||
if (!ret) {
|
||||
flash->addr_width = flash->size > 0x1000000 ? 4 : 3;
|
||||
goto print_sf_info;
|
||||
}
|
||||
#endif
|
||||
printf("SF: Unsupported flash IDs: ");
|
||||
printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
|
||||
idcode[0], jedec, ext_jedec);
|
||||
|
|
@ -1120,6 +1128,7 @@ int spi_flash_scan(struct spi_flash *flash)
|
|||
}
|
||||
#endif
|
||||
|
||||
print_sf_info:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
printf("SF: Detected %s with page size ", flash->name);
|
||||
print_size(flash->page_size, ", erase size ");
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
#include <linux/mtd/nand.h>
|
||||
#include <spi_flash.h>
|
||||
#include <asm/errno.h>
|
||||
#include "spi_flash_internal.h"
|
||||
#include "spi_nand_dev.h"
|
||||
#include <malloc.h>
|
||||
#include "spi.h"
|
||||
#include <watchdog.h>
|
||||
|
||||
#define CONFIG_SF_DEFAULT_SPEED (48 * 1000 * 1000)
|
||||
#define TIMEOUT 5000
|
||||
|
|
@ -172,6 +173,41 @@ void winbond_norm_read_cmd(u8 *cmd, int column)
|
|||
cmd[3] = 0;
|
||||
}
|
||||
|
||||
int spi_nand_flash_cmd_poll_bit(struct spi_flash *flash, unsigned long timeout,
|
||||
u8 cmd, u8 poll_bit, u8 *status)
|
||||
{
|
||||
struct spi_slave *spi = flash->spi;
|
||||
unsigned long timebase;
|
||||
u8 cmd_buf[2];
|
||||
|
||||
cmd_buf[0] = 0x0F;
|
||||
cmd_buf[1] = cmd;
|
||||
|
||||
timebase = get_timer(0);
|
||||
do {
|
||||
WATCHDOG_RESET();
|
||||
|
||||
spi_flash_cmd_read(spi, cmd_buf, 2, status, 1);
|
||||
if ((*status & poll_bit) == 0)
|
||||
break;
|
||||
|
||||
} while (get_timer(timebase) < timeout);
|
||||
|
||||
if ((*status & poll_bit) == 0)
|
||||
return 0;
|
||||
|
||||
/* Timed out */
|
||||
debug("SF: time out!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int spi_nand_flash_cmd_wait_ready(struct spi_flash *flash, u8 status_bit, u8 *status,
|
||||
unsigned long timeout)
|
||||
{
|
||||
return spi_nand_flash_cmd_poll_bit(flash, timeout,
|
||||
0xC0, status_bit, status);
|
||||
}
|
||||
|
||||
static int spinand_waitfunc(struct mtd_info *mtd, u8 val, u8 *status)
|
||||
{
|
||||
struct ipq40xx_spinand_info *info = mtd_to_ipq_info(mtd);
|
||||
|
|
@ -644,7 +680,7 @@ static int spi_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
|
|||
struct mtd_oob_ops ops = {0};
|
||||
u32 ret;
|
||||
|
||||
ops.mode = MTD_OOB_AUTO;
|
||||
ops.mode = MTD_OPS_AUTO_OOB;
|
||||
ops.len = len;
|
||||
ops.datbuf = (uint8_t *)buf;
|
||||
ret = spi_nand_read_std(mtd, from, &ops);
|
||||
|
|
@ -748,6 +784,8 @@ static int spi_nand_write_std(struct mtd_info *mtd, loff_t to, struct mtd_oob_op
|
|||
}
|
||||
if (ops->ooblen)
|
||||
ret = spi_nand_write_oob_data(mtd, to, ops);
|
||||
|
||||
ops->retlen += bytes;
|
||||
write_len -= bytes;
|
||||
if (!write_len)
|
||||
break;
|
||||
|
|
@ -771,6 +809,7 @@ static int spi_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
|
|||
ops.len = len;
|
||||
ops.datbuf = (uint8_t *)buf;
|
||||
ret = spi_nand_write_std(mtd, to, &ops);
|
||||
*retlen = ops.retlen;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -789,10 +828,9 @@ static int spi_nand_write_oob(struct mtd_info *mtd, loff_t to,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct spi_flash *spi_nand_flash_probe(struct spi_slave *spi,
|
||||
u8 *idcode)
|
||||
int spi_nand_flash_probe(struct spi_slave *spi, struct spi_flash *flash,
|
||||
u8 *idcode)
|
||||
{
|
||||
struct spi_flash *flash;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spi_nand_flash_tbl); i++) {
|
||||
|
|
@ -809,25 +847,16 @@ struct spi_flash *spi_nand_flash_probe(struct spi_slave *spi,
|
|||
}
|
||||
|
||||
if (i == ARRAY_SIZE(spi_nand_flash_tbl)) {
|
||||
printf("SF NAND unsupported id:%x:%x:%x:%x",
|
||||
idcode[0], idcode[1], idcode[2], idcode[3]);
|
||||
return NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flash = (struct spi_flash *)malloc(sizeof (*flash));
|
||||
if (!flash) {
|
||||
printf ("SF Failed to allocate memeory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
flash->spi = spi;
|
||||
|
||||
flash->name = params->name;
|
||||
flash->page_size = params->page_size;
|
||||
flash->sector_size = params->page_size;
|
||||
flash->erase_size = params->erase_size;
|
||||
flash->size = (params->page_size * params->nr_sectors * params->pages_per_sector);
|
||||
|
||||
return flash;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spinand_unlock_protect(struct mtd_info *mtd)
|
||||
|
|
@ -962,20 +991,19 @@ int spi_nand_init(void)
|
|||
|
||||
mtd->priv = chip;
|
||||
mtd->writesize = flash->page_size;
|
||||
mtd->writebufsize = mtd->writesize;
|
||||
mtd->erasesize = params->erase_size;
|
||||
mtd->oobsize = params->oob_size;
|
||||
mtd->size = flash->size;
|
||||
mtd->type = MTD_NANDFLASH;
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->point = NULL;
|
||||
mtd->unpoint = NULL;
|
||||
mtd->read = spi_nand_read;
|
||||
mtd->write = spi_nand_write;
|
||||
mtd->erase = spi_nand_erase;
|
||||
mtd->read_oob = spi_nand_read_oob;
|
||||
mtd->write_oob = spi_nand_write_oob;
|
||||
mtd->block_isbad = spi_nand_block_isbad;
|
||||
mtd->block_markbad = spi_nand_block_markbad;
|
||||
mtd->_read = spi_nand_read;
|
||||
mtd->_write = spi_nand_write;
|
||||
mtd->_erase = spi_nand_erase;
|
||||
mtd->_read_oob = spi_nand_read_oob;
|
||||
mtd->_write_oob = spi_nand_write_oob;
|
||||
mtd->_block_isbad = spi_nand_block_isbad;
|
||||
mtd->_block_markbad = spi_nand_block_markbad;
|
||||
|
||||
chip->page_shift = ffs(mtd->writesize) - 1;
|
||||
chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue