feat(spi_flash): Add 32M flash support on esp32c5

This commit is contained in:
C.S.M
2024-12-16 17:37:52 +08:00
parent d695060742
commit d448c4ed05
9 changed files with 98 additions and 10 deletions

View File

@@ -128,7 +128,10 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
#include "esp32s3/rom/opi_flash.h" #include "esp32s3/rom/opi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/opi_flash.h" #include "esp32p4/rom/opi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/opi_flash.h"
#endif #endif
#include "spi_flash/spi_flash_defs.h"
#if ESP_TEE_BUILD #if ESP_TEE_BUILD
#include "esp_flash_partitions.h" #include "esp_flash_partitions.h"
@@ -592,37 +595,37 @@ void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t fla
switch (flash_mode) { switch (flash_mode) {
case ESP_ROM_SPIFLASH_DOUT_MODE: case ESP_ROM_SPIFLASH_DOUT_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 8; cache_rd.dummy_bit_len = SPI_FLASH_DOUT_DUMMY_BITLEN;
cache_rd.cmd = CMD_FASTRD_DUAL_4B; cache_rd.cmd = CMD_FASTRD_DUAL_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;
case ESP_ROM_SPIFLASH_DIO_MODE: case ESP_ROM_SPIFLASH_DIO_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 4; cache_rd.dummy_bit_len = SPI_FLASH_DIO_DUMMY_BITLEN;
cache_rd.cmd = CMD_FASTRD_DIO_4B; cache_rd.cmd = CMD_FASTRD_DIO_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;
case ESP_ROM_SPIFLASH_QOUT_MODE: case ESP_ROM_SPIFLASH_QOUT_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 8; cache_rd.dummy_bit_len = SPI_FLASH_QOUT_DUMMY_BITLEN;
cache_rd.cmd = CMD_FASTRD_QUAD_4B; cache_rd.cmd = CMD_FASTRD_QUAD_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;
case ESP_ROM_SPIFLASH_QIO_MODE: case ESP_ROM_SPIFLASH_QIO_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 6; cache_rd.dummy_bit_len = SPI_FLASH_QIO_DUMMY_BITLEN;
cache_rd.cmd = CMD_FASTRD_QIO_4B; cache_rd.cmd = CMD_FASTRD_QIO_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;
case ESP_ROM_SPIFLASH_FASTRD_MODE: case ESP_ROM_SPIFLASH_FASTRD_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 8; cache_rd.dummy_bit_len = SPI_FLASH_FASTRD_DUMMY_BITLEN;
cache_rd.cmd = CMD_FASTRD_4B; cache_rd.cmd = CMD_FASTRD_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;
case ESP_ROM_SPIFLASH_SLOWRD_MODE: case ESP_ROM_SPIFLASH_SLOWRD_MODE:
cache_rd.addr_bit_len = 32; cache_rd.addr_bit_len = 32;
cache_rd.dummy_bit_len = 0; cache_rd.dummy_bit_len = SPI_FLASH_SLOWRD_DUMMY_BITLEN;
cache_rd.cmd = CMD_SLOWRD_4B; cache_rd.cmd = CMD_SLOWRD_4B;
cache_rd.cmd_bit_len = 8; cache_rd.cmd_bit_len = 8;
break; break;

View File

@@ -29,6 +29,7 @@
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "hal/cache_ll.h" #include "hal/cache_ll.h"
#include "hal/mspi_timing_tuning_ll.h" #include "hal/mspi_timing_tuning_ll.h"
#include "bootloader_flash_override.h"
void bootloader_flash_update_id() void bootloader_flash_update_id()
{ {
@@ -117,6 +118,9 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr)
case ESP_IMAGE_FLASH_SIZE_16MB: case ESP_IMAGE_FLASH_SIZE_16MB:
size = 16; size = 16;
break; break;
case ESP_IMAGE_FLASH_SIZE_32MB:
size = 32;
break;
default: default:
size = 2; size = 2;
} }
@@ -193,6 +197,9 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
case ESP_IMAGE_FLASH_SIZE_16MB: case ESP_IMAGE_FLASH_SIZE_16MB:
str = "16MB"; str = "16MB";
break; break;
case ESP_IMAGE_FLASH_SIZE_32MB:
str = "32MB";
break;
default: default:
str = "2MB"; str = "2MB";
break; break;
@@ -227,6 +234,10 @@ esp_err_t bootloader_init_spi_flash(void)
bootloader_enable_qio_mode(); bootloader_enable_qio_mode();
#endif #endif
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
#endif
print_flash_info(&bootloader_image_hdr); print_flash_info(&bootloader_image_hdr);
cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
@@ -295,6 +306,10 @@ void bootloader_flash_hardware_init(void)
bootloader_spi_flash_resume(); bootloader_spi_flash_resume();
bootloader_flash_unlock(); bootloader_flash_unlock();
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
#endif
cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
update_flash_config(&hdr); update_flash_config(&hdr);
cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);

View File

@@ -17,6 +17,9 @@
#elif CONFIG_IDF_TARGET_ESP32P4 #elif CONFIG_IDF_TARGET_ESP32P4
#include "esp32p4/rom/spi_flash.h" #include "esp32p4/rom/spi_flash.h"
#include "esp32p4/rom/opi_flash.h" #include "esp32p4/rom/opi_flash.h"
#elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/spi_flash.h"
#include "esp32c5/rom/opi_flash.h"
#endif #endif
#define SPI_IDX 1 #define SPI_IDX 1
@@ -756,7 +759,34 @@ void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const
REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_Q_POL); REG_SET_BIT(SPI_MEM_C_CTRL_REG, SPI_MEM_C_Q_POL);
} }
} }
#elif CONFIG_IDF_TARGET_ESP32C5
extern void esp_rom_spi_set_address_bit_len(int spi, int addr_bits);
void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache)
{
esp_rom_spi_set_op_mode(0, mode);
if (cache) {
esp_rom_spi_set_address_bit_len(0, cache->addr_bit_len);
// Patch for ROM function `esp_rom_opiflash_cache_mode_config`, because when dummy is 0,
// `SPI_MEM_USR_DUMMY` should be 0. `esp_rom_opiflash_cache_mode_config` doesn't handle this
// properly.
if (cache->dummy_bit_len == 0) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, cache->dummy_bit_len - 1 + rom_spiflash_legacy_data->dummy_len_plus[0]);
}
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, cache->cmd);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_BITLEN, cache->cmd_bit_len - 1);
REG_SET_FIELD(SPI_MEM_DDR_REG(0), SPI_FMEM_VAR_DUMMY, cache->var_dummy_en);
}
if (mode == ESP_ROM_SPIFLASH_DIO_MODE || mode == ESP_ROM_SPIFLASH_QIO_MODE) {
REG_SET_FIELD(SPI_MEM_RD_STATUS_REG(0), SPI_MEM_WB_MODE, 0x00);
REG_SET_FIELD(SPI_MEM_RD_STATUS_REG(0), SPI_MEM_WB_MODE_BITLEN, 7);
REG_SET_FIELD(SPI_MEM_RD_STATUS_REG(0), SPI_MEM_WB_MODE_EN, 1);
}
}
#endif // IDF_TARGET #endif // IDF_TARGET

View File

@@ -70,6 +70,7 @@ typedef union {
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n) #define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time) #define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C5*/ } #define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C5*/ }
#define spi_flash_ll_wb_mode_enable(dev, wb_mode_enale) { /* Not supported on gpspi on ESP32-C5*/ }
#else #else
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev) #define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev) #define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
@@ -101,6 +102,7 @@ typedef union {
#define spi_flash_ll_sync_reset() spimem_flash_ll_sync_reset() #define spi_flash_ll_sync_reset() spimem_flash_ll_sync_reset()
#define spi_flash_ll_set_common_command_register_info(dev, ctrl_reg, user_reg, user1_reg, user2_reg) spimem_flash_ll_set_common_command_register_info((spi_mem_dev_t*)dev, ctrl_reg, user_reg, user1_reg, user2_reg) #define spi_flash_ll_set_common_command_register_info(dev, ctrl_reg, user_reg, user1_reg, user2_reg) spimem_flash_ll_set_common_command_register_info((spi_mem_dev_t*)dev, ctrl_reg, user_reg, user1_reg, user2_reg)
#define spi_flash_ll_get_common_command_register_info(dev, ctrl_reg, user_reg, user1_reg, user2_reg) spimem_flash_ll_get_common_command_register_info((spi_mem_dev_t*)dev, ctrl_reg, user_reg, user1_reg, user2_reg) #define spi_flash_ll_get_common_command_register_info(dev, ctrl_reg, user_reg, user1_reg, user2_reg) spimem_flash_ll_get_common_command_register_info((spi_mem_dev_t*)dev, ctrl_reg, user_reg, user1_reg, user2_reg)
#define spi_flash_ll_wb_mode_enable(dev, wb_mode_enale) spimem_flash_ll_wb_mode_enable((spi_mem_dev_t*)dev, wb_mode_enale)
#endif #endif

View File

@@ -555,6 +555,7 @@ static inline int spimem_flash_ll_get_addr_bitlen(spi_mem_dev_t *dev)
__attribute__((always_inline)) __attribute__((always_inline))
static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t bitlen) static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t bitlen)
{ {
dev->cache_fctrl.cache_usr_addr_4byte = (bitlen == 32) ? 1 : 0;
dev->user1.usr_addr_bitlen = (bitlen - 1); dev->user1.usr_addr_bitlen = (bitlen - 1);
dev->user.usr_addr = bitlen ? 1 : 0; dev->user.usr_addr = bitlen ? 1 : 0;
} }
@@ -567,8 +568,20 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t
*/ */
static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr) static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr)
{ {
dev->cache_fctrl.cache_usr_addr_4byte = 0; // Fixed wb mode to 0x00, the bit length fixed to 8
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr); HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr);
dev->rd_status.wb_mode_bitlen = 7; // 8 - 1
}
/**
* Enable extra address for bits M0-M7 in DIO/QIO mode.
*
* @param dev Beginning address of the peripheral registers.
* @param wb_mode_enable true for enabling wb_mode
*/
static inline void spimem_flash_ll_wb_mode_enable(spi_mem_dev_t *dev, bool wb_mode_enable)
{
dev->rd_status.wb_mode_en = wb_mode_enable;
} }
/** /**

View File

@@ -126,10 +126,15 @@ esp_err_t spi_flash_hal_configure_host_io_mode(
* - DIO is similar. * - DIO is similar.
*/ */
if (conf_required) { if (conf_required) {
#if !SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
int line_width = (io_mode == SPI_FLASH_DIO? 2: 4); int line_width = (io_mode == SPI_FLASH_DIO? 2: 4);
dummy_cyclelen_base -= SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS / line_width; dummy_cyclelen_base -= SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS / line_width;
addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS; addr_bitlen += SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS;
#endif
spi_flash_ll_set_extra_address(dev, 0); spi_flash_ll_set_extra_address(dev, 0);
#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
spi_flash_ll_wb_mode_enable(dev, true);
#endif
} }
#endif #endif
#else #else
@@ -204,6 +209,9 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_tr
if (trans->miso_len > 0) { if (trans->miso_len > 0) {
spi_flash_ll_get_buffer_data(dev, trans->miso_data, trans->miso_len); spi_flash_ll_get_buffer_data(dev, trans->miso_data, trans->miso_len);
} }
#if SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
spi_flash_ll_wb_mode_enable(dev, false);
#endif
return ESP_OK; return ESP_OK;
} }

View File

@@ -1143,6 +1143,14 @@ config SOC_SPI_MEM_SUPPORT_WRAP
bool bool
default y default y
config SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
bool
default y
config SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP
bool
default y
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
bool bool
default y default y

View File

@@ -462,6 +462,8 @@
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL (1)
#define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1)
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1

View File

@@ -1,9 +1,11 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "soc/soc_caps.h"
#pragma once #pragma once
/* SPI commands (actual on-wire commands not SPI controller bitmasks) /* SPI commands (actual on-wire commands not SPI controller bitmasks)
@@ -55,10 +57,15 @@
#define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ #define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */
#define SPI_FLASH_DIO_ADDR_BITLEN 24 #if !SOC_SPI_MEM_SUPPORT_WB_MODE_INDEPENDENT_CONTROL
#define SPI_FLASH_DIO_DUMMY_BITLEN 4 #define SPI_FLASH_DIO_DUMMY_BITLEN 4
#define SPI_FLASH_QIO_ADDR_BITLEN 24
#define SPI_FLASH_QIO_DUMMY_BITLEN 6 #define SPI_FLASH_QIO_DUMMY_BITLEN 6
#else
#define SPI_FLASH_DIO_DUMMY_BITLEN 0
#define SPI_FLASH_QIO_DUMMY_BITLEN 4
#endif
#define SPI_FLASH_DIO_ADDR_BITLEN 24
#define SPI_FLASH_QIO_ADDR_BITLEN 24
#define SPI_FLASH_QOUT_ADDR_BITLEN 24 #define SPI_FLASH_QOUT_ADDR_BITLEN 24
#define SPI_FLASH_QOUT_DUMMY_BITLEN 8 #define SPI_FLASH_QOUT_DUMMY_BITLEN 8
#define SPI_FLASH_DOUT_ADDR_BITLEN 24 #define SPI_FLASH_DOUT_ADDR_BITLEN 24