mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
feat(spi_flash): Add flash suspend support on esp32h21, esp32h4
This commit is contained in:
@@ -85,12 +85,13 @@ void IRAM_ATTR bootloader_configure_spi_pins(int drv)
|
||||
esp_rom_gpio_pad_set_drv(wp_gpio_num, drv);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR bootloader_flash_clock_init(void)
|
||||
static void IRAM_ATTR bootloader_mspi_clock_init(void)
|
||||
{
|
||||
// // To raise the MSPI clock to 64MHz, needs to enable the 64MHz clock source, which is XTAL_X2_CLK
|
||||
// // (FPGA image fixed MSPI0/1 clock to 64MHz)
|
||||
// clk_ll_xtal_x2_enable();
|
||||
// _mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_PLL_F64M);
|
||||
// IDF-13632
|
||||
_mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_PLL_F48M);
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
|
||||
|
||||
static void IRAM_ATTR bootloader_init_flash_configure(void)
|
||||
{
|
||||
bootloader_flash_clock_init();
|
||||
bootloader_mspi_clock_init();
|
||||
bootloader_configure_spi_pins(1);
|
||||
bootloader_flash_cs_timing_config();
|
||||
}
|
||||
@@ -278,7 +279,7 @@ void bootloader_flash_hardware_init(void)
|
||||
bootloader_configure_spi_pins(1);
|
||||
bootloader_flash_set_spi_mode(&hdr);
|
||||
bootloader_flash_clock_config(&hdr);
|
||||
bootloader_flash_clock_init();
|
||||
bootloader_mspi_clock_init();
|
||||
bootloader_flash_cs_timing_config();
|
||||
|
||||
bootloader_spi_flash_resume();
|
||||
|
@@ -128,6 +128,19 @@ static inline void cache_ll_invalidate_addr(uint32_t cache_level, cache_type_t t
|
||||
Cache_Invalidate_Addr(vaddr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Invalidate all
|
||||
*
|
||||
* @param cache_level level of the cache
|
||||
* @param type see `cache_type_t`
|
||||
* @param cache_id id of the cache in this type and level
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void cache_ll_invalidate_all(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
|
||||
{
|
||||
Cache_Invalidate_ICache_All();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Freeze Cache
|
||||
*
|
||||
|
@@ -725,6 +725,79 @@ static inline void spimem_flash_ll_set_common_command_register_info(spi_mem_dev_
|
||||
dev->user2.val = user2_reg;
|
||||
}
|
||||
|
||||
|
||||
#define SPIMEM_FLASH_LL_SUSPEND_END_INTR SPI_MEM_PES_END_INT_ENA_M
|
||||
#define SPIMEM_FLASH_LL_INTERRUPT_SOURCE ETS_MSPI_INTR_SOURCE
|
||||
|
||||
/**
|
||||
* @brief Get the address of the interrupt status register.
|
||||
*
|
||||
* This function returns a pointer to the interrupt status register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @return volatile void* Pointer to the interrupt status register.
|
||||
*/
|
||||
static inline volatile void *spimem_flash_ll_get_interrupt_status_reg(spi_mem_dev_t *dev)
|
||||
{
|
||||
return &dev->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear specific interrupt status bits.
|
||||
*
|
||||
* This function clears the specified interrupt bits in the interrupt clear register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to clear.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_clear_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt bits.
|
||||
*
|
||||
* This function enables the specified interrupts in the interrupt enable register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to enable.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_enable_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_ena.val |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt bits.
|
||||
*
|
||||
* This function disables the specified interrupts in the interrupt enable register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to disable.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_disable_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current interrupt status.
|
||||
*
|
||||
* This function retrieves the current interrupt status from the interrupt status register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[out] intr_status Pointer to a variable where the interrupt status will be stored.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_get_intr_mask(spi_mem_dev_t *dev, uint32_t *intr_status)
|
||||
{
|
||||
*intr_status = dev->int_st.val;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -56,6 +56,7 @@ static inline void _mspi_timing_ll_set_flash_clk_src(uint32_t mspi_id, soc_perip
|
||||
// case FLASH_CLK_SRC_PLL_F64M:
|
||||
// PCR.mspi_clk_conf.mspi_func_clk_sel = 2;
|
||||
// break;
|
||||
// TODO: [ESP32H4] IDF-13632, support 64M
|
||||
case FLASH_CLK_SRC_PLL_F48M:
|
||||
PCR.mspi_clk_conf.mspi_func_clk_sel = 3;
|
||||
break;
|
||||
|
@@ -724,6 +724,79 @@ static inline void spimem_flash_ll_set_common_command_register_info(spi_mem_dev_
|
||||
dev->user2.val = user2_reg;
|
||||
}
|
||||
|
||||
|
||||
#define SPIMEM_FLASH_LL_SUSPEND_END_INTR SPI_MEM_PES_END_INT_ENA_M
|
||||
#define SPIMEM_FLASH_LL_INTERRUPT_SOURCE ETS_MSPI_INTR_SOURCE
|
||||
|
||||
/**
|
||||
* @brief Get the address of the interrupt status register.
|
||||
*
|
||||
* This function returns a pointer to the interrupt status register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @return volatile void* Pointer to the interrupt status register.
|
||||
*/
|
||||
static inline volatile void *spimem_flash_ll_get_interrupt_status_reg(spi_mem_dev_t *dev)
|
||||
{
|
||||
return &dev->int_st;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear specific interrupt status bits.
|
||||
*
|
||||
* This function clears the specified interrupt bits in the interrupt clear register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to clear.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_clear_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable specific interrupt bits.
|
||||
*
|
||||
* This function enables the specified interrupts in the interrupt enable register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to enable.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_enable_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_ena.val |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable specific interrupt bits.
|
||||
*
|
||||
* This function disables the specified interrupts in the interrupt enable register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[in] mask Bitmask specifying which interrupt bits to disable.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_disable_intr_mask(spi_mem_dev_t *dev, uint32_t mask)
|
||||
{
|
||||
dev->int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current interrupt status.
|
||||
*
|
||||
* This function retrieves the current interrupt status from the interrupt status register of the SPI memory device.
|
||||
*
|
||||
* @param[in] dev Pointer to the SPI memory device structure.
|
||||
* @param[out] intr_status Pointer to a variable where the interrupt status will be stored.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spimem_flash_ll_get_intr_mask(spi_mem_dev_t *dev, uint32_t *intr_status)
|
||||
{
|
||||
*intr_status = dev->int_st.val;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -567,6 +567,10 @@ config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_AUTO_RESUME
|
||||
bool
|
||||
default y
|
||||
@@ -587,18 +591,6 @@ config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_64M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_32M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_16M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SYSTIMER_COUNTER_NUM
|
||||
int
|
||||
default 2
|
||||
|
@@ -415,17 +415,13 @@
|
||||
|
||||
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
|
||||
// #define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) //TODO: [ESP32H21] IDF-11526
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_RESUME (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
||||
|
||||
#define SOC_MEMSPI_SRC_FREQ_64M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_32M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_16M_SUPPORTED 1
|
||||
|
||||
/*-------------------------- SYSTIMER CAPS ----------------------------------*/
|
||||
#define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units
|
||||
#define SOC_SYSTIMER_ALARM_NUM 3 // Number of alarm units
|
||||
|
@@ -335,6 +335,10 @@ config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MEM_SUPPORT_AUTO_RESUME
|
||||
bool
|
||||
default y
|
||||
@@ -355,18 +359,6 @@ config SOC_SPI_MEM_SUPPORT_WRAP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_64M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_32M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_16M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SYSTIMER_COUNTER_NUM
|
||||
int
|
||||
default 2
|
||||
|
@@ -407,17 +407,13 @@
|
||||
|
||||
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
|
||||
// #define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) // TODO: [ESP32H4] IDF-12290
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_RESUME (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
|
||||
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
||||
|
||||
#define SOC_MEMSPI_SRC_FREQ_64M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_32M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_16M_SUPPORTED 1
|
||||
|
||||
/*-------------------------- SYSTIMER CAPS ----------------------------------*/
|
||||
#define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units
|
||||
#define SOC_SYSTIMER_ALARM_NUM 3 // Number of alarm units
|
||||
|
@@ -5,6 +5,4 @@ choice ESPTOOLPY_FLASHFREQ
|
||||
bool "48 MHz"
|
||||
config ESPTOOLPY_FLASHFREQ_24M
|
||||
bool "24 MHz"
|
||||
config ESPTOOLPY_FLASHFREQ_12M
|
||||
bool "12 MHz"
|
||||
endchoice
|
||||
|
@@ -73,6 +73,7 @@ esp_err_t spi_flash_chip_gd_detect_size(esp_flash_t *chip, uint32_t *size)
|
||||
#define FLASH_SIZE_MASK 0xFF
|
||||
#define GD25Q_PRODUCT_ID 0x4000
|
||||
#define GD25LQ_PRODUCT_ID 0x6000
|
||||
#define GD25UF_PRODUCT_ID 0x8300
|
||||
|
||||
#define WRSR_16B_REQUIRED(chip_id) (((chip_id) & FLASH_ID_MASK) == GD25LQ_PRODUCT_ID || \
|
||||
((chip_id) & FLASH_SIZE_MASK) <= 0x15)
|
||||
@@ -88,7 +89,7 @@ esp_err_t spi_flash_chip_gd_probe(esp_flash_t *chip, uint32_t flash_id)
|
||||
}
|
||||
|
||||
uint32_t product_id = flash_id & FLASH_ID_MASK;
|
||||
if (product_id != GD25Q_PRODUCT_ID && product_id != GD25LQ_PRODUCT_ID) {
|
||||
if (product_id != GD25Q_PRODUCT_ID && product_id != GD25LQ_PRODUCT_ID && product_id != GD25UF_PRODUCT_ID) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "esp_flash.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "rom/cache.h"
|
||||
#include "hal/cache_ll.h"
|
||||
|
||||
#include "test_utils.h"
|
||||
|
||||
@@ -77,6 +78,8 @@ static bool IRAM_ATTR gptimer_alarm_suspend_cb(gptimer_handle_t timer, const gpt
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_All(CACHE_MAP_L2_CACHE);
|
||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||
cache_ll_invalidate_all(CACHE_LL_LEVEL_ALL, CACHE_TYPE_ALL, CACHE_LL_ID_ALL);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61
|
||||
Cache_Invalidate_All();
|
||||
#else
|
||||
|
Reference in New Issue
Block a user