x1000: move NAND commands to chip data

Using predefined commands is too inflexible so allow the chip data
to specify I/O commands directly.

Change-Id: Ie8f943914da4b8299678a59b1063c4c6d226e83e
This commit is contained in:
Aidan MacDonald 2022-06-23 16:37:02 +01:00
parent 2fce0a98f8
commit 9ab5d311cb
2 changed files with 18 additions and 35 deletions

View file

@ -31,8 +31,6 @@ const struct nand_chip supported_nand_chips[] = {
/* ATO25D1GA */ /* ATO25D1GA */
.mf_id = 0x9b, .mf_id = 0x9b,
.dev_id = 0x12, .dev_id = 0x12,
.row_cycles = 3,
.col_cycles = 2,
.log2_ppb = 6, /* 64 pages */ .log2_ppb = 6, /* 64 pages */
.page_size = 2048, .page_size = 2048,
.oob_size = 64, .oob_size = 64,
@ -46,6 +44,11 @@ const struct nand_chip supported_nand_chips[] = {
STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS), STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS),
SMP_DELAY(1)), SMP_DELAY(1)),
.flags = NAND_CHIPFLAG_QUAD | NAND_CHIPFLAG_HAS_QE_BIT, .flags = NAND_CHIPFLAG_QUAD | NAND_CHIPFLAG_HAS_QE_BIT,
.cmd_page_read = NANDCMD_PAGE_READ(3),
.cmd_program_execute = NANDCMD_PROGRAM_EXECUTE(3),
.cmd_block_erase = NANDCMD_BLOCK_ERASE(3),
.cmd_read_cache = NANDCMD_READ_CACHE_x4(2),
.cmd_program_load = NANDCMD_PROGRAM_LOAD_x4(2),
}, },
#else #else
{ 0 }, { 0 },
@ -127,22 +130,6 @@ static void setup_chip_data(struct nand_drv* drv)
drv->fpage_size = drv->chip->page_size + drv->chip->oob_size; drv->fpage_size = drv->chip->page_size + drv->chip->oob_size;
} }
static void setup_chip_commands(struct nand_drv* drv)
{
/* Select commands appropriate for the chip */
drv->cmd_page_read = NANDCMD_PAGE_READ(drv->chip->row_cycles);
drv->cmd_program_execute = NANDCMD_PROGRAM_EXECUTE(drv->chip->row_cycles);
drv->cmd_block_erase = NANDCMD_BLOCK_ERASE(drv->chip->row_cycles);
if(drv->chip->flags & NAND_CHIPFLAG_QUAD) {
drv->cmd_read_cache = NANDCMD_READ_CACHE_x4(drv->chip->col_cycles);
drv->cmd_program_load = NANDCMD_PROGRAM_LOAD_x4(drv->chip->col_cycles);
} else {
drv->cmd_read_cache = NANDCMD_READ_CACHE(drv->chip->col_cycles);
drv->cmd_program_load = NANDCMD_PROGRAM_LOAD(drv->chip->col_cycles);
}
}
static void setup_chip_registers(struct nand_drv* drv) static void setup_chip_registers(struct nand_drv* drv)
{ {
/* Set chip registers to enter normal operation */ /* Set chip registers to enter normal operation */
@ -189,7 +176,6 @@ int nand_open(struct nand_drv* drv)
return NAND_ERR_UNKNOWN_CHIP; return NAND_ERR_UNKNOWN_CHIP;
setup_chip_data(drv); setup_chip_data(drv);
setup_chip_commands(drv);
/* Set new SFC parameters */ /* Set new SFC parameters */
sfc_set_dev_conf(drv->chip->dev_conf); sfc_set_dev_conf(drv->chip->dev_conf);
@ -234,7 +220,7 @@ static uint8_t nand_wait_busy(struct nand_drv* drv)
int nand_block_erase(struct nand_drv* drv, nand_block_t block) int nand_block_erase(struct nand_drv* drv, nand_block_t block)
{ {
sfc_exec(NANDCMD_WR_EN, 0, NULL, 0); sfc_exec(NANDCMD_WR_EN, 0, NULL, 0);
sfc_exec(drv->cmd_block_erase, block, NULL, 0); sfc_exec(drv->chip->cmd_block_erase, block, NULL, 0);
uint8_t status = nand_wait_busy(drv); uint8_t status = nand_wait_busy(drv);
if(status & FREG_STATUS_EFAIL) if(status & FREG_STATUS_EFAIL)
@ -246,8 +232,9 @@ int nand_block_erase(struct nand_drv* drv, nand_block_t block)
int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer) int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer)
{ {
sfc_exec(NANDCMD_WR_EN, 0, NULL, 0); sfc_exec(NANDCMD_WR_EN, 0, NULL, 0);
sfc_exec(drv->cmd_program_load, 0, (void*)buffer, drv->fpage_size|SFC_WRITE); sfc_exec(drv->chip->cmd_program_load,
sfc_exec(drv->cmd_program_execute, page, NULL, 0); 0, (void*)buffer, drv->fpage_size|SFC_WRITE);
sfc_exec(drv->chip->cmd_program_execute, page, NULL, 0);
uint8_t status = nand_wait_busy(drv); uint8_t status = nand_wait_busy(drv);
if(status & FREG_STATUS_PFAIL) if(status & FREG_STATUS_PFAIL)
@ -258,9 +245,9 @@ int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer
int nand_page_read(struct nand_drv* drv, nand_page_t page, void* buffer) int nand_page_read(struct nand_drv* drv, nand_page_t page, void* buffer)
{ {
sfc_exec(drv->cmd_page_read, page, NULL, 0); sfc_exec(drv->chip->cmd_page_read, page, NULL, 0);
nand_wait_busy(drv); nand_wait_busy(drv);
sfc_exec(drv->cmd_read_cache, 0, buffer, drv->fpage_size|SFC_READ); sfc_exec(drv->chip->cmd_read_cache, 0, buffer, drv->fpage_size|SFC_READ);
if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) { if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) {
uint8_t status = nand_get_reg(drv, FREG_STATUS); uint8_t status = nand_get_reg(drv, FREG_STATUS);

View file

@ -106,10 +106,6 @@ struct nand_chip {
uint8_t dev_id; uint8_t dev_id;
uint8_t dev_id2; uint8_t dev_id2;
/* Row/column address width */
uint8_t row_cycles;
uint8_t col_cycles;
/* Base2 logarithm of the number of pages per block */ /* Base2 logarithm of the number of pages per block */
unsigned log2_ppb; unsigned log2_ppb;
@ -132,6 +128,13 @@ struct nand_chip {
/* Chip specific flags */ /* Chip specific flags */
uint32_t flags; uint32_t flags;
/* SFC commands for issuing I/O ops */
uint32_t cmd_page_read;
uint32_t cmd_program_execute;
uint32_t cmd_block_erase;
uint32_t cmd_read_cache;
uint32_t cmd_program_load;
/* Chip-specific setup routine */ /* Chip-specific setup routine */
void(*setup_chip)(struct nand_drv* drv); void(*setup_chip)(struct nand_drv* drv);
}; };
@ -170,13 +173,6 @@ struct nand_drv {
uint8_t mf_id; uint8_t mf_id;
uint8_t dev_id; uint8_t dev_id;
uint8_t dev_id2; uint8_t dev_id2;
/* SFC commands used for I/O, these are set based on chip data */
uint32_t cmd_page_read;
uint32_t cmd_read_cache;
uint32_t cmd_program_load;
uint32_t cmd_program_execute;
uint32_t cmd_block_erase;
}; };
extern const struct nand_chip supported_nand_chips[]; extern const struct nand_chip supported_nand_chips[];