summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-06-07 19:37:11 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-09-17 10:14:26 -0400
commite64b0e81ad76ef057b7a3c79ac8a810c1b73faaf (patch)
treeb3be811c48b7903db5b26cb0b7e14bf3e796fe15
parent17443de2214f7bfe77e1ebc11c268adaa15ae856 (diff)
downloadrockbox-e64b0e81ad.tar.gz
rockbox-e64b0e81ad.zip
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
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.c31
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.h3
2 files changed, 34 insertions, 0 deletions
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 <string.h>
+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)