From e64b0e81ad76ef057b7a3c79ac8a810c1b73faaf Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 7 Jun 2022 19:37:11 +0100 Subject: [PATCH] x1000: add support for the W25N01GVxx NAND flash This chip is apparently used in some Surfans F20 units, and has the same geometry as the ATO25D1GA. It has an on-die ECC engine. Change-Id: I4d37a2455620ce43cec0a9bcbb32c776d1a8eba1 --- .../target/mips/ingenic_x1000/nand-x1000.c | 31 +++++++++++++++++++ .../target/mips/ingenic_x1000/nand-x1000.h | 3 ++ 2 files changed, 34 insertions(+) diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.c b/firmware/target/mips/ingenic_x1000/nand-x1000.c index 6255597165..c78f990f5f 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.c +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.c @@ -25,6 +25,8 @@ #include "logf.h" #include +static void winbond_setup_chip(struct nand_drv* drv); + static const struct nand_chip chip_ato25d1ga = { .log2_ppb = 6, /* 64 pages */ .page_size = 2048, @@ -46,9 +48,32 @@ static const struct nand_chip chip_ato25d1ga = { .cmd_program_load = NANDCMD_PROGRAM_LOAD_x4, }; +static const struct nand_chip chip_w25n01gvxx = { + .log2_ppb = 6, /* 64 pages */ + .page_size = 2048, + .oob_size = 64, + .nr_blocks = 1024, + .bbm_pos = 2048, + .clock_freq = 150000000, + .dev_conf = jz_orf(SFC_DEV_CONF, + CE_DL(1), HOLD_DL(1), WP_DL(1), + CPHA(0), CPOL(0), + TSH(11), TSETUP(0), THOLD(0), + STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS), + SMP_DELAY(1)), + .flags = NAND_CHIPFLAG_ON_DIE_ECC, + /* TODO: quad mode? */ + .cmd_page_read = NANDCMD_PAGE_READ, + .cmd_program_execute = NANDCMD_PROGRAM_EXECUTE, + .cmd_block_erase = NANDCMD_BLOCK_ERASE, + .cmd_read_cache = NANDCMD_READ_CACHE_SLOW, + .cmd_program_load = NANDCMD_PROGRAM_LOAD, + .setup_chip = winbond_setup_chip, +}; const struct nand_chip_id supported_nand_chips[] = { NAND_CHIP_ID(&chip_ato25d1ga, NAND_READID_ADDR, 0x9b, 0x12), + NAND_CHIP_ID(&chip_w25n01gvxx, NAND_READID_ADDR, 0xef, 0xaa, 0x21), }; const size_t nr_supported_nand_chips = ARRAYLEN(supported_nand_chips); @@ -127,6 +152,12 @@ static void setup_chip_data(struct nand_drv* drv) drv->fpage_size = drv->chip->page_size + drv->chip->oob_size; } +static void winbond_setup_chip(struct nand_drv* drv) +{ + /* Ensure we are in buffered read mode. */ + nand_upd_reg(drv, FREG_CFG, FREG_CFG_WINBOND_BUF, FREG_CFG_WINBOND_BUF); +} + static void setup_chip_registers(struct nand_drv* drv) { /* Set chip registers to enter normal operation */ diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.h b/firmware/target/mips/ingenic_x1000/nand-x1000.h index 2c3294cfad..0ccd075079 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.h +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.h @@ -72,6 +72,9 @@ #define FREG_CFG_ECC_ENABLE (1 << 4) #define FREG_CFG_QUAD_ENABLE (1 << 0) +/* Winbond-specific bit used on the W25N01GVxx */ +#define FREG_CFG_WINBOND_BUF (1 << 3) + #define FREG_STATUS 0xc0 #define FREG_STATUS_BUSY (1 << 0) #define FREG_STATUS_EFAIL (1 << 2)