From b0392bd460d2521df19ed2999d3017d568bb4b96 Mon Sep 17 00:00:00 2001 From: airjinkela <67526885+airjinkela@users.noreply.github.com> Date: Fri, 29 Aug 2025 20:06:32 +0800 Subject: [PATCH] atf-20250711: fix cannot recognize dosilicon nand (#146) patch from : https://github.com/immortalwrt/immortalwrt/commit/f0c23d2356a5402cc5247712195ecd61912cf7f2 Signed-off-by: air jinkela --- .../drivers/spi_nand/mtk_spi_nand.c | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/atf-20250711/plat/mediatek/apsoc_common/drivers/spi_nand/mtk_spi_nand.c b/atf-20250711/plat/mediatek/apsoc_common/drivers/spi_nand/mtk_spi_nand.c index 99a5e24e2..3166819af 100644 --- a/atf-20250711/plat/mediatek/apsoc_common/drivers/spi_nand/mtk_spi_nand.c +++ b/atf-20250711/plat/mediatek/apsoc_common/drivers/spi_nand/mtk_spi_nand.c @@ -20,8 +20,11 @@ #define SPI_NAND_MAX_ID_LEN 4U #define DELAY_US_400MS 400000U +#define DOSILICON_ID 0xE5U #define ETRON_ID 0xD5U +#define FMSH_ID 0xA1U #define GIGADEVICE_ID 0xC8U +#define GSTO_ID 0x52U #define MACRONIX_ID 0xC2U #define MICRON_ID 0x2CU #define TOSHIBA_ID 0x98U @@ -145,7 +148,10 @@ static int spi_nand_quad_enable(uint8_t manufacturer_id) if (manufacturer_id != MACRONIX_ID && manufacturer_id != GIGADEVICE_ID && + manufacturer_id != GSTO_ID && + manufacturer_id != DOSILICON_ID && manufacturer_id != ETRON_ID && + manufacturer_id != FMSH_ID && manufacturer_id != FORESEE_ID) { return 0; } @@ -543,6 +549,10 @@ static int spi_nand_check_pp(struct parameter_page *pp, uint8_t *sel) INFO("PP COPY %d CRC read: 0x%x, compute: 0x%x\n", i, crc, crc_compute); + // Integrity CRC (bytes 254-255) on FMSH was reversed + if (crc != crc_compute) + crc = htobe16(pp->integrity_crc); + if (crc != crc_compute) { ret = -EBADMSG; continue; @@ -634,8 +644,9 @@ restore: return valid ? valid: 0; } -static int spi_nand_read_pp(struct parameter_page *pp, uint8_t *sel) +static int spi_nand_read_pp(uint8_t *id, struct parameter_page *pp, uint8_t *sel) { + const bool is_dosilicon = (id[1] == DOSILICON_ID); uint8_t pp_offset[3] = {0x0, 0x1, 0x4}; int valid = -EINVAL; int ret, last_ret; @@ -648,7 +659,7 @@ static int spi_nand_read_pp(struct parameter_page *pp, uint8_t *sel) return ret; } - ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg_reg | BIT(6)); + ret = spi_nand_write_reg(SPI_NAND_REG_CFG, is_dosilicon ? BIT(6) : (cfg_reg | BIT(6))); if (ret != 0) { return ret; } @@ -677,7 +688,7 @@ static int spi_nand_read_pp(struct parameter_page *pp, uint8_t *sel) } restore: - last_ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg_reg); + last_ret = spi_nand_write_reg(SPI_NAND_REG_CFG, is_dosilicon ? 0x10 : cfg_reg); if (last_ret) { return last_ret; } @@ -877,9 +888,13 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size) fallback_pp: WARN("CASN page may not exist. Try to read parameter page.\n"); + ret = spi_nand_read_id(id); + if (ret) { + return ret; + } sel = 0; pp = (struct parameter_page *)buf; - ret = spi_nand_read_pp(pp, &sel); + ret = spi_nand_read_pp(id, pp, &sel); if (ret) { goto fallback_id; } @@ -889,10 +904,6 @@ fallback_pp: fallback_id: WARN("Parameter page may not exist. Try to read ID.\n"); - ret = spi_nand_read_id(id); - if (ret) { - return ret; - } spi_nand_set_data_via_id(&spinand_dev, id, &vendor_id); success: