From ad6f49145971cf232c609367927017cb1fb9e124 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Wed, 9 Oct 2024 17:24:12 +0800 Subject: [PATCH] patch(spi_flash): cleanup XMC flash chip usage according to new information --- .../bootloader_flash/src/bootloader_flash.c | 7 ++--- components/spi_flash/Kconfig | 11 +++++++ components/spi_flash/flash_brownout_hook.c | 2 +- .../include/spi_flash/spi_flash_defs.h | 2 ++ components/spi_flash/spi_flash_chip_generic.c | 30 +++++++++++++++++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index ea10579221..adff675c26 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -670,7 +670,6 @@ void bootloader_spi_flash_reset(void) #define XMC_SUPPORT CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT #define XMC_VENDOR_ID_1 0x20 -#define XMC_VENDOR_ID_2 0x46 #if BOOTLOADER_BUILD #define BOOTLOADER_FLASH_LOG(level, ...) ESP_EARLY_LOG##level(TAG, ##__VA_ARGS__) @@ -687,7 +686,7 @@ static IRAM_ATTR bool is_xmc_chip_strict(uint32_t rdid) uint32_t mfid = BYTESHIFT(rdid, 1); uint32_t cpid = BYTESHIFT(rdid, 0); - if (vendor_id != XMC_VENDOR_ID_1 && vendor_id != XMC_VENDOR_ID_2) { + if (vendor_id != XMC_VENDOR_ID_1) { return false; } @@ -720,7 +719,7 @@ esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void) // Check the Manufacturer ID in SFDP registers (JEDEC standard). If not XMC chip, no need to run the flow const int sfdp_mfid_addr = 0x10; uint8_t mf_id = (bootloader_flash_read_sfdp(sfdp_mfid_addr, 1) & 0xff); - if ((mf_id != XMC_VENDOR_ID_1) && (mf_id != XMC_VENDOR_ID_2)) { + if (mf_id != XMC_VENDOR_ID_1) { BOOTLOADER_FLASH_LOG(D, "non-XMC chip detected by SFDP Read (%02X), skip.", mf_id); return ESP_OK; } @@ -752,7 +751,7 @@ esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void) static IRAM_ATTR bool is_xmc_chip(uint32_t rdid) { uint32_t vendor_id = (rdid >> 16) & 0xFF; - return ((vendor_id == XMC_VENDOR_ID_1) || (vendor_id == XMC_VENDOR_ID_2)); + return (vendor_id == XMC_VENDOR_ID_1); } esp_err_t IRAM_ATTR bootloader_flash_xmc_startup(void) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 367b137657..80a48a1b7e 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -109,6 +109,17 @@ menu "Main Flash configuration" This config is used for setting Tsus parameter. Tsus means CS# high to next command after suspend. You can refer to the chapter of AC CHARACTERISTICS of flash datasheet. + config SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND + bool "Enable XMC-C series flash chip suspend feature anyway" + default n + help + XMC-C series is regarded as not qualified for the Suspend feature, since its specification + has a tRS >= 1ms restriction. We strongly do not suggest using it for the Suspend feature. + However, if your product in field has enabled this feature, you may still enable this + config option to keep the legacy behavior. + + For new users, DO NOT enable this config. + endmenu endmenu diff --git a/components/spi_flash/flash_brownout_hook.c b/components/spi_flash/flash_brownout_hook.c index 762b54028d..7d070c0b19 100644 --- a/components/spi_flash/flash_brownout_hook.c +++ b/components/spi_flash/flash_brownout_hook.c @@ -20,7 +20,7 @@ void spi_flash_needs_reset_check(void) { // Currently only XMC is suggested to reset when brownout #if CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC - if ((g_rom_flashchip.device_id >> 16) == 0x20 || (g_rom_flashchip.device_id >> 16) == 0x46) { + if ((g_rom_flashchip.device_id >> 16) == 0x20) { flash_brownout_needs_reset = true; } #endif diff --git a/components/spi_flash/include/spi_flash/spi_flash_defs.h b/components/spi_flash/include/spi_flash/spi_flash_defs.h index 08247c619b..7a8bf432f7 100644 --- a/components/spi_flash/include/spi_flash/spi_flash_defs.h +++ b/components/spi_flash/include/spi_flash/spi_flash_defs.h @@ -53,6 +53,8 @@ #define CMD_RST_EN 0x66 #define CMD_RST_DEV 0x99 +#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ + #define SPI_FLASH_DIO_ADDR_BITLEN 24 #define SPI_FLASH_DIO_DUMMY_BITLEN 4 #define SPI_FLASH_QIO_ADDR_BITLEN 24 diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index 33bd1c3029..8233eaf174 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -599,11 +599,37 @@ spi_flash_caps_t spi_flash_chip_generic_get_caps(esp_flash_t *chip) // 32M-bits address support // flash suspend support - // XMC support suspend - if (chip->chip_id >> 16 == 0x20 || chip->chip_id >> 16 == 0x46) { + // XMC-D support suspend + if (chip->chip_id >> 16 == 0x46) { caps_flags |= SPI_FLASH_CHIP_CAP_SUSPEND; } + // XMC-D support suspend (some D series flash chip begin with 0x20, difference checked by SFDP) + if (chip->chip_id >> 16 == 0x20) { + uint8_t data = 0; + spi_flash_trans_t t = { + .command = CMD_RDSFDP, + .address_bitlen = 24, + .address = 0x32, + .mosi_len = 0, + .mosi_data = 0, + .miso_len = 1, + .miso_data = &data, + .dummy_bitlen = 8, + }; + chip->host->driver->common_command(chip->host, &t); + if((data & 0x8) == 0x8) { + caps_flags |= SPI_FLASH_CHIP_CAP_SUSPEND; + } + } + +#if CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND + // XMC-C suspend has big risk. But can enable this anyway. + if (chip->chip_id >> 16 == 0x20) { + caps_flags |= SPI_FLASH_CHIP_CAP_SUSPEND; + } +#endif + // FM support suspend if (chip->chip_id >> 16 == 0xa1) { caps_flags |= SPI_FLASH_CHIP_CAP_SUSPEND;