From ebbd9cdb5993148f57d850786ab8fe6321815e25 Mon Sep 17 00:00:00 2001 From: armando Date: Thu, 26 Mar 2026 15:18:18 +0800 Subject: [PATCH 1/2] feat(psram): support psram device driver --- .../flash_encryption_secure_features.c | 69 ++ .../bootloader_support/src/flash_encrypt.c | 3 +- .../esp32s31/include/hal/clk_tree_ll.h | 57 +- .../esp32p4/include/hal/mspi_ll.h | 1 + .../esp32s31/include/hal/mspi_ll.h | 171 +++- .../esp32s31/include/hal/psram_ctrlr_ll.h | 946 ++++++++++++++++++ .../esp32s31/include/hal/spimem_flash_ll.h | 2 +- components/esp_hw_support/clk_ctrl_os.c | 2 + components/esp_hw_support/linker.lf | 23 +- .../mspi_timing_tuning/mspi_timing_tuning.c | 6 +- .../port/esp32s31/CMakeLists.txt | 11 + .../port/esp32s31/mspi_timing_config.c | 60 ++ .../esp32s31/mspi_timing_tuning_configs.h | 60 ++ .../tuning_scheme_impl/mspi_timing_by_dqs.c | 57 +- .../port/esp32s31/cpu_region_protect.c | 9 +- .../esp_hw_support/port/esp32s31/rtc_clk.c | 27 +- .../esp_hw_support/port/esp32s31/rtc_time.c | 2 +- components/esp_psram/CMakeLists.txt | 4 +- components/esp_psram/device/CMakeLists.txt | 6 + .../esp_psram/device/esp_psram_impl_ap_oct.c | 585 +++++++++++ components/esp_psram/esp32s31/Kconfig.spiram | 96 ++ components/esp_psram/linker.lf | 4 +- .../esp_psram/test_apps/psram/README.md | 4 +- .../test_apps/psram/main/test_psram.c | 4 +- .../esp32s31/include/esp32s31/rom/opi_flash.h | 325 ++++++ components/esp_system/fpga_overrides_clk.c | 2 +- .../esp32s31/include/soc/Kconfig.soc_caps.in | 24 +- .../soc/esp32s31/include/soc/clk_tree_defs.h | 17 + .../soc/esp32s31/include/soc/soc_caps.h | 11 +- .../register/soc/iomux_mspi_pin_struct.h | 541 ++-------- .../soc/esp32s31/register/soc/reg_base.h | 2 +- .../esp32s31/register/soc/spi1_mem_c_struct.h | 287 +++--- .../esp32s31/register/soc/spi1_mem_s_struct.h | 354 +++---- components/spi_flash/flash_ops.c | 2 +- examples/system/xip_from_psram/README.md | 4 +- 35 files changed, 2871 insertions(+), 907 deletions(-) create mode 100644 components/bootloader_support/src/esp32s31/flash_encryption_secure_features.c create mode 100644 components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h create mode 100644 components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt create mode 100644 components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c create mode 100644 components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h create mode 100644 components/esp_psram/device/esp_psram_impl_ap_oct.c create mode 100644 components/esp_psram/esp32s31/Kconfig.spiram create mode 100644 components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h diff --git a/components/bootloader_support/src/esp32s31/flash_encryption_secure_features.c b/components/bootloader_support/src/esp32s31/flash_encryption_secure_features.c new file mode 100644 index 0000000000..4b57850cc4 --- /dev/null +++ b/components/bootloader_support/src/esp32s31/flash_encryption_secure_features.c @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include + #include "esp_secure_boot.h" + #include "esp_efuse.h" + #include "esp_efuse_table.h" + #include "esp_log.h" + #include "sdkconfig.h" + + ESP_LOG_ATTR_TAG(TAG, "secure_boot"); + + esp_err_t esp_secure_boot_enable_secure_features(void) + { + esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); + + #ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + ESP_LOGI(TAG, "Enabling Security download mode..."); + esp_err_t err = esp_efuse_enable_rom_secure_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not enable Security download mode..."); + return err; + } + #elif CONFIG_SECURE_DISABLE_ROM_DL_MODE + ESP_LOGI(TAG, "Disable ROM Download mode..."); + esp_err_t err = esp_efuse_disable_rom_download_mode(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Could not disable ROM Download mode..."); + return err; + } + #else + ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED"); + #endif + + #ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG + ESP_LOGI(TAG, "Disable hardware & software JTAG..."); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG); + esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); + esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count); + #else + ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED"); + #endif + + #ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE); + #endif + + esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN); + + #ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS + bool rd_dis_now = true; + #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + /* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot + when Flash Encryption is being enabled */ + rd_dis_now = esp_efuse_is_flash_encryption_enabled(); + #endif + if (rd_dis_now) { + ESP_LOGI(TAG, "Prevent read disabling of additional efuses..."); + esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS); + } + #else + ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED"); + #endif + + return ESP_OK; + } diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index e3c52b4305..5e8eb135f3 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -433,7 +433,8 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) // are mutually exclusive because this will make the chip not functional. // Only one type key must be configured in eFuses. secure = false; - for (unsigned i = 0; i < sizeof(purposes) / sizeof(esp_efuse_purpose_t); i++) { + size_t purpose_count = sizeof(purposes) / sizeof(esp_efuse_purpose_t); + for (size_t i = 0; i < purpose_count; i++) { esp_efuse_block_t block; if (esp_efuse_find_purpose(purposes[i], &block)) { secure = esp_efuse_get_key_dis_read(block); diff --git a/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h b/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h index f5c0c4faa4..3e7a3e81f1 100644 --- a/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h +++ b/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h @@ -139,7 +139,8 @@ static inline __attribute__((always_inline)) void clk_ll_lp_pll_disable(void) */ static inline __attribute__((always_inline)) void clk_ll_mpll_enable(void) { - // TODO: [ESP32S31] IDF-14733 + REG_SET_BIT(PMU_PSRAM_CFG_REG, PMU_PSRAM_XPD); + REG_SET_BIT(HP_ALIVE_SYS_HP_CLK_CTRL_REG, HP_ALIVE_SYS_HP_MPLL_500M_CLK_EN); } /** @@ -147,7 +148,7 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_enable(void) */ static inline __attribute__((always_inline)) void clk_ll_mpll_disable(void) { - // TODO: [ESP32S31] IDF-14733 + REG_CLR_BIT(PMU_PSRAM_CFG_REG, PMU_PSRAM_XPD); } /** @@ -289,6 +290,18 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled // TODO: [ESP32S31] IDF-14733 } +/** + * @brief Get XTAL_CLK frequency + * + * @return Main XTAL clock frequency, in MHz. + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(void) +{ + return 40; +} + +#define clk_ll_xtal_load_freq_mhz() clk_ll_xtal_get_freq_mhz() + /** * @brief Enable the digital RC32K_CLK, which is used to support peripherals. */ @@ -386,9 +399,8 @@ static inline __attribute__((always_inline)) bool clk_ll_cpll_calibration_is_don */ static inline __attribute__((always_inline)) uint32_t clk_ll_mpll_get_freq_mhz(uint32_t xtal_freq_mhz) { - // uint8_t div = REGI2C_READ_MASK(I2C_MPLL, I2C_MPLL_DIV_ADDR); - // uint8_t ref_div = REGI2C_READ_MASK(I2C_MPLL, I2C_MPLL_REF_DIV_ADDR); - return 0;//xtal_freq_mhz * (div + 1) / (ref_div + 1); + uint8_t fb_div = REG_GET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV); + return xtal_freq_mhz * (fb_div + 1) / 2; } /** @@ -399,7 +411,11 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_mpll_get_freq_mhz(u */ static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_t mpll_freq_mhz, uint32_t xtal_freq_mhz) { - // TODO: [ESP32S31] IDF-14733 + HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_40M); + + uint8_t ref_div = 1; + uint8_t fb_div = mpll_freq_mhz * (ref_div + 1) / xtal_freq_mhz - 1; + REG_SET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV, fb_div); } /** @@ -859,35 +875,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin // } /************************** LP STORAGE REGISTER STORE/LOAD **************************/ -/** - * @brief Store XTAL_CLK frequency in RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even, - * otherwise there will be a conflict with the low bit, which is used to disable logs - * in the ROM code. - */ -static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz) -{ - // TODO: [ESP32S31] IDF-14733 -} - -/** - * @brief Load XTAL_CLK frequency from RTC storage register - * - * Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit - * halves. These are the routines to work with that representation. - * - * @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid. - */ -static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void) -{ - // TODO: [ESP32S31] IDF-14733 - return 0; -} - /** * @brief Store RTC_SLOW_CLK calibration value in RTC storage register * diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h index 3dee57e309..7e87504bf2 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h @@ -84,6 +84,7 @@ extern "C" { #define MSPI_LL_AXI_DISABLE_SUPPORTED 1 #define MSPI_LL_INTR_EVENT_SUPPORTED 1 +#define MSPI_LL_PSRAM_DQS1_SUPPORTED 1 /** * MSPI DQS ID diff --git a/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h index 8c8a17dc4b..ecb8c85f40 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/mspi_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,12 +29,16 @@ #include "esp_bit_defs.h" #include "hal/assert.h" #include "soc/soc.h" +#include "soc/hp_sys_clkrst_struct.h" #include "soc/spi_mem_reg.h" #include "soc/io_mux_reg.h" +#include "soc/iomux_mspi_pin_reg.h" +#include "soc/iomux_mspi_pin_struct.h" #include "soc/spi_mem_struct.h" #include "soc/spi_mem_s_struct.h" #include "soc/spi_mem_c_reg.h" #include "soc/spi1_mem_c_reg.h" +#include "soc/clk_tree_defs.h" #ifdef __cplusplus extern "C" { @@ -50,8 +54,171 @@ extern "C" { #define MSPI_LL_AXI_DISABLE_SUPPORTED 1 #define MSPI_LL_INTR_EVENT_SUPPORTED 1 -// TODO: ["ESP32S31"] IDF-14653 +/** + * MSPI DQS ID + */ +typedef enum { + MSPI_LL_DQS_ID_0, +} mspi_ll_dqs_id_t; +/** + * MSPI DQS Phase + */ +typedef enum { + MSPI_LL_DQS_PHASE_67_5, + MSPI_LL_DQS_PHASE_78_75, + MSPI_LL_DQS_PHASE_90, + MSPI_LL_DQS_PHASE_101_25, + MSPI_LL_DQS_PHASE_MAX, +} mspi_ll_dqs_phase_t; + +/** + * MSPI Delayline + * + * @note The Sequence of these enums should not be changed + */ +typedef enum { + MSPI_LL_PIN_D = 0, + MSPI_LL_PIN_Q, + MSPI_LL_PIN_WP, + MSPI_LL_PIN_HD, + MSPI_LL_PIN_D4, + MSPI_LL_PIN_D5, + MSPI_LL_PIN_D6, + MSPI_LL_PIN_D7, + MSPI_LL_PIN_DQS0, + MSPI_LL_PIN_CLK, + MSPI_LL_PIN_CS, + MSPI_LL_PIN_MAX, +} mspi_ll_pin_t; + +/*--------------------------------------------------------------- + PSRAM tuning +---------------------------------------------------------------*/ +/** + * Set all MSPI DQS phase + * + * @param dqs_id DQS ID + * @param phase Phase + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_set_dqs_phase(mspi_ll_dqs_id_t dqs_id, mspi_ll_dqs_phase_t phase) +{ + HAL_ASSERT(dqs_id < 1); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_PHASE, phase); +} + +/** + * Set all MSPI delayline + * + * @param pin Pin + * @param delayline Delayline + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_set_delayline(mspi_ll_pin_t pin, uint8_t delayline) +{ + HAL_ASSERT(pin < MSPI_LL_PIN_MAX); + + switch (pin) { + case MSPI_LL_PIN_DQS0: + MSPI_IOMUX.psram_pin_group.dqs0.reg_psram_dqs_delay_90 = delayline; + MSPI_IOMUX.psram_pin_group.dqs0.reg_psram_dqs_delay_270 = delayline; + break; + case MSPI_LL_PIN_D: + case MSPI_LL_PIN_Q: + case MSPI_LL_PIN_WP: + case MSPI_LL_PIN_HD: + case MSPI_LL_PIN_D4: + case MSPI_LL_PIN_D5: + case MSPI_LL_PIN_D6: + case MSPI_LL_PIN_D7: + MSPI_IOMUX.psram_pin_group.pin_group0[pin].reg_psram_pin_dlc = delayline; + break; + case MSPI_LL_PIN_CLK: + MSPI_IOMUX.psram_pin_group.pin_clk.reg_psram_pin_dlc = delayline; + break; + case MSPI_LL_PIN_CS: + MSPI_IOMUX.psram_pin_group.pin_cs.reg_psram_pin_dlc = delayline; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * Enable DQS + * + * @param en Enable/disable + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_enable_dqs(bool en) +{ + if (en) { + REG_SET_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_XPD); + } else { + REG_CLR_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_XPD); + } +} + +/** + * Set all MSPI pin drive + * + * @param drv Pin drive + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_pin_drv_set(uint8_t drv) +{ + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_D_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_Q_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_Q_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_WP_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_WP_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_HOLD_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_HOLD_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ4_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ4_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ5_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ5_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ6_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ6_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ7_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ7_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_CK_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_CK_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_CS_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_CS_DRV, drv); +} + +/*--------------------------------------------------------------- + Flash tuning +---------------------------------------------------------------*/ +/* + * @brief Select FLASH clock source + * + * @param mspi_id mspi_id + * @param clk_src clock source, see valid sources in type `soc_periph_flash_clk_src_t` + */ +__attribute__((always_inline)) +static inline void _mspi_timing_ll_set_flash_clk_src(uint32_t mspi_id, soc_periph_flash_clk_src_t clk_src) +{ + HAL_ASSERT(mspi_id == MSPI_TIMING_LL_MSPI_ID_0); + uint32_t clk_val = 0; + switch (clk_src) { + case FLASH_CLK_SRC_XTAL: + clk_val = 0; + break; + case FLASH_CLK_SRC_SPLL: + clk_val = 1; + break; + case FLASH_CLK_SRC_CPLL: + clk_val = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + HP_SYS_CLKRST.flash_ctrl0.reg_flash_sys_clk_en = 1; + HP_SYS_CLKRST.flash_ctrl0.reg_flash_pll_clk_en = 1; + HP_SYS_CLKRST.flash_ctrl0.reg_flash_clk_src_sel = clk_val; +} + +/*--------------------------------------------------------------- + Misc +---------------------------------------------------------------*/ /** * @brief Enable/Disable MSPI controller interrupt * diff --git a/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h new file mode 100644 index 0000000000..5e1613866a --- /dev/null +++ b/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h @@ -0,0 +1,946 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/config.h" +#include "soc/spi_mem_s_struct.h" +#include "soc/spi_mem_s_reg.h" +#include "soc/spi1_mem_s_reg.h" +#include "soc/spi1_mem_s_struct.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/clk_tree_defs.h" +#include "soc/hp_system_struct.h" +#include "rom/opi_flash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSRAM_CTRLR_LL_MSPI_ID_2 2 +#define PSRAM_CTRLR_LL_MSPI_ID_3 3 +#define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_2 +#define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_3 + +#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 +#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) +#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) + +#define PSRAM_CTRLR_LL_FIFO_MAX_BYTES 64 + +#define PSRAM_CTRLR_LL_THRESH_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_ADDR_INT_SUPPORTED 1 +#define PSRAM_CTRLR_LL_EVENT_SLV_ST_END (1<<3) +#define PSRAM_CTRLR_LL_EVENT_MST_ST_END (1<<4) +#define PSRAM_CTRLR_LL_EVENT_ECC_ERR (1<<5) +#define PSRAM_CTRLR_LL_EVENT_PMS_REJECT (1<<6) +#define PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR (1<<7) +#define PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR (1<<8) +#define PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR (1<<9) +#define PSRAM_CTRLR_LL_EVENT_RX_TRANS_OVF (1<<26) +#define PSRAM_CTRLR_LL_EVENT_TX_TRANS_UDF (1<<27) +#define PSRAM_CTRLR_LL_EVENT_MASK (PSRAM_CTRLR_LL_EVENT_ECC_ERR | PSRAM_CTRLR_LL_EVENT_PMS_REJECT | PSRAM_CTRLR_LL_EVENT_AXI_RADDR_ERR | \ + PSRAM_CTRLR_LL_EVENT_AXI_WR_FLASH_ERR | PSRAM_CTRLR_LL_EVENT_AXI_WADDR_ERR | PSRAM_CTRLR_LL_EVENT_RX_TRANS_OVF | \ + PSRAM_CTRLR_LL_EVENT_TX_TRANS_UDF) + +#define PSRAM_CTRLR_LL_INTR_EVENT_SUPPORTED 1 + +/** + * @brief Set PSRAM write cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_wr_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1; + SPIMEM2.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_dwr_cmd, mem_cache_sram_usr_wr_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM read cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM2.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1; + SPIMEM2.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM2.mem_sram_drd_cmd, mem_cache_sram_usr_rd_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM addr bitlen + * + * @param mspi_id mspi_id + * @param addr_bitlen address bitlen + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_addr_bitlen(uint32_t mspi_id, uint32_t addr_bitlen) +{ + (void)mspi_id; + HAL_ASSERT(addr_bitlen > 0); + SPIMEM2.mem_cache_sctrl.mem_sram_addr_bitlen = addr_bitlen - 1; +} + +/** + * @brief Enable PSRAM 4B addr + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_4byte_addr(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_cache_sctrl.mem_cache_usr_saddr_4byte = en; +} + +/** + * @brief Set PSRAM write dummy + * + * @param mspi_id mspi_id + * @param dummy_n dummy number + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_wr_dummy(uint32_t mspi_id, uint32_t dummy_n) +{ + (void)mspi_id; + HAL_ASSERT(dummy_n > 0); + SPIMEM2.mem_cache_sctrl.mem_usr_wr_sram_dummy = 1; + SPIMEM2.mem_cache_sctrl.mem_sram_wdummy_cyclelen = dummy_n - 1; +} + +/** + * @brief Set PSRAM read dummy + * + * @param mspi_id mspi_id + * @param dummy_n dummy number + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_dummy(uint32_t mspi_id, uint32_t dummy_n) +{ + (void)mspi_id; + HAL_ASSERT(dummy_n > 0); + SPIMEM2.mem_cache_sctrl.mem_usr_rd_sram_dummy = 1; + SPIMEM2.mem_cache_sctrl.mem_sram_rdummy_cyclelen = dummy_n - 1; +} + +/** + * @brief Enable PSRAM variable dummy + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_variable_dummy(uint32_t mspi_id, bool en) +{ + if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) { + SPIMEM2.smem_ddr.smem_var_dummy = en; + } else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) { + SPIMEM3.ddr.fmem_var_dummy = en; + } +} + +/** + * @brief Enable PSRAM write dummy level control + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_wr_dummy_level_control(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_sram_cmd.mem_sdummy_wout = en; +} + +/** + * @brief Enable PSRAM read dummy level control + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_rd_dummy_level_control(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_sram_cmd.mem_sdummy_rin = en; +} + +/** + * @brief Enable PSRAM ddr mode + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_ddr_mode(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ddr.smem_ddr_en = en; +} + +/** + * @brief Enable PSRAM ddr write data swap + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_ddr_wr_data_swap(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ddr.smem_ddr_wdat_swp = en; +} + +/** + * @brief Enable PSRAM ddr read data swap + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_ddr_rd_data_swap(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ddr.smem_ddr_rdat_swp = en; +} + +/** + * @brief Enable PSRAM octal mode + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_oct_line_mode(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_cache_sctrl.mem_sram_oct = en; + SPIMEM2.mem_sram_cmd.mem_scmd_oct = en; + SPIMEM2.mem_sram_cmd.mem_saddr_oct = en; + SPIMEM2.mem_sram_cmd.mem_sdout_oct = en; + SPIMEM2.mem_sram_cmd.mem_sdin_oct = en; +} + +/** + * @brief Enable PSRAM hex data line mode + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_hex_data_line_mode(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_sram_cmd.mem_sdin_hex = en; + SPIMEM2.mem_sram_cmd.mem_sdout_hex = en; +} + +/** + * @brief Get PSRAM hex data line mode enable status + * + * @param mspi_id mspi_id + * + * @return true if hex data line mode is enabled, false otherwise + */ +__attribute__((always_inline)) +static inline bool psram_ctrlr_ll_is_hex_data_line_mode(uint32_t mspi_id) +{ + (void)mspi_id; + return (SPIMEM2.mem_sram_cmd.mem_sdin_hex & SPIMEM2.mem_sram_cmd.mem_sdout_hex); +} + +/** + * @brief Enable PSRAM AXI master access + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_axi_access(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_cache_fctrl.mem_axi_req_en = en; + SPIMEM2.mem_cache_fctrl.close_axi_inf_en = !en; +} + +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 +/** + * @brief Enable PSRAM AXI weight arbiter for TX / RX AXI requests + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_axi_req_weight_arbiter(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_cache_fctrl.mem_arb_wei_en = en; +} + +/** + * @brief Set PSRAM AXI request weight + * + * @param mspi_id mspi_id + * @param rd_weight read weight + * @param wr_weight write weight + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_axi_req_weight(uint32_t mspi_id, uint32_t rd_weight, uint32_t wr_weight) +{ + //1~15 + HAL_ASSERT(rd_weight && rd_weight < 16); + HAL_ASSERT(wr_weight && wr_weight < 16); + + SPIMEM2.mem_cache_fctrl.mem_arb_req0_wei = rd_weight; + SPIMEM2.mem_cache_fctrl.mem_arb_req1_wei = wr_weight; +} + +/** + * @brief Set PSRAM AXI request priority + * + * @param mspi_id mspi_id + * @param rd_prio read priority + * @param wr_prio write priority + */ +static inline void psram_ctrlr_ll_set_axi_req_priority(uint32_t mspi_id, uint32_t rd_prio, uint32_t wr_prio) +{ + SPIMEM2.mem_cache_fctrl.mem_arb_req0_pri = rd_prio; + SPIMEM2.mem_cache_fctrl.mem_arb_req1_pri = wr_prio; +} +#endif + +/** + * @brief Enable PSRAM write splice transfer + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_wr_splice(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_ctrl1.mem_aw_splice_en = en; +} + +/** + * @brief Enable PSRAM read splice transfer + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_rd_splice(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.mem_ctrl1.mem_ar_splice_en = en; +} + +/** + * @brief Enable PSRAM module clock + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + HP_SYS_CLKRST.psram_ctrl0.reg_psram_sys_clk_en = en; + HP_SYS_CLKRST.psram_ctrl0.reg_psram_pll_clk_en = en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_enable_module_clock(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _psram_ctrlr_ll_enable_module_clock(__VA_ARGS__); \ + } while(0) + +/** + * @brief Reset PSRAM module clock + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_reset_module_clock(uint32_t mspi_id) +{ + HP_SYS_CLKRST.psram_ctrl0.reg_psram_axi_rst_en = 1; + HP_SYS_CLKRST.psram_ctrl0.reg_psram_apb_rst_en = 1; + HP_SYS_CLKRST.psram_ctrl0.reg_psram_apb_rst_en = 0; + HP_SYS_CLKRST.psram_ctrl0.reg_psram_axi_rst_en = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_reset_module_clock(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _psram_ctrlr_ll_reset_module_clock(__VA_ARGS__); \ + } while(0) + +/** + * @brief Select PSRAM clock source + * + * @param mspi_id mspi_id + * @param clk_src clock source, see valid sources in type `soc_periph_psram_clk_src_t` + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph_psram_clk_src_t clk_src) +{ + (void)mspi_id; + uint32_t clk_val = 0; + switch (clk_src) { + case PSRAM_CLK_SRC_XTAL: + clk_val = 0; + break; + case PSRAM_CLK_SRC_MPLL: + clk_val = 1; + break; + case PSRAM_CLK_SRC_CPLL: + clk_val = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + HP_SYS_CLKRST.psram_ctrl0.reg_psram_clk_src_sel = clk_val; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_select_clk_source(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _psram_ctrlr_ll_select_clk_source(__VA_ARGS__); \ + } while(0) + +/** + * @brief Set PSRAM core clock + * + * @param mspi_id mspi_id + * @param freqdiv Divider value + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_set_core_clock_div(uint8_t spi_num, uint32_t freqdiv) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.psram_ctrl0, reg_psram_core_clk_div_num, freqdiv - 1); +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_set_core_clock_div(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _psram_ctrlr_ll_set_core_clock_div(__VA_ARGS__); \ + } while(0) + +/** + * @brief Enable or disable the PSRAM core clock + * + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_enable_core_clock(uint8_t spi_num, bool en) +{ + HP_SYS_CLKRST.psram_ctrl0.reg_psram_core_clk_en = en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_enable_core_clock(...) do { \ + (void)__DECLARE_RCC_ATOMIC_ENV; \ + _psram_ctrlr_ll_enable_core_clock(__VA_ARGS__); \ + } while(0) + +/** + * @brief Set PSRAM bus clock + * + * @param mspi_id mspi_id + * @param freqdiv Divider value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_bus_clock(uint32_t mspi_id, uint32_t freqdiv) +{ + if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) { + if (freqdiv == 1) { + WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, SPI_MEM_S_SCLK_EQU_SYSCLK); + } else { + uint32_t freqbits = (((freqdiv - 1) << SPI_MEM_S_SCLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_S_SCLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_S_SCLKCNT_L_S); + WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, freqbits); + } + } else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) { + if (freqdiv == 1) { + WRITE_PERI_REG(SPI1_MEM_S_CLOCK_REG, SPI1_MEM_S_CLK_EQU_SYSCLK); + } else { + uint32_t freqbits = (((freqdiv - 1) << SPI1_MEM_S_CLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI1_MEM_S_CLKCNT_H_S)) | ((freqdiv - 1) << SPI1_MEM_S_CLKCNT_L_S); + WRITE_PERI_REG(SPI1_MEM_S_CLOCK_REG, freqbits); + } + } +} + +/** + * @brief Enable PSRAM DLL + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_dll(uint32_t mspi_id, bool en) +{ + if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) { + SPIMEM2.smem_timing_cali.smem_dll_timing_cali = en; + } else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) { + SPIMEM2.mem_timing_cali.mem_dll_timing_cali = en; + } else { + HAL_ASSERT(false); + } +} + +/** + * @brief Set CS setup + * + * @param mspi_id mspi_id + * @param setup_n cs setup time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_setup(uint32_t mspi_id, uint32_t setup_n) +{ + (void)mspi_id; + HAL_ASSERT(setup_n > 0); + SPIMEM2.smem_ac.smem_cs_setup = 1; + SPIMEM2.smem_ac.smem_cs_setup_time = setup_n - 1; +} + +/** + * @brief Set CS hold + * + * @param mspi_id mspi_id + * @param hold_n cs hold time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold(uint32_t mspi_id, uint32_t hold_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_n > 0); + SPIMEM2.smem_ac.smem_cs_hold = 1; + SPIMEM2.smem_ac.smem_cs_hold_time = hold_n - 1; +} + +/** + * @brief Set CS hold delay + * + * @param mspi_id mspi_id + * @param hold_n cs hold time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold_delay(uint32_t mspi_id, uint32_t hold_delay_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_delay_n > 0); + SPIMEM2.smem_ac.smem_cs_hold_delay = hold_delay_n - 1; +} + +/** + * @brief Set ECC CS hold + * + * @param mspi_id mspi_id + * @param hold_n cs hold time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold_ecc(uint32_t mspi_id, uint32_t hold_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_n > 0); + SPIMEM2.smem_ac.smem_ecc_cs_hold_time = hold_n - 1; +} + +/** + * @brief Enable 16to18 ECC + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_16to18_ecc(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ac.smem_ecc_16to18_byte_en = en; +} + +/** + * @brief Enable ECC skip page corner + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_skip_page_corner(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ac.smem_ecc_skip_page_corner = en; +} + +/** + * @brief Enable splitting transactions + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_split_trans(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ac.smem_split_trans_en = en; +} + +/** + * @brief Enable ECC address conversion + * + * @param mspi_id mspi_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_ecc_addr_conversion(uint32_t mspi_id, bool en) +{ + (void)mspi_id; + SPIMEM2.smem_ecc_ctrl.smem_ecc_addr_en = en; +} + +/** + * @brief Set page size + * + * @param mspi_id mspi_id + * @param page_size page size + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_page_size(uint32_t mspi_id, uint32_t page_size) +{ + (void)mspi_id; + switch (page_size) { + case 256: + SPIMEM2.smem_ecc_ctrl.smem_page_size = 0; + break; + case 512: + SPIMEM2.smem_ecc_ctrl.smem_page_size = 1; + break; + case 1024: + SPIMEM2.smem_ecc_ctrl.smem_page_size = 2; + break; + case 2048: + SPIMEM2.smem_ecc_ctrl.smem_page_size = 3; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Get page size + * + * @param mspi_id mspi_id + * + * @return page size + */ +__attribute__((always_inline)) +static inline uint32_t psram_ctrlr_ll_get_page_size(uint32_t mspi_id) +{ + (void)mspi_id; + uint32_t page_size = 0; + + uint32_t reg_val = SPIMEM2.smem_ecc_ctrl.smem_page_size; + switch (reg_val) { + case 0: + page_size = 256; + break; + case 1: + page_size = 512; + break; + case 2: + page_size = 1024; + break; + case 3: + page_size = 2048; + break; + default: + HAL_ASSERT(false); + } + + return page_size; +} + +/** + * @brief Enable PMS ECC + * + * @param mspi_id mspi_id + * @param region_id region_id + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_ecc = en; +} + +/** + * @brief Set PMS attr + * + * @param mspi_id mspi_id + * @param region_id region_id + * @param attr_mask attribute mask + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 0; + SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 0; + if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { + SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 1; + } + if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { + SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 1; + } +} + +/** + * @brief Set PMS address + * + * @param mspi_id mspi_id + * @param region_id region_id + * @param addr start addr + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + SPIMEM2.smem_pmsn_addr[region_id].smem_pmsn_addr_s = addr; +} + +/** + * @brief Set PMS size + * + * @param mspi_id mspi_id + * @param region_id region_id + * @param size size + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + SPIMEM2.smem_pmsn_size[region_id].smem_pmsn_size = size; +} + +/** + * @brief Get PMS address + * + * @param mspi_id mspi_id + * @param region_id region_id + */ +__attribute__((always_inline)) +static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + return SPIMEM2.smem_pmsn_addr[region_id].smem_pmsn_addr_s; +} + +/** + * @brief Get PMS size + * + * @param mspi_id mspi_id + * @param region_id region_id + */ +__attribute__((always_inline)) +static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) +{ + (void)mspi_id; + HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); + return SPIMEM2.smem_pmsn_size[region_id].smem_pmsn_size; +} + +/** + * @brief PSRAM common transaction + * + * See `opi_flash.h` for parameters + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_rom_spiflash_read_mode_t mode, + uint32_t cmd, uint32_t cmd_bitlen, + uint32_t addr, uint32_t addr_bitlen, + uint32_t dummy_bits, + uint8_t* mosi_data, uint32_t mosi_bitlen, + uint8_t* miso_data, uint32_t miso_bitlen, + uint32_t cs_mask, + bool is_write_erase_operation) +{ + esp_rom_spi_set_op_mode(mspi_id, mode); + esp_rom_spi_cmd_t conf = { + .cmd = cmd, + .cmdBitLen = cmd_bitlen, + .addr = &addr, + .addrBitLen = addr_bitlen, + .txData = (uint32_t *)mosi_data, + .txDataBitLen = mosi_bitlen, + .rxData = (uint32_t *)miso_data, + .rxDataBitLen = miso_bitlen, + .dummyBitLen = dummy_bits, + }; + esp_rom_spi_cmd_config(mspi_id, &conf); + esp_rom_spi_cmd_start(mspi_id, miso_data, miso_bitlen / 8, cs_mask, is_write_erase_operation); +} + +/** + * @brief PSRAM common transaction + * + * See `opi_flash.h` for parameters + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_common_transaction(uint32_t mspi_id, + uint32_t cmd, uint32_t cmd_bitlen, + uint32_t addr, uint32_t addr_bitlen, + uint32_t dummy_bits, + uint8_t* mosi_data, uint32_t mosi_bitlen, + uint8_t* miso_data, uint32_t miso_bitlen, + bool is_write_erase_operation) +{ + esp_rom_spiflash_read_mode_t mode = ESP_ROM_SPIFLASH_OPI_DTR_MODE; + uint32_t cs_mask = 1 << 1; + psram_ctrlr_ll_common_transaction_base(mspi_id, mode, cmd, cmd_bitlen, addr, addr_bitlen, dummy_bits, + mosi_data, mosi_bitlen, miso_data, miso_bitlen, cs_mask, + is_write_erase_operation); +} + +/** + * @brief Wait MSPI PSRAM controller transaction done + * + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_wait_all_transaction_done(void) +{ +#define ALL_TRANSACTION_DONE ( SPI_MEM_S_ALL_FIFO_EMPTY | \ + SPI_RDATA_AFIFO_REMPTY | \ + SPI_RADDR_AFIFO_REMPTY | \ + SPI_WDATA_AFIFO_REMPTY | \ + SPI_WBLEN_AFIFO_REMPTY | \ + SPI_ALL_AXI_TRANS_AFIFO_EMPTY) + while (SPIMEM2.smem_axi_addr_ctrl.val != ALL_TRANSACTION_DONE) { + ; + } +} + +/** + * @brief Enable/Disable PSRAM controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + * @param enable enable / disable + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_intr(uint32_t mspi_id, uint32_t intr_mask, bool enable) +{ + if (enable) { + SPIMEM2.mem_int_ena.val |= intr_mask; + } else { + SPIMEM2.mem_int_ena.val &= ~intr_mask; + } +} + +/** + * @brief Clear PSRAM controller interrupt + * + * @param mspi_id mspi_id + * @param intr_mask interrupt mask + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_clear_intr(uint32_t mspi_id, uint32_t intr_mask) +{ + SPIMEM2.mem_int_clr.val = intr_mask; +} + +/** + * @brief Get PSRAM controller interrupt raw + * + * @param mspi_id mspi_id + */ +__attribute__((always_inline)) +static inline uint32_t psram_ctrlr_ll_get_intr_raw(uint32_t mspi_id) +{ + return SPIMEM2.mem_int_raw.val; +} + +/** + * @brief Backup PSRAM controller registers + * + * @param mspi_id mspi_id + * @param reg registers + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_backup_registers(uint32_t mspi_id, spi_mem_s_dev_t *reg) +{ + memcpy(reg, &SPIMEM2, sizeof(spi_mem_s_dev_t)); +} + +/** + * @brief Restore PSRAM controller registers + * + * @param mspi_id mspi_id + * @param reg registers + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_restore_registers(uint32_t mspi_id, spi_mem_s_dev_t *reg) +{ + memcpy(&SPIMEM2, reg, sizeof(spi_mem_s_dev_t)); +} + +/** + * @brief Disable core error response + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_disable_core_err_resp(void) +{ + HP_SYSTEM.core_err_resp_dis.val = 0x7; +} + +/** + * @brief Enable core error response + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_core_err_resp(void) +{ + HP_SYSTEM.core_err_resp_dis.val = 0x0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h index 2d2b4ca16d..bab1245387 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h @@ -682,7 +682,7 @@ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void) switch (HP_SYS_CLKRST.flash_ctrl0.reg_flash_clk_src_sel) { case 0: - source_clk_mhz = clk_ll_xtal_load_freq_mhz(); + source_clk_mhz = clk_ll_xtal_get_freq_mhz(); break; case 1: source_clk_mhz = CLK_LL_PLL_480M_FREQ_MHZ; // SPLL diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 559a57748c..65a50c2a9b 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -33,6 +33,8 @@ static int s_apll_ref_cnt = 0; #if SOC_CLK_MPLL_SUPPORTED static uint32_t s_cur_mpll_freq_hz = 0; static int s_mpll_ref_cnt = 0; +#endif +#if CONFIG_ESP_LDO_RESERVE_PSRAM static esp_ldo_channel_handle_t s_ldo_chan = NULL; #endif diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 1527d7fd9b..4b51f5b207 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -37,20 +37,21 @@ entries: rtc_sleep:rtc_sleep_pd (noflash) if IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y: rtc_sleep:rtc_sleep_pu (noflash) - if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y: - pmu_sleep (noflash) - if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP != y: - pmu_sleep_clock_icg:pmu_sleep_clock_icg_config (noflash) - sleep_mspi (noflash) + if SOC_PMU_SUPPORTED = y: if SPIRAM_FLASH_LOAD_TO_PSRAM = y: pmu_init (noflash) pmu_param (noflash) - elif PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32P4 != y: - pmu_param:get_act_lp_dbias (noflash) - if IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 = y: - pmu_param:get_act_hp_drvb (noflash) - else: - pmu_param:get_act_hp_dbias (noflash) + if SOC_LIGHT_SLEEP_SUPPORTED = y: + pmu_sleep (noflash) + if SOC_PM_SLEEP_CLK_ICG_USE_REGDMA = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP != y: + pmu_sleep_clock_icg:pmu_sleep_clock_icg_config (noflash) + sleep_mspi (noflash) + if PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32P4 != y: + pmu_param:get_act_lp_dbias (noflash) + if IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21 = y: + pmu_param:get_act_hp_drvb (noflash) + else: + pmu_param:get_act_hp_dbias (noflash) if SOC_PMU_PVT_SUPPORTED = y && ESP_ENABLE_PVT = y: pmu_pvt (noflash) if PM_SLP_IRAM_OPT = y && SOC_USB_SERIAL_JTAG_SUPPORTED = y: diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c b/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c index e5451d5216..f6a7cc95a5 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -245,9 +245,9 @@ static void s_sweep_for_success_sample_points(uint8_t *reference_data, void *con } } - ESP_DRAM_LOGD(TAG, "test nums: %" PRIu32 ", test result: [id][good/bad][good_times]:", s_tuning_cfg_drv.sweep_test_nums); + ESP_DRAM_LOGW(TAG, "test nums: %" PRIu32 ", test result: [id][good/bad][good_times]:", s_tuning_cfg_drv.sweep_test_nums); for (config_idx = 0; config_idx < timing_config->available_config_num; config_idx++) { - ESP_DRAM_LOGD(TAG, "[%"PRIu32"][%s][%" PRIu32 "] ", config_idx, out_array[config_idx] == s_tuning_cfg_drv.sweep_test_nums ? "good" : "bad", out_array[config_idx]); + ESP_DRAM_LOGW(TAG, "[%"PRIu32"][%s][%" PRIu32 "] ", config_idx, out_array[config_idx] == s_tuning_cfg_drv.sweep_test_nums ? "good" : "bad", out_array[config_idx]); } } diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt new file mode 100644 index 0000000000..668e5643d5 --- /dev/null +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/CMakeLists.txt @@ -0,0 +1,11 @@ +target_include_directories(${COMPONENT_LIB} PUBLIC .) + +set(srcs) + +if(NOT BOOTLOADER_BUILD) + if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs "mspi_timing_config.c") + endif() +endif() + +target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c new file mode 100644 index 0000000000..8d322f8705 --- /dev/null +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_config.c @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_types.h" +#include "esp_log.h" +#include "soc/soc_caps.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/mspi_timing_config.h" +#include "mspi_timing_tuning_configs.h" +#include "hal/psram_ctrlr_ll.h" +#include "hal/mspi_ll.h" +#include "soc/hp_sys_clkrst_struct.h" + +ESP_LOG_ATTR_TAG(TAG, "MSPI Timing"); + +//-------------------------------------MSPI Clock Setting-------------------------------------// +void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi) +{ + uint32_t freqdiv = MSPI_TIMING_MPLL_FREQ_MHZ / MSPI_TIMING_CORE_CLOCK_DIV / psram_freq_mhz; + assert(freqdiv > 0); + ESP_DRAM_LOGD(TAG, "psram_freq_mhz: %" PRIu32 " mhz, bus clock div: %" PRIu32, psram_freq_mhz, freqdiv); + PERIPH_RCC_ATOMIC() { + //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_set_core_clock_div(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, freqdiv); + } +} + +void mspi_timing_config_set_flash_clock(uint32_t flash_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi) +{ +#if MSPI_TIMING_FLASH_NEEDS_TUNING + assert(HP_SYS_CLKRST.peri_clk_ctrl00.reg_flash_clk_src_sel == 1); + + uint32_t core_clock_mhz = MSPI_TIMING_SPLL_FREQ_MHZ / MSPI_TIMING_LL_HP_FLASH_CORE_CLK_DIV; + assert(core_clock_mhz == 120); + uint32_t freqdiv = core_clock_mhz / flash_freq_mhz; + + PERIPH_RCC_ATOMIC() { + //core clock shared among SPI0 / SPI1 + mspi_timing_ll_set_flash_core_clock(MSPI_TIMING_LL_MSPI_ID_0, core_clock_mhz); + } + + mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_0, freqdiv); + if (control_both_mspi) { + mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_1, freqdiv); + } + + mspi_timing_ll_mask_invalid_dqs(MSPI_TIMING_LL_MSPI_ID_0, true); + mspi_timing_ll_mask_invalid_dqs(MSPI_TIMING_LL_MSPI_ID_1, true); +#endif +} diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h new file mode 100644 index 0000000000..cb1e4e2eca --- /dev/null +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/port/esp32s31/mspi_timing_tuning_configs.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" + +#define MSPI_TIMING_MSPI1_IS_INVOLVED CONFIG_ESPTOOLPY_FLASHFREQ_120M //This means esp flash driver needs to be notified +#define MSPI_TIMING_CONFIG_NUM_MAX 32 //This should be larger than the max available timing config num +#define MSPI_TIMING_TEST_DATA_LEN 128 +#define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0x80 +#define MSPI_TIMING_DELAYLINE_TEST_NUMS 100 +#define MSPI_TIMING_FLASH_TEST_DATA_ADDR CONFIG_BOOTLOADER_OFFSET_IN_FLASH + +#define MSPI_TIMING_CORE_CLOCK_DIV 1 +#if CONFIG_SPIRAM_SPEED_250M +#define MSPI_TIMING_PSRAM_NEEDS_TUNING 1 +#define MSPI_TIMING_MPLL_FREQ_MHZ 500 +#elif CONFIG_SPIRAM_SPEED_200M +#define MSPI_TIMING_PSRAM_NEEDS_TUNING 1 +#define MSPI_TIMING_MPLL_FREQ_MHZ 400 +#elif CONFIG_SPIRAM_SPEED_80M +#define MSPI_TIMING_PSRAM_NEEDS_TUNING 1 +#define MSPI_TIMING_MPLL_FREQ_MHZ 320 +#else +#define MSPI_TIMING_MPLL_FREQ_MHZ 400 +#endif +#define MSPI_TIMING_SPLL_FREQ_MHZ 480 + +#define MSPI_TIMING_PSRAM_DTR_MODE CONFIG_SPIRAM_MODE_OCT +#define MSPI_TIMING_FLASH_STR_MODE 1 + +#if CONFIG_ESPTOOLPY_FLASHFREQ_20M +#define MSPI_TIMING_FLASH_MODULE_CLOCK 20 +#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M +#define MSPI_TIMING_FLASH_MODULE_CLOCK 40 +#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M +#define MSPI_TIMING_FLASH_MODULE_CLOCK 80 +#else //CONFIG_ESPTOOLPY_FLASHFREQ_120M +#define MSPI_TIMING_FLASH_MODULE_CLOCK 120 +#endif +#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 80) + +#if MSPI_TIMING_FLASH_NEEDS_TUNING +#define MSPI_TIMING_FLASH_CORE_CLOCK_MHZ 120 +#else +#define MSPI_TIMING_FLASH_CORE_CLOCK_MHZ 80 +#endif + +//------------------------------------------Helper Macros to get FLASH/PSRAM tuning configs-----------------------------------------------// +#define __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) \ + (mspi_timing_config_t) { .tuning_config_table = MSPI_TIMING_##type##_CONFIG_TABLE_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \ + .available_config_num = MSPI_TIMING_##type##_CONFIG_NUM_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \ + .flash_default_config_id = MSPI_TIMING_##type##_DEFAULT_CONFIG_ID_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode } + +#define _GET_TUNING_CONFIG(type, core_clock, module_clock, mode) __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) + +#define MSPI_TIMING_FLASH_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(FLASH, core_clock_mhz, module_clock_mhz, mode) diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c index c8267c37ae..134d56afcb 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,12 +49,14 @@ ESP_LOG_ATTR_TAG(TAG, "MSPI DQS"); const static uint32_t s_test_data[MSPI_TIMING_TEST_DATA_LEN] = {0x7f786655, 0xa5ff005a, 0x3f3c33aa, 0xa5ff5a00, 0x1f1e9955, 0xa5005aff, 0x0f0fccaa, 0xa55a00ff, 0x07876655, 0xffa55a00, 0x03c333aa, 0xff00a55a, 0x01e19955, 0xff005aa5, 0x00f0ccaa, 0xff5a00a5, 0x80786655, 0x00a5ff5a, 0xc03c33aa, 0x00a55aff, 0xe01e9355, 0x00ff5aa5, 0xf00fccaa, 0x005affa5, - 0xf8876655, 0x5aa5ff00, 0xfcc333aa, 0x5affa500, 0xfee19955, 0x5a00a5ff, 0x11f0ccaa, 0x5a00ffa5}; + 0xf8876655, 0x5aa5ff00, 0xfcc333aa, 0x5affa500, 0xfee19955, 0x5a00a5ff, 0x11f0ccaa, 0x5a00ffa5 + }; const static mspi_timing_config_t s_test_delayline_config = { - .delayline_table = {{0, 15}, {0, 14}, {0, 13}, {0, 12}, {0, 11}, {0, 10}, {0, 9}, {0, 8}, {0, 7}, {0, 6}, {0, 5}, {0, 4}, {0, 3}, {0, 2}, {0, 1}, - {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0}}, - .available_config_num = 31, - }; + .delayline_table = {{0, 15}, {0, 14}, {0, 13}, {0, 12}, {0, 11}, {0, 10}, {0, 9}, {0, 8}, {0, 7}, {0, 6}, {0, 5}, {0, 4}, {0, 3}, {0, 2}, {0, 1}, + {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0} + }, + .available_config_num = 31, +}; static mspi_ll_dqs_phase_t s_psram_best_phase = MSPI_LL_DQS_PHASE_MAX; static delayline_config_t s_psram_best_delayline = {WRONG_DELAYLINE, WRONG_DELAYLINE}; @@ -121,7 +123,9 @@ void mspi_timing_config_psram_set_tuning_phase(const void *configs, uint8_t id) { mspi_ll_dqs_phase_t phase = ((mspi_timing_config_t *)configs)->phase[id]; mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, phase); +#if MSPI_LL_PSRAM_DQS1_SUPPORTED mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, phase); +#endif ESP_DRAM_LOGD(TAG, "set to phase: %d", phase); } @@ -139,7 +143,7 @@ uint32_t mspi_timing_psram_select_best_tuning_phase(const void *configs, uint32_ } if (success) { - ESP_DRAM_LOGD(TAG, "tuning success, best phase id is %"PRIu32, best_phase_id); + ESP_DRAM_LOGI(TAG, "tuning success, best phase id is %"PRIu32, best_phase_id); } else { ESP_DRAM_LOGW(TAG, "tuning fail, best phase id is fallen back to index %"PRIu32"", best_phase_id); } @@ -162,14 +166,22 @@ void mspi_timing_config_psram_set_tuning_delayline(const void *configs, uint8_t { assert(s_psram_best_phase != MSPI_LL_DQS_PHASE_MAX); mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, s_psram_best_phase); +#if MSPI_LL_PSRAM_DQS1_SUPPORTED mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, s_psram_best_phase); +#endif ESP_DRAM_LOGD(TAG, "set to best phase: %d", s_psram_best_phase); const delayline_config_t *delayline_config = &((mspi_timing_config_t *)configs)->delayline_table[id]; for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { - if (i == MSPI_LL_PIN_DQS0 || i == MSPI_LL_PIN_DQS1) { + if (i == MSPI_LL_PIN_DQS0) { mspi_timing_ll_set_delayline(i, delayline_config->dqs_delayline); - } else { + } +#if MSPI_LL_PSRAM_DQS1_SUPPORTED + else if (i == MSPI_LL_PIN_DQS1) { + mspi_timing_ll_set_delayline(i, delayline_config->dqs_delayline); + } +#endif + else { mspi_timing_ll_set_delayline(i, delayline_config->data_delayline); } } @@ -185,7 +197,7 @@ uint32_t mspi_timing_psram_select_best_tuning_delayline(const void *configs, uin ESP_DRAM_LOGW(TAG, "tuning fail, best delayline id is fallen back to index %"PRIu32"", bset_delayline_id); } else { bset_delayline_id = end - consecutive_length / 2; - ESP_DRAM_LOGD(TAG, "tuning success, best delayline id is %"PRIu32, bset_delayline_id); + ESP_DRAM_LOGI(TAG, "tuning success, best delayline id is %"PRIu32, bset_delayline_id); } return bset_delayline_id; @@ -199,8 +211,9 @@ void mspi_timing_psram_set_best_tuning_delayline(const void *configs, uint8_t be void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi) { mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, 0); +#if MSPI_LL_PSRAM_DQS1_SUPPORTED mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, 0); - +#endif for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { mspi_timing_ll_set_delayline(i, 0); } @@ -209,13 +222,31 @@ void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi) void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi) { mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, s_psram_best_phase); +#if MSPI_LL_PSRAM_DQS1_SUPPORTED mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, s_psram_best_phase); +#endif for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { - if (i == MSPI_LL_PIN_DQS0 || i == MSPI_LL_PIN_DQS1) { + if (i == MSPI_LL_PIN_DQS0) { mspi_timing_ll_set_delayline(i, s_psram_best_delayline.dqs_delayline); - } else { + } +#if MSPI_LL_PSRAM_DQS1_SUPPORTED + else if (i == MSPI_LL_PIN_DQS1) { + mspi_timing_ll_set_delayline(i, s_psram_best_delayline.dqs_delayline); + } +#endif + else { mspi_timing_ll_set_delayline(i, s_psram_best_delayline.data_delayline); } } } + +void mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi) +{ + //for compatibility +} + +void mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi) +{ + //for compatibility +} diff --git a/components/esp_hw_support/port/esp32s31/cpu_region_protect.c b/components/esp_hw_support/port/esp32s31/cpu_region_protect.c index cd0c02ce1a..a0cabf296f 100644 --- a/components/esp_hw_support/port/esp32s31/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32s31/cpu_region_protect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,4 +40,11 @@ void esp_cpu_configure_region_protection(void) { /* TODO: [ESP32S31] IDF-15238 */ + + __attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W; + __attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X; + __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; + + //without setting this, psram cannot be reached + PMA_RESET_AND_ENTRY_SET_NAPOT(7, SOC_EXTRAM_LOW, (SOC_EXTRAM_HIGH - SOC_EXTRAM_LOW), PMA_NAPOT | PMA_RWX); } diff --git a/components/esp_hw_support/port/esp32s31/rtc_clk.c b/components/esp_hw_support/port/esp32s31/rtc_clk.c index 65ca09584b..5d9e39e9d3 100644 --- a/components/esp_hw_support/port/esp32s31/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s31/rtc_clk.c @@ -32,7 +32,7 @@ static const char *TAG = "rtc_clk"; static int s_cur_cpll_freq = 0; // MPLL frequency option, 400MHz. Zero if MPLL is not enabled. -static SPM_DRAM_ATTR uint32_t s_cur_mpll_freq = 0; +static uint32_t s_cur_mpll_freq = 0; void rtc_clk_32k_enable(bool enable) { @@ -204,7 +204,7 @@ void rtc_clk_cpu_freq_set_xtal_for_sleep(void) soc_xtal_freq_t rtc_clk_xtal_freq_get(void) { - uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); + uint32_t xtal_freq_mhz = clk_ll_xtal_get_freq_mhz(); if (xtal_freq_mhz == 0) { ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); return SOC_XTAL_FREQ_40M; @@ -214,7 +214,7 @@ soc_xtal_freq_t rtc_clk_xtal_freq_get(void) void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq) { - clk_ll_xtal_store_freq_mhz(xtal_freq); + // clk_ll_xtal_store_freq_mhz(xtal_freq); } uint32_t rtc_clk_apb_freq_get(void) @@ -331,7 +331,26 @@ IRAM_ATTR void rtc_clk_mpll_enable(void) void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq, bool thread_safe) { - // TODO: ["ESP32S31"] IDF-14678 + /* Analog part */ + if (thread_safe) { + _regi2c_ctrl_ll_master_enable_clock(true); + } else { + ANALOG_CLOCK_ENABLE(); + } + /* MPLL calibration start */ + clk_ll_mpll_calibration_start(); + clk_ll_mpll_set_config(mpll_freq, xtal_freq); + /* wait calibration done */ + while(!clk_ll_mpll_calibration_is_done()); + /* MPLL calibration stop */ + clk_ll_mpll_calibration_stop(); + + if (thread_safe) { + _regi2c_ctrl_ll_master_enable_clock(false); + } else { + ANALOG_CLOCK_DISABLE(); + } + s_cur_mpll_freq = mpll_freq; } IRAM_ATTR uint32_t rtc_clk_mpll_get_freq(void) diff --git a/components/esp_hw_support/port/esp32s31/rtc_time.c b/components/esp_hw_support/port/esp32s31/rtc_time.c index 76b42b0433..76331a7b18 100644 --- a/components/esp_hw_support/port/esp32s31/rtc_time.c +++ b/components/esp_hw_support/port/esp32s31/rtc_time.c @@ -213,7 +213,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) uint64_t rtc_time_get(void) { - return 0;// TODO: ["ESP32S31"] IDF-14678 + return rtc_timer_hal_get_cycle_count(0); } uint32_t rtc_clk_freq_cal(uint32_t cal_val) diff --git a/components/esp_psram/CMakeLists.txt b/components/esp_psram/CMakeLists.txt index 5d1ee8437b..ac6f66c2f3 100644 --- a/components/esp_psram/CMakeLists.txt +++ b/components/esp_psram/CMakeLists.txt @@ -31,7 +31,9 @@ if(CONFIG_SPIRAM) endif() elseif(CONFIG_SPIRAM_MODE_OCT) - list(APPEND srcs "${target}/esp_psram_impl_octal.c") + if(${target} STREQUAL "esp32s3") + list(APPEND srcs "${target}/esp_psram_impl_octal.c") + endif() endif() endif() diff --git a/components/esp_psram/device/CMakeLists.txt b/components/esp_psram/device/CMakeLists.txt index 94febebb08..9c0b138267 100644 --- a/components/esp_psram/device/CMakeLists.txt +++ b/components/esp_psram/device/CMakeLists.txt @@ -6,6 +6,12 @@ if(CONFIG_SPIRAM_MODE_QUAD) endif() endif() +if(CONFIG_SPIRAM_MODE_OCT) + if(NOT ${target} STREQUAL "esp32s3") + list(APPEND srcs "esp_psram_impl_ap_oct.c") + endif() +endif() + if(CONFIG_SPIRAM_MODE_HEX) list(APPEND srcs "esp_psram_impl_ap_hex.c") endif() diff --git a/components/esp_psram/device/esp_psram_impl_ap_oct.c b/components/esp_psram/device/esp_psram_impl_ap_oct.c new file mode 100644 index 0000000000..0c8ef0b4e2 --- /dev/null +++ b/components/esp_psram/device/esp_psram_impl_ap_oct.c @@ -0,0 +1,585 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/mspi_timing_tuning.h" +#include "esp_private/esp_psram_impl.h" +#include "hal/psram_ctrlr_ll.h" +#include "hal/mspi_ll.h" +#include "clk_ctrl_os.h" +#include "soc/rtc.h" + +#define AP_OCT_PSRAM_SYNC_READ 0x0000 +#define AP_OCT_PSRAM_SYNC_WRITE 0x8080 +#define AP_OCT_PSRAM_BURST_READ 0x2020 +#define AP_OCT_PSRAM_BURST_WRITE 0xA0A0 +#define AP_OCT_PSRAM_REG_READ 0x4040 +#define AP_OCT_PSRAM_REG_WRITE 0xC0C0 +#define AP_OCT_PSRAM_RD_CMD_BITLEN 16 +#define AP_OCT_PSRAM_WR_CMD_BITLEN 16 +#define AP_OCT_PSRAM_ADDR_BITLEN 32 + +#if CONFIG_SPIRAM_SPEED_250M +#define AP_OCT_PSRAM_RD_DUMMY_BITLEN (2*(18-1)) +#define AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN (2*(9-1)) +#define AP_OCT_PSRAM_WR_DUMMY_BITLEN (2*(9-1)) +#define AP_OCT_PSRAM_RD_LATENCY 6 +#define AP_OCT_PSRAM_WR_LATENCY 3 +#elif CONFIG_SPIRAM_SPEED_200M +#define AP_OCT_PSRAM_RD_DUMMY_BITLEN (2*(14-1)) +#define AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN (2*(7-1)) +#define AP_OCT_PSRAM_WR_DUMMY_BITLEN (2*(7-1)) +#define AP_OCT_PSRAM_RD_LATENCY 4 +#define AP_OCT_PSRAM_WR_LATENCY 1 +#else +#define AP_OCT_PSRAM_RD_DUMMY_BITLEN (2*(10-1)) +#define AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN (2*(5-1)) +#define AP_OCT_PSRAM_WR_DUMMY_BITLEN (2*(5-1)) +#define AP_OCT_PSRAM_RD_LATENCY 2 +#define AP_OCT_PSRAM_WR_LATENCY 2 +#endif + +#define AP_OCT_PSRAM_VENDOR_ID_AP 0xD +#define AP_OCT_PSRAM_VENDOR_ID_UNILC 0x1A //UnilC shares driver pattern with AP +#define AP_OCT_PSRAM_CS_SETUP_TIME 4 +#define AP_OCT_PSRAM_CS_HOLD_TIME 4 +#define AP_OCT_PSRAM_CS_ECC_HOLD_TIME 4 +#define AP_OCT_PSRAM_CS_HOLD_DELAY 3 + +#if CONFIG_SPIRAM_SPEED_80M +#define AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ 320 +#elif CONFIG_SPIRAM_SPEED_250M +#define AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ 500 +#else +#define AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ 400 +#endif + +#define AP_OCT_PSRAM_REF_DATA 0x5a6b7c8d + +#define AP_OCT_PSRAM_ULP_MODE_HALFSLEEP 0xF0 + +typedef struct { + union { + struct { + uint8_t drive_str: 2; + uint8_t read_latency: 3; + uint8_t lt: 1; + uint8_t rsvd6: 1; + uint8_t tso: 1; + }; + uint8_t val; + } mr0; + union { + struct { + uint8_t vendor_id: 5; + uint8_t rsvd5_7: 3; + uint8_t ulp: 1; + }; + uint8_t val; + } mr1; + union { + struct { + uint8_t density: 3; + uint8_t dev_id: 2; + uint8_t kgd: 3; + }; + uint8_t val; + } mr2; + union { + struct { + uint8_t rsvd0_3: 4; + uint8_t srf: 2; + uint8_t rsvd6: 1; + uint8_t rbx_en: 1; + }; + uint8_t val; + } mr3; + union { + struct { + uint8_t pasr: 3; + uint8_t rf: 2; + uint8_t wr_latency: 3; + }; + uint8_t val; + } mr4; + union { + struct { + uint8_t rsvd0_3: 4; + uint8_t halfsleep: 4; + }; + uint8_t val; + } mr6; + union { + struct { + uint8_t bl: 2; + uint8_t bt: 1; + uint8_t rbx: 1; + uint8_t rsvd5: 2; + uint8_t x16: 1; + uint8_t rsvd7: 1; + }; + uint8_t val; + } mr8; +} oct_psram_mode_reg_t; + +static const char* TAG = "oct_psram"; +static uint32_t s_psram_size; //this stands for physical psram size in bytes + +/** + * Common psram transaction + */ +static void s_psram_common_transaction(uint32_t mspi_id, + uint32_t cmd, uint32_t cmd_bitlen, + uint32_t addr, uint32_t addr_bitlen, + uint32_t dummy_bits, + uint8_t* mosi_data, uint32_t mosi_bitlen, + uint8_t* miso_data, uint32_t miso_bitlen, + bool is_write_erase_operation) +{ + psram_ctrlr_ll_common_transaction(mspi_id, cmd, cmd_bitlen, addr, addr_bitlen, dummy_bits, + mosi_data, mosi_bitlen, miso_data, miso_bitlen, + is_write_erase_operation); +} + +/** + * Initialise mode registers of the PSRAM + */ +static void s_init_psram_mode_reg(int spi_num, oct_psram_mode_reg_t *mode_reg_config) +{ + int cmd_len = 16; + uint32_t addr = 0x0; + int addr_bit_len = 32; + int dummy = AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN; + oct_psram_mode_reg_t mode_reg = {0}; + int data_bit_len = 16; + + //read MR0 and MR1 + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + addr, addr_bit_len, + dummy, + NULL, 0, + &mode_reg.mr0.val, data_bit_len, + false); + + addr = 0x4; + //read MR4 and MR8 + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + addr, addr_bit_len, + dummy, + NULL, 0, + &mode_reg.mr4.val, data_bit_len, + false); + + //modify + mode_reg.mr0.lt = mode_reg_config->mr0.lt; + mode_reg.mr0.read_latency = mode_reg_config->mr0.read_latency; + mode_reg.mr0.drive_str = mode_reg_config->mr0.drive_str; + mode_reg.mr4.wr_latency = mode_reg_config->mr4.wr_latency; + + //write + addr = 0x0; + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_WRITE, cmd_len, + addr, addr_bit_len, + 0, + &mode_reg.mr0.val, 16, + NULL, 0, + false); + + addr = 0x4; + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_WRITE, cmd_len, + addr, addr_bit_len, + 0, + &mode_reg.mr4.val, 16, + NULL, 0, + false); + + //read + addr = 0x8; + data_bit_len = 8; + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + addr, addr_bit_len, + dummy, + NULL, 0, + &mode_reg.mr8.val, data_bit_len, + false); + + //modify + mode_reg.mr8.bt = mode_reg_config->mr8.bt; + mode_reg.mr8.bl = mode_reg_config->mr8.bl; + mode_reg.mr8.rbx = mode_reg_config->mr8.rbx; + mode_reg.mr8.x16 = mode_reg_config->mr8.x16; + + //write + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_WRITE, cmd_len, + addr, addr_bit_len, + 0, + &mode_reg.mr8.val, 16, + NULL, 0, + false); +} + +static void s_get_psram_mode_reg(int spi_num, oct_psram_mode_reg_t *out_reg) +{ + int cmd_len = 16; + int addr_bit_len = 32; + int dummy = AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN; + int data_bit_len = 16; + + //Read MR0~1 register + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + 0x0, addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr0.val, data_bit_len, + false); + //Read MR2~3 register + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + 0x2, addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr2.val, data_bit_len, + false); + data_bit_len = 8; + //Read MR4 register + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + 0x4, addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr4.val, data_bit_len, + false); + //Read MR8 register + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_REG_READ, cmd_len, + 0x8, addr_bit_len, + dummy, + NULL, 0, + &out_reg->mr8.val, data_bit_len, + false); +} + +/** + * Check if PSRAM is connected by write and read + */ +static esp_err_t s_check_psram_connected(int spi_num) +{ + uint32_t addr = 0x80; + uint32_t ref_data = AP_OCT_PSRAM_REF_DATA; + uint32_t exp_data = 0; + int data_bit_len = 32; + + //write + addr = 0x0; + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_SYNC_WRITE, AP_OCT_PSRAM_WR_CMD_BITLEN, + addr, AP_OCT_PSRAM_ADDR_BITLEN, + AP_OCT_PSRAM_WR_DUMMY_BITLEN, + (uint8_t *)&ref_data, data_bit_len, + NULL, 0, + false); + + //read MR4 and MR8 + s_psram_common_transaction(spi_num, + AP_OCT_PSRAM_SYNC_READ, AP_OCT_PSRAM_RD_CMD_BITLEN, + addr, AP_OCT_PSRAM_ADDR_BITLEN, + AP_OCT_PSRAM_RD_DUMMY_BITLEN, + NULL, 0, + (uint8_t *)&exp_data, data_bit_len, + false); + + ESP_EARLY_LOGD(TAG, "exp_data: 0x%08x", exp_data); + ESP_EARLY_LOGD(TAG, "ref_data: 0x%08x", ref_data); + + return (exp_data == ref_data ? ESP_OK : ESP_FAIL); +} + +static void s_print_psram_info(oct_psram_mode_reg_t *reg_val) +{ + ESP_EARLY_LOGI(TAG, "vendor id : 0x%02x (%s)", reg_val->mr1.vendor_id, reg_val->mr1.vendor_id == 0x0d ? "AP" : "UNKNOWN"); + ESP_EARLY_LOGI(TAG, "Latency : 0x%02x (%s)", reg_val->mr0.lt, reg_val->mr0.lt == 1 ? "Fixed" : "Variable"); + ESP_EARLY_LOGI(TAG, "DriveStr. : 0x%02x (%d Ohm)", reg_val->mr0.drive_str, reg_val->mr0.drive_str < 2 ? 25 * (reg_val->mr0.drive_str + 1) : 100 * (reg_val->mr0.drive_str - 1)); + ESP_EARLY_LOGI(TAG, "dev id : 0x%02x (generation %d)", reg_val->mr2.dev_id, reg_val->mr2.dev_id + 1); + ESP_EARLY_LOGI(TAG, "density : 0x%02x (%d Mbit)", reg_val->mr2.density, reg_val->mr2.density == 0x1 ? 32 : + reg_val->mr2.density == 0X3 ? 64 : + reg_val->mr2.density == 0x5 ? 128 : + reg_val->mr2.density == 0x7 ? 256 : 0); + ESP_EARLY_LOGI(TAG, "good-die : 0x%02x (%s)", reg_val->mr2.kgd, reg_val->mr2.kgd == 6 ? "Pass" : "Fail"); + ESP_EARLY_LOGI(TAG, "SRF : 0x%02x (%s Refresh)", reg_val->mr3.srf, reg_val->mr3.srf == 0x1 ? "Fast" : "Slow"); + ESP_EARLY_LOGI(TAG, "BurstType : 0x%02x (%s Wrap)", reg_val->mr8.bt, reg_val->mr8.bt == 1 && reg_val->mr8.bl != 3 ? "Hybrid" : ""); + ESP_EARLY_LOGI(TAG, "BurstLen : 0x%02x (%d Byte)", reg_val->mr8.bl, reg_val->mr8.bl == 0x00 ? 16 : + reg_val->mr8.bl == 0x01 ? 32 : + reg_val->mr8.bl == 0x10 ? 64 : 2048); + ESP_EARLY_LOGI(TAG, "BitMode : 0x%02x (%s Mode)", reg_val->mr8.x16, reg_val->mr8.x16 == 1 ? "X16" : "X8"); + + ESP_EARLY_LOGI(TAG, "Readlatency : 0x%02x (%d cycles@%s)", reg_val->mr0.read_latency, reg_val->mr0.read_latency * 2 + 6, + reg_val->mr0.lt == 1 ? "Fixed" : "Variable"); + ESP_EARLY_LOGI(TAG, "DriveStrength: 0x%02x (1/%d)", reg_val->mr0.drive_str, reg_val->mr0.drive_str == 0x00 ? 1 : + reg_val->mr0.drive_str == 0x01 ? 2 : + reg_val->mr0.drive_str == 0x02 ? 4 : 8); +} + +static void s_config_mspi_for_psram(void) +{ + //Config Write CMD phase for SPI0 to access PSRAM + psram_ctrlr_ll_set_wr_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_WR_CMD_BITLEN, AP_OCT_PSRAM_SYNC_WRITE); + + //Config Read CMD phase for SPI0 to access PSRAM + psram_ctrlr_ll_set_rd_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_RD_CMD_BITLEN, AP_OCT_PSRAM_SYNC_READ); + + //Config ADDR phase + psram_ctrlr_ll_set_addr_bitlen(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_ADDR_BITLEN); + psram_ctrlr_ll_enable_4byte_addr(PSRAM_CTRLR_LL_MSPI_ID_2, true); + + //Config RD/WR Dummy phase + psram_ctrlr_ll_set_wr_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_WR_DUMMY_BITLEN); + psram_ctrlr_ll_set_rd_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_RD_DUMMY_BITLEN); + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_wr_dummy_level_control(PSRAM_CTRLR_LL_MSPI_ID_2, true); + + //DDR + psram_ctrlr_ll_enable_ddr_wr_data_swap(PSRAM_CTRLR_LL_MSPI_ID_2, false); + psram_ctrlr_ll_enable_ddr_rd_data_swap(PSRAM_CTRLR_LL_MSPI_ID_2, false); + psram_ctrlr_ll_enable_ddr_mode(PSRAM_CTRLR_LL_MSPI_ID_2, true); + + //8-line mode + psram_ctrlr_ll_enable_oct_line_mode(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_hex_data_line_mode(PSRAM_CTRLR_LL_MSPI_ID_2, false); + + //AXI + psram_ctrlr_ll_enable_axi_access(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_wr_splice(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_rd_splice(PSRAM_CTRLR_LL_MSPI_ID_2, true); +} + +static void s_set_psram_cs_timing(void) +{ + psram_ctrlr_ll_set_cs_setup(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_CS_SETUP_TIME); + psram_ctrlr_ll_set_cs_hold(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_CS_HOLD_TIME); + psram_ctrlr_ll_set_cs_hold_delay(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_CS_HOLD_DELAY); +#if CONFIG_SPIRAM_ECC_ENABLE + psram_ctrlr_ll_set_cs_hold_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_CS_ECC_HOLD_TIME); +#endif +} + +#if CONFIG_SPIRAM_ECC_ENABLE +static void s_mspi_ecc_show_info(void) +{ + for (int i = 0; i < PSRAM_CTRLR_LL_PMS_REGION_NUMS; i++) { + ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, psram_ctrlr_ll_get_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_2, i)); + ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, psram_ctrlr_ll_get_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_2, i)); + } + + uint32_t page_size = psram_ctrlr_ll_get_page_size(PSRAM_CTRLR_LL_MSPI_ID_2); + ESP_EARLY_LOGV(TAG, "ECC page size: %d", page_size); +} + +/** + * Enable error correcting code feature + * + * Can add an input parameter for selecting ECC mode if needed + */ +static void s_configure_psram_ecc(void) +{ + psram_ctrlr_ll_enable_16to18_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_skip_page_corner(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_ecc_addr_conversion(PSRAM_CTRLR_LL_MSPI_ID_2, 2048); + + /** + * Enable ECC region 0 (ACE0) + * Default: ACE0 range: 0 ~ 256MB + * Current PSRAM is 8MB, ACE0 is enough + */ + psram_ctrlr_ll_enable_pms_region_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, 0, true); + + ESP_EARLY_LOGI(TAG, "ECC is enabled"); + s_mspi_ecc_show_info(); +} +#endif //#if CONFIG_SPIRAM_ECC_ENABLE + +esp_err_t esp_psram_impl_enable(void) +{ +#if SOC_CLK_MPLL_SUPPORTED + periph_rtc_mpll_acquire(); + uint32_t real_mpll_freq = 0; + periph_rtc_mpll_freq_set(AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ * 1000000, &real_mpll_freq); + ESP_EARLY_LOGD(TAG, "real_mpll_freq: %d", real_mpll_freq); +#endif + + PERIPH_RCC_ATOMIC() { + psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_reset_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2); + psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL); + psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL); + } + + mspi_timing_ll_pin_drv_set(2); + mspi_timing_ll_enable_dqs(true); + + s_set_psram_cs_timing(); + psram_ctrlr_ll_enable_split_trans(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_set_page_size(PSRAM_CTRLR_LL_MSPI_ID_2, 2048); +#if CONFIG_SPIRAM_ECC_ENABLE + s_configure_psram_ecc(); +#endif + //enter MSPI slow mode to init PSRAM device registers + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ / CONFIG_SPIRAM_SPEED); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, AP_OCT_PSRAM_MPLL_DEFAULT_FREQ_MHZ / CONFIG_SPIRAM_SPEED); + psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true); + + static oct_psram_mode_reg_t mode_reg = {}; + mode_reg.mr0.lt = 1; + mode_reg.mr0.read_latency = AP_OCT_PSRAM_RD_LATENCY; + mode_reg.mr0.drive_str = 0; + mode_reg.mr4.wr_latency = AP_OCT_PSRAM_WR_LATENCY; + mode_reg.mr8.bl = 3; + mode_reg.mr8.bt = 0; + mode_reg.mr8.rbx = 1; + mode_reg.mr8.x16 = 0; + + s_init_psram_mode_reg(PSRAM_CTRLR_LL_MSPI_ID_3, &mode_reg); + + if (s_check_psram_connected(PSRAM_CTRLR_LL_MSPI_ID_3) != ESP_OK) { + ESP_EARLY_LOGE(TAG, "PSRAM chip is not connected"); + return ESP_ERR_NOT_SUPPORTED; + } + + s_get_psram_mode_reg(PSRAM_CTRLR_LL_MSPI_ID_3, &mode_reg); + if (mode_reg.mr1.vendor_id != AP_OCT_PSRAM_VENDOR_ID_AP && mode_reg.mr1.vendor_id != AP_OCT_PSRAM_VENDOR_ID_UNILC) { + ESP_EARLY_LOGW(TAG, "PSRAM ID read error: 0x%08x, fallback to use default driver pattern", mode_reg.mr1.vendor_id); + } + + s_print_psram_info(&mode_reg); + s_psram_size = mode_reg.mr2.density == 0x1 ? PSRAM_SIZE_4MB : + mode_reg.mr2.density == 0X3 ? PSRAM_SIZE_8MB : + mode_reg.mr2.density == 0x5 ? PSRAM_SIZE_16MB : + mode_reg.mr2.density == 0x7 ? PSRAM_SIZE_32MB : + mode_reg.mr2.density == 0x6 ? PSRAM_SIZE_64MB : 0; + + s_config_mspi_for_psram(); + mspi_timing_psram_tuning(); + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_3, true); + + return ESP_OK; +} + +uint8_t esp_psram_impl_get_cs_io(void) +{ + ESP_EARLY_LOGI(TAG, "psram CS IO is dedicated"); + return -1; +} + +esp_err_t esp_psram_impl_get_physical_size(uint32_t *out_size_bytes) +{ + if (!out_size_bytes) { + return ESP_ERR_INVALID_ARG; + } + + *out_size_bytes = s_psram_size; + return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE); +} + +/** + * This function is to get the available physical psram size in bytes. + * If ECC is enabled, available PSRAM size will be 7/8 times its physical size. + */ +esp_err_t esp_psram_impl_get_available_size(uint32_t *out_size_bytes) +{ + if (!out_size_bytes) { + return ESP_ERR_INVALID_ARG; + } + +#if CONFIG_SPIRAM_ECC_ENABLE + *out_size_bytes = s_psram_size * 7 / 8; +#else + *out_size_bytes = s_psram_size; +#endif + return (s_psram_size ? ESP_OK : ESP_ERR_INVALID_STATE); +} + +/******************************* Halfsleep Mode *******************************/ +static struct { + uint8_t mr4; + uint64_t halfsleep_wakeup_tick; +} s_halfsleep_ctx = {0}; + +void esp_psram_impl_enter_halfsleep_mode(void) +{ + // Backup MR4 + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_OCT_PSRAM_REG_READ, AP_OCT_PSRAM_RD_CMD_BITLEN, + 0x4, AP_OCT_PSRAM_ADDR_BITLEN, + AP_OCT_PSRAM_RD_REG_DUMMY_BITLEN, + NULL, 0, + &s_halfsleep_ctx.mr4, 16, + false); + // Set refresh rate to 0.5x + oct_psram_mode_reg_t mode_reg; + mode_reg.mr4.val = s_halfsleep_ctx.mr4; + mode_reg.mr4.rf = 3; // (0:4x 1:1x 3:0.5x) + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_OCT_PSRAM_REG_WRITE, AP_OCT_PSRAM_RD_CMD_BITLEN, + 0x4, AP_OCT_PSRAM_ADDR_BITLEN, + 0, + &mode_reg.mr4.val, 16, + NULL, 0, + false); + // Set halfsleep mode + uint8_t halfsleep_cmd = AP_OCT_PSRAM_ULP_MODE_HALFSLEEP; + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_OCT_PSRAM_REG_WRITE, AP_OCT_PSRAM_RD_CMD_BITLEN, + 0x6, AP_OCT_PSRAM_ADDR_BITLEN, + 0, + &halfsleep_cmd, 16, + NULL, 0, + false); +} + +void esp_psram_impl_exit_halfsleep_mode(void) +{ + // Record the tick exiting halfsleep mode + s_halfsleep_ctx.halfsleep_wakeup_tick = rtc_time_get(); + + // Do a SPI dummy write transmission to invalid address to wake up from halfsleep mode + uint8_t null = 0; + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_OCT_PSRAM_REG_WRITE, AP_OCT_PSRAM_WR_CMD_BITLEN, + 0xFF, AP_OCT_PSRAM_ADDR_BITLEN, + 0, + &null, 0, + NULL, 0, + false); +} + +void esp_psram_impl_resume_from_halfsleep_mode(uint32_t slowclk_period) +{ + uint64_t halfsleep_exit_tick = s_halfsleep_ctx.halfsleep_wakeup_tick + rtc_time_us_to_slowclk(CONFIG_PM_SLP_SPIRAM_HALFSLEEP_EXIT_WAIT_DELAY, slowclk_period); + while (rtc_time_get() < halfsleep_exit_tick) { + // Busy wait for PSRAM to exit halfsleep mode + } + + // Restore MR4 configuration (restore refresh rate) + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_OCT_PSRAM_REG_WRITE, AP_OCT_PSRAM_WR_CMD_BITLEN, + 0x4, AP_OCT_PSRAM_ADDR_BITLEN, + 0, + &s_halfsleep_ctx.mr4, 16, + NULL, 0, + false); +} diff --git a/components/esp_psram/esp32s31/Kconfig.spiram b/components/esp_psram/esp32s31/Kconfig.spiram new file mode 100644 index 0000000000..97acbcb457 --- /dev/null +++ b/components/esp_psram/esp32s31/Kconfig.spiram @@ -0,0 +1,96 @@ +config SPIRAM + bool "Support for external PSRAM" + default "n" + help + This enables support for an external PSRAM chip, connected in parallel with the + main SPI flash chip. + +menu "PSRAM config" + depends on SPIRAM + + choice SPIRAM_MODE + prompt "Line Mode of PSRAM chip in use" + default SPIRAM_MODE_OCT + + config SPIRAM_MODE_OCT + bool "8-Line-Mode PSRAM" + endchoice + + choice SPIRAM_SPEED + prompt "Set PSRAM clock speed" + default SPIRAM_SPEED_200M + help + Select the speed for the PSRAM chip. + + config SPIRAM_SPEED_250M + bool "250MHz clock speed" + + config SPIRAM_SPEED_200M + bool "200MHz clock speed" + + config SPIRAM_SPEED_80M + bool "80MHz clock speed" + + config SPIRAM_SPEED_40M + bool "40MHz clock speed" + endchoice + + config SPIRAM_SPEED + int + default 40 if SPIRAM_SPEED_40M + default 80 if SPIRAM_SPEED_80M + default 100 if SPIRAM_SPEED_100M + default 200 if SPIRAM_SPEED_200M + default 250 if SPIRAM_SPEED_250M + + config SPIRAM_FETCH_INSTRUCTIONS + bool + help + Enable this option allows moving application's instruction segment from the SPI Flash to + PSRAM + + config SPIRAM_RODATA + bool + help + Enable this option allows moving application's rodata segment from the SPI Flash to + PSRAM + + config SPIRAM_XIP_FROM_PSRAM + bool "Enable Executable in place from (XiP) from PSRAM feature (READ HELP)" + default n + depends on SPIRAM_BOOT_INIT + select SPIRAM_FETCH_INSTRUCTIONS + select SPIRAM_RODATA + select SPIRAM_FLASH_LOAD_TO_PSRAM + help + If enabled, firmware in flash including instructions and data will be moved into PSRAM on startup, + firmware code will execute directly from PSRAM. + + With this option enabled, code that requires execution during an MSPI1 Flash operation + does not have to be placed in IRAM. Therefore codes that need to be executing during Flash + operations can continue working normally. + + Because P4 flash and PSRAM are using two separate SPI buses, moving flash content to PSRAM will + actually increase the load of the PSRAM MSPI bus, so the exact impact on performance will be dependent + on your app usage of PSRAM. For example, as the PSRAM bus speed could be much faster than flash bus speed, + if the instructions and data that are used to be in flash are not accessed very frequently, you might + get better performance with this option enabled. We suggest doing performance profiling to determine + if enabling this option. + + config SPIRAM_FLASH_LOAD_TO_PSRAM + bool + help + This is a helper indicating this condition: + `CONFIG_SPIRAM_XIP_FROM_PSRAM && CONFIG_IDF_TARGET_ESP32S31` + + config SPIRAM_ECC_ENABLE + bool "Enable PSRAM ECC" + default n + help + Enable Error-Correcting Code function when accessing PSRAM. + + If enabled, 1/8 of the PSRAM total size will be reserved for error-correcting code. + + source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here + +endmenu diff --git a/components/esp_psram/linker.lf b/components/esp_psram/linker.lf index 65f737830e..c5473cff39 100644 --- a/components/esp_psram/linker.lf +++ b/components/esp_psram/linker.lf @@ -17,8 +17,10 @@ entries: if SPIRAM_MODE_HEX = y: esp_psram_impl_ap_hex (noflash) + if SPIRAM_MODE_OCT = y: + esp_psram_impl_ap_oct (noflash) + if SPIRAM_FLASH_LOAD_TO_PSRAM = y: - esp_psram_impl_ap_hex (noflash) mmu_psram_flash_v2 (noflash) esp_psram: esp_psram_chip_init (noflash) esp_psram: esp_psram_init (noflash) diff --git a/components/esp_psram/test_apps/psram/README.md b/components/esp_psram/test_apps/psram/README.md index cd0b24f6cb..487dd594b8 100644 --- a/components/esp_psram/test_apps/psram/README.md +++ b/components/esp_psram/test_apps/psram/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | ----- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | This test app is used to test PSRAM diff --git a/components/esp_psram/test_apps/psram/main/test_psram.c b/components/esp_psram/test_apps/psram/main/test_psram.c index 7dc2e59755..da91ced5a9 100644 --- a/components/esp_psram/test_apps/psram/main/test_psram.c +++ b/components/esp_psram/test_apps/psram/main/test_psram.c @@ -65,9 +65,9 @@ TEST_CASE("test psram halfsleep mode (if applicable)", "[psram]") { uint32_t rtc_slow_clk_period = rtc_clk_cal(CLK_CAL_RTC_SLOW, CONFIG_RTC_CLK_CAL_CYCLES); s_test_psram_heap_allocable(); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 3; i++) { esp_psram_impl_enter_halfsleep_mode(); - vTaskDelay(pdMS_TO_TICKS(1000)); + esp_rom_delay_us(1000); esp_psram_impl_exit_halfsleep_mode(); esp_psram_impl_resume_from_halfsleep_mode(rtc_slow_clk_period); s_test_psram_heap_allocable(); diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h b/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h new file mode 100644 index 0000000000..5ae5c4ae58 --- /dev/null +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/opi_flash.h @@ -0,0 +1,325 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #ifndef _ROM_OPI_FLASH_H_ + #define _ROM_OPI_FLASH_H_ + #include + #include + #include + #include + #include "spi_flash.h" + + #ifdef __cplusplus + extern "C" { + #endif + + + + typedef struct { + uint8_t mode; + uint8_t cmd_bit_len; + uint16_t cmd; + uint32_t addr; + uint8_t addr_bit_len; + uint8_t dummy_bit_len; + uint8_t data_bit_len; + uint8_t cs_sel: 4; + uint8_t is_pe: 4; + } esp_rom_opiflash_cmd_t; + + typedef struct { + uint8_t addr_bit_len; + uint8_t dummy_bit_len; + uint16_t cmd; + uint8_t cmd_bit_len; + uint8_t var_dummy_en; + } esp_rom_opiflash_spi0rd_t; + + typedef struct { + esp_rom_opiflash_cmd_t rdid; + esp_rom_opiflash_cmd_t rdsr; + esp_rom_opiflash_cmd_t wren; + esp_rom_opiflash_cmd_t se; + esp_rom_opiflash_cmd_t be64k; + esp_rom_opiflash_cmd_t read; + esp_rom_opiflash_cmd_t pp; + esp_rom_opiflash_spi0rd_t cache_rd_cmd; + bool usr_ecc_en; + } esp_rom_opiflash_def_t; + + typedef struct { + uint16_t cmd; /*!< Command value */ + uint16_t cmdBitLen; /*!< Command byte length*/ + uint32_t *addr; /*!< Point to address value*/ + uint32_t addrBitLen; /*!< Address byte length*/ + uint32_t *txData; /*!< Point to send data buffer*/ + uint32_t txDataBitLen; /*!< Send data byte length.*/ + uint32_t *rxData; /*!< Point to receive data buffer*/ + uint32_t rxDataBitLen; /*!< Receive Data byte length.*/ + uint32_t dummyBitLen; + } esp_rom_spi_cmd_t; + + #define ESP_ROM_OPIFLASH_MUX_TAKE() + #define ESP_ROM_OPIFLASH_MUX_GIVE() + #define ESP_ROM_OPIFLASH_SEL_CS0 (BIT(0)) + #define ESP_ROM_OPIFLASH_SEL_CS1 (BIT(1)) + + // Definition of MX25UM25645G Octa Flash + // SPI status register + #define ESP_ROM_SPIFLASH_BUSY_FLAG BIT0 + #define ESP_ROM_SPIFLASH_WRENABLE_FLAG BIT1 + #define ESP_ROM_SPIFLASH_BP0 BIT2 + #define ESP_ROM_SPIFLASH_BP1 BIT3 + #define ESP_ROM_SPIFLASH_BP2 BIT4 + #define ESP_ROM_SPIFLASH_WR_PROTECT (ESP_ROM_SPIFLASH_BP0|ESP_ROM_SPIFLASH_BP1|ESP_ROM_SPIFLASH_BP2) + #define ESP_ROM_SPIFLASH_QE BIT9 + + #define FLASH_OP_MODE_RDCMD_DOUT 0x3B + #define ESP_ROM_FLASH_SECTOR_SIZE 0x1000 + #define ESP_ROM_FLASH_BLOCK_SIZE_64K 0x10000 + #define ESP_ROM_FLASH_PAGE_SIZE 256 + + // FLASH commands + #define ROM_FLASH_CMD_RDID 0x9F + #define ROM_FLASH_CMD_WRSR 0x01 + #define ROM_FLASH_CMD_WRSR2 0x31 /* Not all SPI flash uses this command */ + #define ROM_FLASH_CMD_WREN 0x06 + #define ROM_FLASH_CMD_WRDI 0x04 + #define ROM_FLASH_CMD_RDSR 0x05 + #define ROM_FLASH_CMD_RDSR2 0x35 /* Not all SPI flash uses this command */ + #define ROM_FLASH_CMD_ERASE_SEC 0x20 + #define ROM_FLASH_CMD_ERASE_BLK_32K 0x52 + #define ROM_FLASH_CMD_ERASE_BLK_64K 0xD8 + #define ROM_FLASH_CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */ + #define ROM_FLASH_CMD_RSTEN 0x66 + #define ROM_FLASH_CMD_RST 0x99 + + #define ROM_FLASH_CMD_SE4B 0x21 + #define ROM_FLASH_CMD_SE4B_OCT 0xDE21 + #define ROM_FLASH_CMD_BE4B 0xDC + #define ROM_FLASH_CMD_BE4B_OCT 0x23DC + #define ROM_FLASH_CMD_RSTEN_OCT 0x9966 + #define ROM_FLASH_CMD_RST_OCT 0x6699 + + #define ROM_FLASH_CMD_FSTRD4B_STR 0x13EC + #define ROM_FLASH_CMD_FSTRD4B_DTR 0x11EE + #define ROM_FLASH_CMD_FSTRD4B 0x0C + #define ROM_FLASH_CMD_PP4B 0x12 + #define ROM_FLASH_CMD_PP4B_OCT 0xED12 + + #define ROM_FLASH_CMD_RDID_OCT 0x609F + #define ROM_FLASH_CMD_WREN_OCT 0xF906 + #define ROM_FLASH_CMD_RDSR_OCT 0xFA05 + #define ROM_FLASH_CMD_RDCR2 0x71 + #define ROM_FLASH_CMD_RDCR2_OCT 0x8E71 + #define ROM_FLASH_CMD_WRCR2 0x72 + #define ROM_FLASH_CMD_WRCR2_OCT 0x8D72 + + // Definitions for GigaDevice GD25LX256E Flash + #define ROM_FLASH_CMD_RDFSR_GD 0x70 + #define ROM_FLASH_CMD_RD_GD 0x03 + #define ROM_FLASH_CMD_RD4B_GD 0x13 + #define ROM_FLASH_CMD_FSTRD_GD 0x0B + #define ROM_FLASH_CMD_FSTRD4B_GD 0x0C + #define ROM_FLASH_CMD_FSTRD_OOUT_GD 0x8B + #define ROM_FLASH_CMD_FSTRD4B_OOUT_GD 0x7C + #define ROM_FLASH_CMD_FSTRD_OIOSTR_GD 0xCB + #define ROM_FLASH_CMD_FSTRD4B_OIOSTR_GD 0xCC + #define ROM_FLASH_CMD_FSTRD4B_OIODTR_GD 0xFD + + #define ROM_FLASH_CMD_PP_GD 0x02 + #define ROM_FLASH_CMD_PP4B_GD 0x12 + #define ROM_FLASH_CMD_PP_OOUT_GD 0x82 + #define ROM_FLASH_CMD_PP4B_OOUT_GD 0x84 + #define ROM_FLASH_CMD_PP_OIO_GD 0xC2 + #define ROM_FLASH_CMD_PP4B_OIOSTR_GD 0x8E + + #define ROM_FLASH_CMD_SE_GD 0x20 + #define ROM_FLASH_CMD_SE4B_GD 0x21 + #define ROM_FLASH_CMD_BE32K_GD 0x52 + #define ROM_FLASH_CMD_BE32K4B_GD 0x5C + #define ROM_FLASH_CMD_BE64K_GD 0xD8 + #define ROM_FLASH_CMD_BE64K4B_GD 0xDC + + #define ROM_FLASH_CMD_EN4B_GD 0xB7 + #define ROM_FLASH_CMD_DIS4B_GD 0xE9 + + extern const esp_rom_opiflash_def_t *rom_opiflash_cmd_def; + + /** + * @brief init legacy driver for Octal Flash + */ + void esp_rom_opiflash_legacy_driver_init(const esp_rom_opiflash_def_t *flash_cmd_def); + + // spi user mode command config + /** + * @brief Config the spi user command + * @param spi_num spi port + * @param pcmd pointer to accept the spi command struct + */ + void esp_rom_spi_cmd_config(int spi_num, esp_rom_spi_cmd_t* pcmd); + + /** + * @brief Start a spi user command sequence + * @param spi_num spi port + * @param rx_buf buffer pointer to receive data + * @param rx_len receive data length in byte + * @param cs_en_mask decide which cs to use, 0 for cs0, 1 for cs1 + * @param is_write_erase to indicate whether this is a write or erase operation, since the CPU would check permission + */ + void esp_rom_spi_cmd_start(int spi_num, uint8_t* rx_buf, uint16_t rx_len, uint8_t cs_en_mask, bool is_write_erase); + + /** + * @brief Config opi flash pads according to efuse settings. + */ + void esp_rom_opiflash_pin_config(void); + + // set SPI read/write mode + /** + * @brief Set SPI operation mode + * @param spi_num spi port + * @param mode Flash Read Mode + */ + void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode); + + /** + * @brief Set data swap mode in DTR(DDR) mode + * @param spi_num spi port + * @param wr_swap to decide whether to swap fifo data in dtr write operation + * @param rd_swap to decide whether to swap fifo data in dtr read operation + */ + void esp_rom_spi_set_dtr_swap_mode(int spi, bool wr_swap, bool rd_swap); + + + /** + * @brief to send reset command in spi/opi-str/opi-dtr mode(for MX25UM25645G) + * @param spi_num spi port + */ + void esp_rom_opiflash_mode_reset(int spi_num); + + /** + * @brief To execute a flash operation command + * @param spi_num spi port + * @param mode Flash Read Mode + * @param cmd data to send in command field + * @param cmd_bit_len bit length of command field + * @param addr data to send in address field + * @param addr_bit_len bit length of address field + * @param dummy_bits bit length of dummy field + * @param mosi_data data buffer to be sent in mosi field + * @param mosi_bit_len bit length of data buffer to be sent in mosi field + * @param miso_data data buffer to accept data in miso field + * @param miso_bit_len bit length of data buffer to accept data in miso field + * @param cs_mark decide which cs pin to use. 0: cs0, 1: cs1 + * @param is_write_erase_operation to indicate whether this a write or erase flash operation + */ + void esp_rom_opiflash_exec_cmd(int spi_num, esp_rom_spiflash_read_mode_t mode, + uint32_t cmd, int cmd_bit_len, + uint32_t addr, int addr_bit_len, + int dummy_bits, + uint8_t* mosi_data, int mosi_bit_len, + uint8_t* miso_data, int miso_bit_len, + uint32_t cs_mask, + bool is_write_erase_operation); + + /** + * @brief send reset command to opi flash + * @param spi_num spi port + * @param mode Flash Operation Mode + */ + void esp_rom_opiflash_soft_reset(int spi_num, esp_rom_spiflash_read_mode_t mode); + + + /** + * @brief to read opi flash ID + * @note command format would be defined in initialization + * @param[out] out_id buffer to accept id + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_read_id(uint8_t *out_id); + + /** + * @brief to read opi flash status register + * @note command format would be defined in initialization + * @return opi flash status value + */ + uint8_t esp_rom_opiflash_rdsr(void); + + /** + * @brief wait opi flash status register to be idle + * @note command format would be defined in initialization + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_wait_idle(void); + + /** + * @brief to erase flash sector + * @note command format would be defined in initialization + * @param sector_num the sector to be erased + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_erase_sector(uint32_t sector_num); + + /** + * @brief to erase flash block + * @note command format would be defined in initialization + * @param block_num the block to be erased + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_erase_block_64k(uint32_t block_num); + + /** + * @brief to erase a flash area define by start address and length + * @note command format would be defined in initialization + * @param start_addr the start address to be erased + * @param area_len the erea length to be erased + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_erase_area(uint32_t start_addr, uint32_t area_len); + + /** + * @brief to read data from opi flash + * @note command format would be defined in initialization + * @param flash_addr flash address to read data from + * @param data_addr data buffer to accept the data + * @param len data length to be read + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_read(uint32_t flash_addr, void *data_addr, int len); + + /** + * @brief to write data to opi flash + * @note command format would be defined in initialization + * @param flash_addr flash address to write data to + * @param data_addr data buffer to write to flash + * @param len data length to write + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_write(uint32_t flash_addr, const uint32_t *data_addr, int len); + + /** + * @brief send WREN command + * @note command format would be defined in initialization + * @param arg not used, set to NULL + * @return flash operation result + */ + esp_rom_spiflash_result_t esp_rom_opiflash_wren(void* arg); + + /** + * @brief to configure SPI0 read flash command format for cache + * @note command format would be defined in initialization + * + */ + void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache); + + esp_rom_spiflash_result_t esp_rom_opiflash_read_raw(uint32_t flash_addr, uint8_t* buf, int len); + + + #ifdef __cplusplus + } + #endif + + #endif diff --git a/components/esp_system/fpga_overrides_clk.c b/components/esp_system/fpga_overrides_clk.c index 0d3e142d0e..d37a970e90 100644 --- a/components/esp_system/fpga_overrides_clk.c +++ b/components/esp_system/fpga_overrides_clk.c @@ -52,7 +52,7 @@ void bootloader_clock_configure(void) #endif } -void esp_rtc_init(void) +void IRAM_ATTR esp_rtc_init(void) { #if SOC_PMU_SUPPORTED pmu_init(); diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index e09bc635d2..d31a832dc7 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -67,6 +67,10 @@ config SOC_RTC_TIMER_SUPPORTED bool default y +config SOC_SPIRAM_SUPPORTED + bool + default y + config SOC_PSRAM_DMA_CAPABLE bool default y @@ -299,6 +303,18 @@ config SOC_SPI_MAXIMUM_BUFFER_SIZE int default 64 +config SOC_SPIRAM_XIP_SUPPORTED + bool + default y + +config SOC_SPI_MEM_SUPPORT_TIMING_TUNING + bool + default y + +config SOC_MEMSPI_TIMING_TUNING_BY_DQS + bool + default y + config SOC_MSPI_HAS_INDEPENT_IOMUX bool default y @@ -311,10 +327,6 @@ config SOC_MEMSPI_SUPPORT_CONTROL_DUMMY_OUT bool default y -config SOC_MEMSPI_FLASH_PSRAM_INDEPENDENT - bool - default y - config SOC_MEMSPI_ENCRYPTION_ALIGNMENT int default 16 @@ -415,6 +427,10 @@ config SOC_CLK_APLL_SUPPORTED bool default y +config SOC_CLK_MPLL_SUPPORTED + bool + default y + config SOC_CLK_RC32K_SUPPORTED bool default y diff --git a/components/soc/esp32s31/include/soc/clk_tree_defs.h b/components/soc/esp32s31/include/soc/clk_tree_defs.h index a4605ccc4e..4c9e9dd213 100644 --- a/components/soc/esp32s31/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s31/include/soc/clk_tree_defs.h @@ -274,6 +274,23 @@ typedef enum { SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select XTAL as default source clock */ } soc_periph_spi_clk_src_t; +/////////////////////////////////////////////////PSRAM//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of PSRAM + */ +#define SOC_PSRAM_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_CPLL, SOC_MOD_CLK_MPLL} + +/** + * @brief Type of PSRAM clock source. + */ +typedef enum { + PSRAM_CLK_SRC_DEFAULT = SOC_MOD_CLK_MPLL, /*!< Select SOC_MOD_CLK_MPLL as PSRAM source clock */ + PSRAM_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as PSRAM source clock */ + PSRAM_CLK_SRC_CPLL = SOC_MOD_CLK_CPLL, /*!< Select SOC_MOD_CLK_CPLL as PSRAM source clock */ + PSRAM_CLK_SRC_MPLL = SOC_MOD_CLK_MPLL, /*!< Select SOC_MOD_CLK_MPLL as PSRAM source clock */ +} soc_periph_psram_clk_src_t; + /////////////////////////////////////////////////FLASH//////////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index b6a3e053d4..50bf58b087 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -80,7 +80,7 @@ // #define SOC_LP_PERIPHERALS_SUPPORTED 1 // TODO: [ESP32S31] IDF-14785 // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32S31] IDF-14635 // #define SOC_LP_SPI_SUPPORTED 1 // TODO: [ESP32S31] IDF-14639 -// #define SOC_SPIRAM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14718 +#define SOC_SPIRAM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14718 #define SOC_PSRAM_DMA_CAPABLE 1 // #define SOC_SDMMC_HOST_SUPPORTED 1 // TODO: [ESP32S31] IDF-14705 // #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32S31] IDF-14733 @@ -217,13 +217,17 @@ #define SOC_SPI_MAXIMUM_BUFFER_SIZE 64 #define SOC_SPI_MAX_BITWIDTH(host_id) ((host_id == 2) ? 4 : 8) // Supported line mode: SPI3: 1, 2, 4, SPI1/2: 1, 2, 4, 8 +/*-------------------------- SPIRAM CAPS ----------------------------------------*/ +#define SOC_SPIRAM_XIP_SUPPORTED 1 + /*-------------------------- SPI MEM CAPS ---------------------------------------*/ +#define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1) +#define SOC_MEMSPI_TIMING_TUNING_BY_DQS (1) + #define SOC_MSPI_HAS_INDEPENT_IOMUX 1 #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_MEMSPI_SUPPORT_CONTROL_DUMMY_OUT 1 -#define SOC_MEMSPI_FLASH_PSRAM_INDEPENDENT 1 - #define SOC_MEMSPI_ENCRYPTION_ALIGNMENT 16 /*!< 16-byte alignment restriction to mem addr and size if encryption is enabled */ /*-------------------------- SYSTIMER CAPS ----------------------------------*/ @@ -281,6 +285,7 @@ #define SOC_MODEM_CLOCK_IS_INDEPENDENT (1) #define SOC_CLK_APLL_SUPPORTED (1) /*!< Support Audio PLL */ +#define SOC_CLK_MPLL_SUPPORTED (1) /*!< Support MSPI PLL */ #define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */ #define SOC_CLK_LP_FAST_SUPPORT_LP_PLL (1) /*!< Support LP_PLL clock as the LP_FAST clock source */ diff --git a/components/soc/esp32s31/register/soc/iomux_mspi_pin_struct.h b/components/soc/esp32s31/register/soc/iomux_mspi_pin_struct.h index b4b25ef2fa..459497a7ed 100644 --- a/components/soc/esp32s31/register/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32s31/register/soc/iomux_mspi_pin_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -26,405 +26,89 @@ typedef union { uint32_t val; } iomux_mspi_pin_clk_en0_reg_t; - -/** Group: psram_d_pin */ -/** Type of psram_d_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ +/** psram_pin */ typedef union { struct { - /** reg_psram_d_dli : R/W; bitpos: [3:0]; default: 0; - * psram d dli + /** reg_psram_pin_dli : R/W; bitpos: [3:0]; default: 0; + * psram pin dli */ - uint32_t reg_psram_d_dli:4; - /** reg_psram_d_dlc : R/W; bitpos: [7:4]; default: 0; - * psram d dlc + uint32_t reg_psram_pin_dli:4; + /** reg_psram_pin_dlc : R/W; bitpos: [7:4]; default: 0; + * psram pin dlc */ - uint32_t reg_psram_d_dlc:4; - /** reg_psram_d_hys : R/W; bitpos: [8]; default: 0; - * psram d sl + uint32_t reg_psram_pin_dlc:4; + /** reg_psram_pin_hys : R/W; bitpos: [8]; default: 0; + * psram pin hys */ - uint32_t reg_psram_d_hys:1; - /** reg_psram_d_ie : R/W; bitpos: [9]; default: 0; + uint32_t reg_psram_pin_hys:1; + /** reg_psram_pin_ie : R/W; bitpos: [9]; default: 0; * Reserved */ - uint32_t reg_psram_d_ie:1; - /** reg_psram_d_wpu : R/W; bitpos: [10]; default: 0; - * psram d wpu + uint32_t reg_psram_pin_ie:1; + /** reg_psram_pin_wpu : R/W; bitpos: [10]; default: 0; + * psram pin wpu */ - uint32_t reg_psram_d_wpu:1; - /** reg_psram_d_wpd : R/W; bitpos: [11]; default: 0; - * psram d wpd + uint32_t reg_psram_pin_wpu:1; + /** reg_psram_pin_wpd : R/W; bitpos: [11]; default: 0; + * psram pin wpd */ - uint32_t reg_psram_d_wpd:1; - /** reg_psram_d_drv : R/W; bitpos: [14:12]; default: 4; - * psram d drv + uint32_t reg_psram_pin_wpd:1; + /** reg_psram_pin_drv : R/W; bitpos: [14:12]; default: 4; + * psram pin drv */ - uint32_t reg_psram_d_drv:3; - /** reg_psram_d_hold : R/W; bitpos: [15]; default: 0; - * psram d hold + uint32_t reg_psram_pin_drv:3; + /** reg_psram_pin_hold : R/W; bitpos: [15]; default: 0; + * psram pin hold */ - uint32_t reg_psram_d_hold:1; + uint32_t reg_psram_pin_hold:1; uint32_t reserved_16:16; }; uint32_t val; -} iomux_mspi_pin_psram_d_pin0_reg_t; +} iomux_mspi_pin_psram_pin_reg_t; - -/** Group: psram_q_pin */ -/** Type of psram_q_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ +/** psram_dqs_pin */ typedef union { struct { - /** reg_psram_q_dli : R/W; bitpos: [3:0]; default: 0; - * psram q dli + /** reg_psram_dqs_xpd : R/W; bitpos: [0]; default: 0; + * psram xpd dqs */ - uint32_t reg_psram_q_dli:4; - /** reg_psram_q_dlc : R/W; bitpos: [7:4]; default: 0; - * psram q dlc + uint32_t reg_psram_dqs_xpd:1; + /** reg_psram_dqs_phase : R/W; bitpos: [2:1]; default: 0; + * psram dqs phase */ - uint32_t reg_psram_q_dlc:4; - /** reg_psram_q_hys : R/W; bitpos: [8]; default: 0; - * psram q sl + uint32_t reg_psram_dqs_phase:2; + /** reg_psram_dqs_dli : R/W; bitpos: [6:3]; default: 0; + * psram dqs dli */ - uint32_t reg_psram_q_hys:1; - /** reg_psram_q_ie : R/W; bitpos: [9]; default: 0; + uint32_t reg_psram_dqs_dli:4; + /** reg_psram_dqs_delay_90 : R/W; bitpos: [10:7]; default: 0; + * psram dqs delay 90 + */ + uint32_t reg_psram_dqs_delay_90:4; + /** reg_psram_dqs_hys : R/W; bitpos: [11]; default: 0; + * psram dqs hys + */ + uint32_t reg_psram_dqs_hys:1; + /** reg_psram_dqs_ie : R/W; bitpos: [12]; default: 0; * Reserved */ - uint32_t reg_psram_q_ie:1; - /** reg_psram_q_wpu : R/W; bitpos: [10]; default: 0; - * psram q wpu + uint32_t reg_psram_dqs_ie:1; + /** reg_psram_dqs_wpu : R/W; bitpos: [13]; default: 0; + * psram dqs wpu */ - uint32_t reg_psram_q_wpu:1; - /** reg_psram_q_wpd : R/W; bitpos: [11]; default: 0; - * psram q wpd + uint32_t reg_psram_dqs_wpu:1; + /** reg_psram_dqs_wpd : R/W; bitpos: [14]; default: 0; + * psram dqs wpd */ - uint32_t reg_psram_q_wpd:1; - /** reg_psram_q_drv : R/W; bitpos: [14:12]; default: 4; - * psram q drv + uint32_t reg_psram_dqs_wpd:1; + /** reg_psram_dqs_drv : R/W; bitpos: [17:15]; default: 4; + * psram dqs drv */ - uint32_t reg_psram_q_drv:3; - /** reg_psram_q_hold : R/W; bitpos: [15]; default: 0; - * psram q hold + uint32_t reg_psram_dqs_drv:3; + /** reg_psram_dqs_delay_270 : R/W; bitpos: [21:18]; default: 0; + * psram dqs delay 270 */ - uint32_t reg_psram_q_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_q_pin0_reg_t; - - -/** Group: psram_wp_pin */ -/** Type of psram_wp_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_wp_dli : R/W; bitpos: [3:0]; default: 0; - * psram wp dli - */ - uint32_t reg_psram_wp_dli:4; - /** reg_psram_wp_dlc : R/W; bitpos: [7:4]; default: 0; - * psram wp dlc - */ - uint32_t reg_psram_wp_dlc:4; - /** reg_psram_wp_hys : R/W; bitpos: [8]; default: 0; - * psram wp sl - */ - uint32_t reg_psram_wp_hys:1; - /** reg_psram_wp_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_wp_ie:1; - /** reg_psram_wp_wpu : R/W; bitpos: [10]; default: 0; - * psram wp wpu - */ - uint32_t reg_psram_wp_wpu:1; - /** reg_psram_wp_wpd : R/W; bitpos: [11]; default: 0; - * psram wp wpd - */ - uint32_t reg_psram_wp_wpd:1; - /** reg_psram_wp_drv : R/W; bitpos: [14:12]; default: 4; - * psram wp drv - */ - uint32_t reg_psram_wp_drv:3; - /** reg_psram_wp_hold : R/W; bitpos: [15]; default: 0; - * psram wp hold - */ - uint32_t reg_psram_wp_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_wp_pin0_reg_t; - - -/** Group: psram_hold_pin */ -/** Type of psram_hold_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_hold_dli : R/W; bitpos: [3:0]; default: 0; - * psram hold dli - */ - uint32_t reg_psram_hold_dli:4; - /** reg_psram_hold_dlc : R/W; bitpos: [7:4]; default: 0; - * psram hold dlc - */ - uint32_t reg_psram_hold_dlc:4; - /** reg_psram_hold_hys : R/W; bitpos: [8]; default: 0; - * psram hold sl - */ - uint32_t reg_psram_hold_hys:1; - /** reg_psram_hold_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_hold_ie:1; - /** reg_psram_hold_wpu : R/W; bitpos: [10]; default: 0; - * psram hold wpu - */ - uint32_t reg_psram_hold_wpu:1; - /** reg_psram_hold_wpd : R/W; bitpos: [11]; default: 0; - * psram hold wpd - */ - uint32_t reg_psram_hold_wpd:1; - /** reg_psram_hold_drv : R/W; bitpos: [14:12]; default: 4; - * psram hold drv - */ - uint32_t reg_psram_hold_drv:3; - /** reg_psram_hold_hold : R/W; bitpos: [15]; default: 0; - * psram hold hold - */ - uint32_t reg_psram_hold_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_hold_pin0_reg_t; - - -/** Group: psram_dq4_pin */ -/** Type of psram_dq4_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq4_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq4 dli - */ - uint32_t reg_psram_dq4_dli:4; - /** reg_psram_dq4_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq4 dlc - */ - uint32_t reg_psram_dq4_dlc:4; - /** reg_psram_dq4_hys : R/W; bitpos: [8]; default: 0; - * psram dq4 sl - */ - uint32_t reg_psram_dq4_hys:1; - /** reg_psram_dq4_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq4_ie:1; - /** reg_psram_dq4_wpu : R/W; bitpos: [10]; default: 0; - * psram dq4 wpu - */ - uint32_t reg_psram_dq4_wpu:1; - /** reg_psram_dq4_wpd : R/W; bitpos: [11]; default: 0; - * psram dq4 wpd - */ - uint32_t reg_psram_dq4_wpd:1; - /** reg_psram_dq4_drv : R/W; bitpos: [14:12]; default: 4; - * psram dq4 drv - */ - uint32_t reg_psram_dq4_drv:3; - /** reg_psram_dq4_hold : R/W; bitpos: [15]; default: 0; - * psram dq4 hold - */ - uint32_t reg_psram_dq4_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq4_pin0_reg_t; - - -/** Group: psram_dq5_pin */ -/** Type of psram_dq5_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq5_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq5 dli - */ - uint32_t reg_psram_dq5_dli:4; - /** reg_psram_dq5_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq5 dlc - */ - uint32_t reg_psram_dq5_dlc:4; - /** reg_psram_dq5_hys : R/W; bitpos: [8]; default: 0; - * psram dq5 sl - */ - uint32_t reg_psram_dq5_hys:1; - /** reg_psram_dq5_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq5_ie:1; - /** reg_psram_dq5_wpu : R/W; bitpos: [10]; default: 0; - * psram dq5 wpu - */ - uint32_t reg_psram_dq5_wpu:1; - /** reg_psram_dq5_wpd : R/W; bitpos: [11]; default: 0; - * psram dq5 wpd - */ - uint32_t reg_psram_dq5_wpd:1; - /** reg_psram_dq5_drv : R/W; bitpos: [14:12]; default: 4; - * psram dq5 drv - */ - uint32_t reg_psram_dq5_drv:3; - /** reg_psram_dq5_hold : R/W; bitpos: [15]; default: 0; - * psram dq5 hold - */ - uint32_t reg_psram_dq5_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq5_pin0_reg_t; - - -/** Group: psram_dq6_pin */ -/** Type of psram_dq6_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq6_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq6 dli - */ - uint32_t reg_psram_dq6_dli:4; - /** reg_psram_dq6_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq6 dlc - */ - uint32_t reg_psram_dq6_dlc:4; - /** reg_psram_dq6_hys : R/W; bitpos: [8]; default: 0; - * psram dq6 sl - */ - uint32_t reg_psram_dq6_hys:1; - /** reg_psram_dq6_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq6_ie:1; - /** reg_psram_dq6_wpu : R/W; bitpos: [10]; default: 0; - * psram dq6 wpu - */ - uint32_t reg_psram_dq6_wpu:1; - /** reg_psram_dq6_wpd : R/W; bitpos: [11]; default: 0; - * psram dq6 wpd - */ - uint32_t reg_psram_dq6_wpd:1; - /** reg_psram_dq6_drv : R/W; bitpos: [14:12]; default: 4; - * psram dq6 drv - */ - uint32_t reg_psram_dq6_drv:3; - /** reg_psram_dq6_hold : R/W; bitpos: [15]; default: 0; - * psram dq6 hold - */ - uint32_t reg_psram_dq6_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq6_pin0_reg_t; - - -/** Group: psram_dq7_pin */ -/** Type of psram_dq7_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq7_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq7 dli - */ - uint32_t reg_psram_dq7_dli:4; - /** reg_psram_dq7_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq7 dlc - */ - uint32_t reg_psram_dq7_dlc:4; - /** reg_psram_dq7_hys : R/W; bitpos: [8]; default: 0; - * psram dq7 sl - */ - uint32_t reg_psram_dq7_hys:1; - /** reg_psram_dq7_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq7_ie:1; - /** reg_psram_dq7_wpu : R/W; bitpos: [10]; default: 0; - * psram dq7 wpu - */ - uint32_t reg_psram_dq7_wpu:1; - /** reg_psram_dq7_wpd : R/W; bitpos: [11]; default: 0; - * psram dq7 wpd - */ - uint32_t reg_psram_dq7_wpd:1; - /** reg_psram_dq7_drv : R/W; bitpos: [14:12]; default: 4; - * psram dq7 drv - */ - uint32_t reg_psram_dq7_drv:3; - /** reg_psram_dq7_hold : R/W; bitpos: [15]; default: 0; - * psram dq7 hold - */ - uint32_t reg_psram_dq7_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq7_pin0_reg_t; - - -/** Group: psram_dqs_0_pin */ -/** Type of psram_dqs_0_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dqs_0_xpd : R/W; bitpos: [0]; default: 0; - * psram xpd dqs0 - */ - uint32_t reg_psram_dqs_0_xpd:1; - /** reg_psram_dqs_0_phase : R/W; bitpos: [2:1]; default: 0; - * psram dqs0 phase - */ - uint32_t reg_psram_dqs_0_phase:2; - /** reg_psram_dqs_0_dli : R/W; bitpos: [6:3]; default: 0; - * psram dqs0 dli - */ - uint32_t reg_psram_dqs_0_dli:4; - /** reg_psram_dqs_0_delay_90 : R/W; bitpos: [10:7]; default: 0; - * psram dqs0 delay 90 - */ - uint32_t reg_psram_dqs_0_delay_90:4; - /** reg_psram_dqs_0_hys : R/W; bitpos: [11]; default: 0; - * psram dqs0 sl - */ - uint32_t reg_psram_dqs_0_hys:1; - /** reg_psram_dqs_0_ie : R/W; bitpos: [12]; default: 0; - * Reserved - */ - uint32_t reg_psram_dqs_0_ie:1; - /** reg_psram_dqs_0_wpu : R/W; bitpos: [13]; default: 0; - * psram dqs0 wpu - */ - uint32_t reg_psram_dqs_0_wpu:1; - /** reg_psram_dqs_0_wpd : R/W; bitpos: [14]; default: 0; - * psram dqs0 wpd - */ - uint32_t reg_psram_dqs_0_wpd:1; - /** reg_psram_dqs_0_drv : R/W; bitpos: [17:15]; default: 4; - * psram dqs0 drv - */ - uint32_t reg_psram_dqs_0_drv:3; - /** reg_psram_dqs_0_delay_270 : R/W; bitpos: [21:18]; default: 0; - * psram dqs0 delay 270 - */ - uint32_t reg_psram_dqs_0_delay_270:4; + uint32_t reg_psram_dqs_delay_270:4; /** reg_psram_dqs_hold : R/W; bitpos: [22]; default: 0; * psram dqs hold */ @@ -432,111 +116,20 @@ typedef union { uint32_t reserved_23:9; }; uint32_t val; -} iomux_mspi_pin_psram_dqs_0_pin0_reg_t; - - -/** Group: psram_ck_pin */ -/** Type of psram_ck_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_ck_dli : R/W; bitpos: [3:0]; default: 0; - * psram ck dli - */ - uint32_t reg_psram_ck_dli:4; - /** reg_psram_ck_dlc : R/W; bitpos: [7:4]; default: 0; - * psram ck dlc - */ - uint32_t reg_psram_ck_dlc:4; - /** reg_psram_ck_hys : R/W; bitpos: [8]; default: 0; - * psram ck sl - */ - uint32_t reg_psram_ck_hys:1; - /** reg_psram_ck_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_ck_ie:1; - /** reg_psram_ck_wpu : R/W; bitpos: [10]; default: 0; - * psram ck wpu - */ - uint32_t reg_psram_ck_wpu:1; - /** reg_psram_ck_wpd : R/W; bitpos: [11]; default: 0; - * psram ck wpd - */ - uint32_t reg_psram_ck_wpd:1; - /** reg_psram_ck_drv : R/W; bitpos: [14:12]; default: 4; - * psram ck drv - */ - uint32_t reg_psram_ck_drv:3; - /** reg_psram_ck_hold : R/W; bitpos: [15]; default: 0; - * psram ck hold - */ - uint32_t reg_psram_ck_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_ck_pin0_reg_t; - - -/** Group: psram_cs_pin */ -/** Type of psram_cs_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_cs_dli : R/W; bitpos: [3:0]; default: 0; - * psram cs dli - */ - uint32_t reg_psram_cs_dli:4; - /** reg_psram_cs_dlc : R/W; bitpos: [7:4]; default: 0; - * psram cs dlc - */ - uint32_t reg_psram_cs_dlc:4; - /** reg_psram_cs_hys : R/W; bitpos: [8]; default: 0; - * psram cs sl - */ - uint32_t reg_psram_cs_hys:1; - /** reg_psram_cs_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_cs_ie:1; - /** reg_psram_cs_wpu : R/W; bitpos: [10]; default: 0; - * psram cs wpu - */ - uint32_t reg_psram_cs_wpu:1; - /** reg_psram_cs_wpd : R/W; bitpos: [11]; default: 0; - * psram cs wpd - */ - uint32_t reg_psram_cs_wpd:1; - /** reg_psram_cs_drv : R/W; bitpos: [14:12]; default: 4; - * psram cs drv - */ - uint32_t reg_psram_cs_drv:3; - /** reg_psram_cs_hold : R/W; bitpos: [15]; default: 0; - * psram cs hold - */ - uint32_t reg_psram_cs_hold:1; - uint32_t reserved_16:16; - }; - uint32_t val; -} iomux_mspi_pin_psram_cs_pin0_reg_t; +} iomux_mspi_pin_psram_dqs_pin_reg_t; +/** psram_pin group */ +typedef struct { + volatile iomux_mspi_pin_psram_pin_reg_t pin_group0[8]; // for d, q, wp, hold, dq4, dq5, dq6, dq7 + volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs0; + volatile iomux_mspi_pin_psram_pin_reg_t pin_clk; + volatile iomux_mspi_pin_psram_pin_reg_t pin_cs; +} iomux_mspi_pin_psram_pin_grp_reg_t; typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; uint32_t reserved_004[6]; - volatile iomux_mspi_pin_psram_d_pin0_reg_t psram_d_pin0; - volatile iomux_mspi_pin_psram_q_pin0_reg_t psram_q_pin0; - volatile iomux_mspi_pin_psram_wp_pin0_reg_t psram_wp_pin0; - volatile iomux_mspi_pin_psram_hold_pin0_reg_t psram_hold_pin0; - volatile iomux_mspi_pin_psram_dq4_pin0_reg_t psram_dq4_pin0; - volatile iomux_mspi_pin_psram_dq5_pin0_reg_t psram_dq5_pin0; - volatile iomux_mspi_pin_psram_dq6_pin0_reg_t psram_dq6_pin0; - volatile iomux_mspi_pin_psram_dq7_pin0_reg_t psram_dq7_pin0; - volatile iomux_mspi_pin_psram_dqs_0_pin0_reg_t psram_dqs_0_pin0; - volatile iomux_mspi_pin_psram_ck_pin0_reg_t psram_ck_pin0; - volatile iomux_mspi_pin_psram_cs_pin0_reg_t psram_cs_pin0; + volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t; extern iomux_mspi_pin_dev_t MSPI_IOMUX; diff --git a/components/soc/esp32s31/register/soc/reg_base.h b/components/soc/esp32s31/register/soc/reg_base.h index 609b347884..d022438c84 100644 --- a/components/soc/esp32s31/register/soc/reg_base.h +++ b/components/soc/esp32s31/register/soc/reg_base.h @@ -81,7 +81,7 @@ #define DR_REG_HP_ALIVE_SYS_BASE 0x20589000 #define DR_REG_HP_PERI1_PMS_BASE 0x2058A000 #define DR_REG_LP_SYS_BASE 0x20700000 -#define DR_REG_LP_CLKRST_BASE 0x20701000 +#define DR_REG_LP_AONCLKRST_BASE 0x20701000 #define DR_REG_LP_ANA_BASE 0x20702000 #define DR_REG_HUK_BASE 0x20703000 #define DR_REG_PMU_BASE 0x20704000 diff --git a/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h b/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h index 4349dac1b0..115f9233c0 100644 --- a/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h +++ b/components/soc/esp32s31/register/soc/spi1_mem_c_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -121,7 +121,7 @@ typedef union { uint32_t flash_read:1; }; uint32_t val; -} spi_mem_cmd_reg_t; +} spi1_mem_c_cmd_reg_t; /** Type of addr register * SPI1 address register @@ -135,7 +135,7 @@ typedef union { uint32_t usr_addr_value:32; }; uint32_t val; -} spi_mem_addr_reg_t; +} spi1_mem_c_addr_reg_t; /** Type of user register * SPI1 user register. @@ -203,7 +203,7 @@ typedef union { uint32_t usr_command:1; }; uint32_t val; -} spi_mem_user_reg_t; +} spi1_mem_c_user_reg_t; /** Type of user1 register * SPI1 user1 register. @@ -222,7 +222,7 @@ typedef union { uint32_t usr_addr_bitlen:6; }; uint32_t val; -} spi_mem_user1_reg_t; +} spi1_mem_c_user1_reg_t; /** Type of user2 register * SPI1 user2 register. @@ -240,7 +240,7 @@ typedef union { uint32_t usr_command_bitlen:4; }; uint32_t val; -} spi_mem_user2_reg_t; +} spi1_mem_c_user2_reg_t; /** Group: Control and configuration registers */ @@ -303,7 +303,7 @@ typedef union { */ uint32_t fread_dual:1; /** resandres : R/W; bitpos: [15]; default: 1; - * The Device ID is read out to SPI_MEM_RD_STATUS register, this bit combine with + * The Device ID is read out to SPI1_MEM_C_RD_STATUS register, this bit combine with * spi_mem_flash_res bit. 1: enable 0: disable. * This field is only for internal debugging purposes. Do not use it in applications. */ @@ -344,7 +344,7 @@ typedef union { uint32_t reserved_25:7; }; uint32_t val; -} spi_mem_ctrl_reg_t; +} spi1_mem_c_ctrl_reg_t; /** Type of ctrl1 register * SPI1 control1 register. @@ -358,19 +358,26 @@ typedef union { */ uint32_t clk_mode:2; /** cs_hold_dly_res : R/W; bitpos: [11:2]; default: 1023; - * After RES/DP/HPM/PES command is sent, SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * - * 128) SPI_CLK cycles. + * After RES/DP/HPM command is sent, SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * + * 512) SPI_CLK cycles. + * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t cs_hold_dly_res:10; - /** cs_hold_dly_per : R/W; bitpos: [21:12]; default: 1023; - * After PER command is sent, SPI1 waits (SPI_MEM_CS_HOLD_DLY_PER[9:0] * 128) SPI_CLK - * cycles. + /** cs_hold_dly_per : R/W; bitpos: [20:12]; default: 511; + * After PER command is sent, SPI1 waits (SPI1_MEM_C_CS_HOLD_DLY_PER[8:0] * 128) + * SPI_CLK cycles. */ - uint32_t cs_hold_dly_per:10; - uint32_t reserved_22:10; + uint32_t cs_hold_dly_per:9; + uint32_t reserved_21:2; + /** cs_hold_dly_per_en : R/W; bitpos: [23]; default: 0; + * 1: use SPI1_MEM_C_CS_HOLD_DLY_PER for per, use SPI1_MEM_C_CS_HOLD_DELAY_RES for + * pes/dp/hpm . 0: use SPI1_MEM_C_CS_HOLD_DELAY_RES for pes/dp/hpm/per . + */ + uint32_t cs_hold_dly_per_en:1; + uint32_t reserved_24:8; }; uint32_t val; -} spi_mem_ctrl1_reg_t; +} spi1_mem_c_ctrl1_reg_t; /** Type of ctrl2 register * SPI1 control2 register. @@ -384,7 +391,7 @@ typedef union { uint32_t sync_reset:1; }; uint32_t val; -} spi_mem_ctrl2_reg_t; +} spi1_mem_c_ctrl2_reg_t; /** Type of clock register * SPI1 clock division control register. @@ -392,16 +399,16 @@ typedef union { typedef union { struct { /** clkcnt_l : R/W; bitpos: [7:0]; default: 3; - * In the master mode it must be equal to SPI_MEM_CLKCNT_N. + * In the master mode it must be equal to SPI1_MEM_C_CLKCNT_N. */ uint32_t clkcnt_l:8; /** clkcnt_h : R/W; bitpos: [15:8]; default: 1; - * In the master mode it must be floor((SPI_MEM_CLKCNT_N+1)/2-1). + * In the master mode it must be floor((SPI1_MEM_C_CLKCNT_N+1)/2-1). */ uint32_t clkcnt_h:8; /** clkcnt_n : R/W; bitpos: [23:16]; default: 3; * In the master mode it is the divider of spi_mem_clk. So spi_mem_clk frequency is - * system/(SPI_MEM_CLKCNT_N+1) + * system/(SPI1_MEM_C_CLKCNT_N+1) */ uint32_t clkcnt_n:8; uint32_t reserved_24:7; @@ -411,7 +418,7 @@ typedef union { uint32_t clk_equ_sysclk:1; }; uint32_t val; -} spi_mem_clock_reg_t; +} spi1_mem_c_clock_reg_t; /** Type of mosi_dlen register * SPI1 send data bit length control register. @@ -425,7 +432,7 @@ typedef union { uint32_t reserved_10:22; }; uint32_t val; -} spi_mem_mosi_dlen_reg_t; +} spi1_mem_c_mosi_dlen_reg_t; /** Type of miso_dlen register * SPI1 receive data bit length control register. @@ -439,7 +446,7 @@ typedef union { uint32_t reserved_10:22; }; uint32_t val; -} spi_mem_miso_dlen_reg_t; +} spi1_mem_c_miso_dlen_reg_t; /** Type of rd_status register * SPI1 status register. @@ -455,20 +462,10 @@ typedef union { * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t wb_mode:8; - /** wb_mode_bitlen : R/W; bitpos: [26:24]; default: 0; - * Mode bits length for flash fast read mode. - * This field is only for internal debugging purposes. Do not use it in applications. - */ - uint32_t wb_mode_bitlen:3; - /** wb_mode_en : R/W; bitpos: [27]; default: 0; - * Mode bits is valid while this bit is enable. 1: enable 0: disable. - * This field is only for internal debugging purposes. Do not use it in applications. - */ - uint32_t wb_mode_en:1; - uint32_t reserved_28:4; + uint32_t reserved_24:8; }; uint32_t val; -} spi_mem_rd_status_reg_t; +} spi1_mem_c_rd_status_reg_t; /** Type of misc register * SPI1 misc register @@ -497,7 +494,7 @@ typedef union { uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_misc_reg_t; +} spi1_mem_c_misc_reg_t; /** Type of cache_fctrl register * SPI1 bit mode control register. @@ -550,7 +547,7 @@ typedef union { uint32_t reserved_9:23; }; uint32_t val; -} spi_mem_cache_fctrl_reg_t; +} spi1_mem_c_cache_fctrl_reg_t; /** Type of flash_waiti_ctrl register * SPI1 wait idle control register @@ -573,9 +570,9 @@ typedef union { */ uint32_t waiti_addr_en:1; /** waiti_addr_cyclelen : R/W; bitpos: [4:3]; default: 0; - * When SPI_MEM_WAITI_ADDR_EN is set, the cycle length of sent out address is - * (SPI_MEM_WAITI_ADDR_CYCLELEN[1:0] + 1) SPI bus clock cycles. It is not active when - * SPI_MEM_WAITI_ADDR_EN is cleared. + * When SPI1_MEM_C_WAITI_ADDR_EN is set, the cycle length of sent out address is + * (SPI1_MEM_C_WAITI_ADDR_CYCLELEN[1:0] + 1) SPI bus clock cycles. It is not active + * when SPI1_MEM_C_WAITI_ADDR_EN is cleared. */ uint32_t waiti_addr_cyclelen:2; uint32_t reserved_5:4; @@ -593,7 +590,7 @@ typedef union { uint32_t waiti_cmd:16; }; uint32_t val; -} spi_mem_flash_waiti_ctrl_reg_t; +} spi1_mem_c_flash_waiti_ctrl_reg_t; /** Type of flash_sus_ctrl register * SPI1 flash suspend control register @@ -613,13 +610,13 @@ typedef union { */ uint32_t flash_pes:1; /** flash_per_wait_en : R/W; bitpos: [2]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after + * 1: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after * program erase resume command is sent. 0: SPI1 does not wait after program erase * resume command is sent. */ uint32_t flash_per_wait_en:1; /** flash_pes_wait_en : R/W; bitpos: [3]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after + * 1: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after * program erase suspend command is sent. 0: SPI1 does not wait after program erase * suspend command is sent. */ @@ -637,7 +634,7 @@ typedef union { * The mask value when check SUS/SUS1/SUS2 status bit. If the read status value is * status_in[15:0](only status_in[7:0] is valid when only one byte of data is read * out, status_in[15:0] is valid when two bytes of data are read out), SUS/SUS1/SUS2 = - * status_in[15:0]^ SPI_MEM_PESR_END_MSK[15:0]. + * status_in[15:0]^ SPI1_MEM_C_PESR_END_MSK[15:0]. */ uint32_t pesr_end_msk:16; /** fmem_rd_sus_2b : R/W; bitpos: [22]; default: 0; @@ -656,13 +653,13 @@ typedef union { */ uint32_t pes_end_en:1; /** sus_timeout_cnt : R/W; bitpos: [31:25]; default: 4; - * When SPI1 checks SUS/SUS1/SUS2 bits fail for SPI_MEM_SUS_TIMEOUT_CNT[6:0] times, it - * will be treated as check pass. + * When SPI1 checks SUS/SUS1/SUS2 bits fail for SPI1_MEM_C_SUS_TIMEOUT_CNT[6:0] times, + * it will be treated as check pass. */ uint32_t sus_timeout_cnt:7; }; uint32_t val; -} spi_mem_flash_sus_ctrl_reg_t; +} spi1_mem_c_flash_sus_ctrl_reg_t; /** Type of flash_sus_cmd register * SPI1 flash suspend command register @@ -680,7 +677,7 @@ typedef union { uint32_t wait_pesr_command:16; }; uint32_t val; -} spi_mem_flash_sus_cmd_reg_t; +} spi1_mem_c_flash_sus_cmd_reg_t; /** Type of sus_status register * SPI1 flash suspend status register @@ -692,40 +689,40 @@ typedef union { */ uint32_t flash_sus:1; /** wait_pesr_cmd_2b : R/W; bitpos: [1]; default: 0; - * 1: SPI1 sends out SPI_MEM_WAIT_PESR_COMMAND[15:0] to check SUS/SUS1/SUS2 bit. 0: - * SPI1 sends out SPI_MEM_WAIT_PESR_COMMAND[7:0] to check SUS/SUS1/SUS2 bit. + * 1: SPI1 sends out SPI1_MEM_C_WAIT_PESR_COMMAND[15:0] to check SUS/SUS1/SUS2 bit. 0: + * SPI1 sends out SPI1_MEM_C_WAIT_PESR_COMMAND[7:0] to check SUS/SUS1/SUS2 bit. */ uint32_t wait_pesr_cmd_2b:1; /** flash_hpm_dly_128 : R/W; bitpos: [2]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after HPM - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after HPM command is sent. + * 1: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after HPM + * command is sent. 0: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after HPM command is sent. */ uint32_t flash_hpm_dly_128:1; /** flash_res_dly_128 : R/W; bitpos: [3]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after RES - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after RES command is sent. + * 1: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after RES + * command is sent. 0: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after RES command is sent. */ uint32_t flash_res_dly_128:1; /** flash_dp_dly_128 : R/W; bitpos: [4]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after DP - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after DP command is sent. + * 1: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after DP + * command is sent. 0: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after DP command is sent. */ uint32_t flash_dp_dly_128:1; /** flash_per_dly_128 : R/W; bitpos: [5]; default: 0; - * Valid when SPI_MEM_FLASH_PER_WAIT_EN is 1. 1: SPI1 waits - * (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PER command is sent. 0: - * SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PER command is - * sent. + * Valid when SPI1_MEM_C_FLASH_PER_WAIT_EN is 1. 1: SPI1 waits + * (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PER command is sent. + * 0: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PER + * command is sent. */ uint32_t flash_per_dly_128:1; /** flash_pes_dly_128 : R/W; bitpos: [6]; default: 0; - * Valid when SPI_MEM_FLASH_PES_WAIT_EN is 1. 1: SPI1 waits - * (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PES command is sent. 0: - * SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PES command is - * sent. + * Valid when SPI1_MEM_C_FLASH_PES_WAIT_EN is 1. 1: SPI1 waits + * (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PES command is sent. + * 0: SPI1 waits (SPI1_MEM_C_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PES + * command is sent. */ uint32_t flash_pes_dly_128:1; /** spi0_lock_en : R/W; bitpos: [7]; default: 0; @@ -744,25 +741,7 @@ typedef union { uint32_t flash_per_command:16; }; uint32_t val; -} spi_mem_sus_status_reg_t; - -/** Type of flash_waiti_ctrl1 register - * SPI1 wait idle control register - */ -typedef union { - struct { - /** waiti_idle_delay_time : R/W; bitpos: [9:0]; default: 0; - * SPI1 wait idle gap time configuration. SPI1 slv fsm will count during SPI1 IDLE. - */ - uint32_t waiti_idle_delay_time:10; - /** waiti_idle_delay_time_en : R/W; bitpos: [10]; default: 0; - * Enable SPI1 wait idle gap time count function. 1: Enable. 0: Disable. - */ - uint32_t waiti_idle_delay_time_en:1; - uint32_t reserved_11:21; - }; - uint32_t val; -} spi_mem_flash_waiti_ctrl1_reg_t; +} spi1_mem_c_sus_status_reg_t; /** Type of ddr register * SPI1 DDR control register @@ -800,8 +779,8 @@ typedef union { uint32_t fmem_usr_ddr_dqs_thd:7; /** fmem_ddr_dqs_loop : HRO; bitpos: [21]; default: 0; * 1: Do not need the input of SPI_DQS signal, SPI0 starts to receive data when - * spi0_slv_st is in SPI_MEM_DIN state. It is used when there is no SPI_DQS signal or - * SPI_DQS signal is not stable. 0: SPI0 starts to store data at the positive and + * spi0_slv_st is in SPI1_MEM_C_DIN state. It is used when there is no SPI_DQS signal + * or SPI_DQS signal is not stable. 0: SPI0 starts to store data at the positive and * negative edge of SPI_DQS. */ uint32_t fmem_ddr_dqs_loop:1; @@ -837,7 +816,7 @@ typedef union { uint32_t reserved_31:1; }; uint32_t val; -} spi_mem_ddr_reg_t; +} spi1_mem_c_ddr_reg_t; /** Type of clock_gate register * SPI1 clk_gate register @@ -851,7 +830,7 @@ typedef union { uint32_t reserved_1:31; }; uint32_t val; -} spi_mem_clock_gate_reg_t; +} spi1_mem_c_clock_gate_reg_t; /** Group: Status register */ @@ -867,7 +846,8 @@ typedef union { uint32_t tx_crc_data:32; }; uint32_t val; -} spi_mem_tx_crc_reg_t; +} spi1_mem_c_tx_crc_reg_t; + /** Group: Interrupt registers */ /** Type of int_ena register @@ -876,34 +856,34 @@ typedef union { typedef union { struct { /** per_end_int_ena : R/W; bitpos: [0]; default: 0; - * The enable bit for SPI_MEM_PER_END_INT interrupt. + * The enable bit for SPI1_MEM_C_PER_END_INT interrupt. */ uint32_t per_end_int_ena:1; /** pes_end_int_ena : R/W; bitpos: [1]; default: 0; - * The enable bit for SPI_MEM_PES_END_INT interrupt. + * The enable bit for SPI1_MEM_C_PES_END_INT interrupt. */ uint32_t pes_end_int_ena:1; /** wpe_end_int_ena : R/W; bitpos: [2]; default: 0; - * The enable bit for SPI_MEM_WPE_END_INT interrupt. + * The enable bit for SPI1_MEM_C_WPE_END_INT interrupt. */ uint32_t wpe_end_int_ena:1; /** slv_st_end_int_ena : R/W; bitpos: [3]; default: 0; - * The enable bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The enable bit for SPI1_MEM_C_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_ena:1; /** mst_st_end_int_ena : R/W; bitpos: [4]; default: 0; - * The enable bit for SPI_MEM_MST_ST_END_INT interrupt. + * The enable bit for SPI1_MEM_C_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_ena:1; uint32_t reserved_5:5; /** brown_out_int_ena : R/W; bitpos: [10]; default: 0; - * The enable bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The enable bit for SPI1_MEM_C_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_ena:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_ena_reg_t; +} spi1_mem_c_int_ena_reg_t; /** Type of int_clr register * SPI1 interrupt clear register @@ -911,34 +891,34 @@ typedef union { typedef union { struct { /** per_end_int_clr : WT; bitpos: [0]; default: 0; - * The clear bit for SPI_MEM_PER_END_INT interrupt. + * The clear bit for SPI1_MEM_C_PER_END_INT interrupt. */ uint32_t per_end_int_clr:1; /** pes_end_int_clr : WT; bitpos: [1]; default: 0; - * The clear bit for SPI_MEM_PES_END_INT interrupt. + * The clear bit for SPI1_MEM_C_PES_END_INT interrupt. */ uint32_t pes_end_int_clr:1; /** wpe_end_int_clr : WT; bitpos: [2]; default: 0; - * The clear bit for SPI_MEM_WPE_END_INT interrupt. + * The clear bit for SPI1_MEM_C_WPE_END_INT interrupt. */ uint32_t wpe_end_int_clr:1; /** slv_st_end_int_clr : WT; bitpos: [3]; default: 0; - * The clear bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The clear bit for SPI1_MEM_C_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_clr:1; /** mst_st_end_int_clr : WT; bitpos: [4]; default: 0; - * The clear bit for SPI_MEM_MST_ST_END_INT interrupt. + * The clear bit for SPI1_MEM_C_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_clr:1; uint32_t reserved_5:5; /** brown_out_int_clr : WT; bitpos: [10]; default: 0; - * The status bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The status bit for SPI1_MEM_C_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_clr:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_clr_reg_t; +} spi1_mem_c_int_clr_reg_t; /** Type of int_raw register * SPI1 interrupt raw register @@ -946,34 +926,34 @@ typedef union { typedef union { struct { /** per_end_int_raw : R/WTC/SS; bitpos: [0]; default: 0; - * The raw bit for SPI_MEM_PER_END_INT interrupt. 1: Triggered when Auto Resume + * The raw bit for SPI1_MEM_C_PER_END_INT interrupt. 1: Triggered when Auto Resume * command (0x7A) is sent and flash is resumed successfully. 0: Others. */ uint32_t per_end_int_raw:1; /** pes_end_int_raw : R/WTC/SS; bitpos: [1]; default: 0; - * The raw bit for SPI_MEM_PES_END_INT interrupt.1: Triggered when Auto Suspend + * The raw bit for SPI1_MEM_C_PES_END_INT interrupt.1: Triggered when Auto Suspend * command (0x75) is sent and flash is suspended successfully. 0: Others. */ uint32_t pes_end_int_raw:1; /** wpe_end_int_raw : R/WTC/SS; bitpos: [2]; default: 0; - * The raw bit for SPI_MEM_WPE_END_INT interrupt. 1: Triggered when WRSR/PP/SE/BE/CE - * is sent and flash is already idle. 0: Others. + * The raw bit for SPI1_MEM_C_WPE_END_INT interrupt. 1: Triggered when + * WRSR/PP/SE/BE/CE is sent and flash is already idle. 0: Others. */ uint32_t wpe_end_int_raw:1; /** slv_st_end_int_raw : R/WTC/SS; bitpos: [3]; default: 0; - * The raw bit for SPI_MEM_SLV_ST_END_INT interrupt. 1: Triggered when spi1_slv_st is - * changed from non idle state to idle state. It means that SPI_CS raises high. 0: + * The raw bit for SPI1_MEM_C_SLV_ST_END_INT interrupt. 1: Triggered when spi1_slv_st + * is changed from non idle state to idle state. It means that SPI_CS raises high. 0: * Others */ uint32_t slv_st_end_int_raw:1; /** mst_st_end_int_raw : R/WTC/SS; bitpos: [4]; default: 0; - * The raw bit for SPI_MEM_MST_ST_END_INT interrupt. 1: Triggered when spi1_mst_st is - * changed from non idle state to idle state. 0: Others. + * The raw bit for SPI1_MEM_C_MST_ST_END_INT interrupt. 1: Triggered when spi1_mst_st + * is changed from non idle state to idle state. 0: Others. */ uint32_t mst_st_end_int_raw:1; uint32_t reserved_5:5; /** brown_out_int_raw : R/WTC/SS; bitpos: [10]; default: 0; - * The raw bit for SPI_MEM_BROWN_OUT_INT interrupt. 1: Triggered condition is that + * The raw bit for SPI1_MEM_C_BROWN_OUT_INT interrupt. 1: Triggered condition is that * chip is losing power and RTC module sends out brown out close flash request to * SPI1. After SPI1 sends out suspend command to flash, this interrupt is triggered * and MSPI returns to idle state. 0: Others. @@ -982,7 +962,7 @@ typedef union { uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_raw_reg_t; +} spi1_mem_c_int_raw_reg_t; /** Type of int_st register * SPI1 interrupt status register @@ -990,34 +970,34 @@ typedef union { typedef union { struct { /** per_end_int_st : RO; bitpos: [0]; default: 0; - * The status bit for SPI_MEM_PER_END_INT interrupt. + * The status bit for SPI1_MEM_C_PER_END_INT interrupt. */ uint32_t per_end_int_st:1; /** pes_end_int_st : RO; bitpos: [1]; default: 0; - * The status bit for SPI_MEM_PES_END_INT interrupt. + * The status bit for SPI1_MEM_C_PES_END_INT interrupt. */ uint32_t pes_end_int_st:1; /** wpe_end_int_st : RO; bitpos: [2]; default: 0; - * The status bit for SPI_MEM_WPE_END_INT interrupt. + * The status bit for SPI1_MEM_C_WPE_END_INT interrupt. */ uint32_t wpe_end_int_st:1; /** slv_st_end_int_st : RO; bitpos: [3]; default: 0; - * The status bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The status bit for SPI1_MEM_C_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_st:1; /** mst_st_end_int_st : RO; bitpos: [4]; default: 0; - * The status bit for SPI_MEM_MST_ST_END_INT interrupt. + * The status bit for SPI1_MEM_C_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_st:1; uint32_t reserved_5:5; /** brown_out_int_st : RO; bitpos: [10]; default: 0; - * The status bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The status bit for SPI1_MEM_C_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_st:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_st_reg_t; +} spi1_mem_c_int_st_reg_t; /** Group: Timing registers */ @@ -1038,7 +1018,7 @@ typedef union { uint32_t reserved_5:27; }; uint32_t val; -} spi_mem_timing_cali_reg_t; +} spi1_mem_c_timing_cali_reg_t; /** Group: Version register */ @@ -1047,57 +1027,54 @@ typedef union { */ typedef union { struct { - /** date : R/W; bitpos: [27:0]; default: 37786176; + /** date : R/W; bitpos: [27:0]; default: 38801712; * Version control register */ uint32_t date:28; uint32_t reserved_28:4; }; uint32_t val; -} spi_mem_date_reg_t; +} spi1_mem_c_date_reg_t; typedef struct spi1_mem_c_dev_s { - volatile spi_mem_cmd_reg_t cmd; + volatile spi1_mem_c_cmd_reg_t cmd; volatile uint32_t addr; - volatile spi_mem_ctrl_reg_t ctrl; - volatile spi_mem_ctrl1_reg_t ctrl1; - volatile spi_mem_ctrl2_reg_t ctrl2; - volatile spi_mem_clock_reg_t clock; - volatile spi_mem_user_reg_t user; - volatile spi_mem_user1_reg_t user1; - volatile spi_mem_user2_reg_t user2; - volatile spi_mem_mosi_dlen_reg_t mosi_dlen; - volatile spi_mem_miso_dlen_reg_t miso_dlen; - volatile spi_mem_rd_status_reg_t rd_status; + volatile spi1_mem_c_ctrl_reg_t ctrl; + volatile spi1_mem_c_ctrl1_reg_t ctrl1; + volatile spi1_mem_c_ctrl2_reg_t ctrl2; + volatile spi1_mem_c_clock_reg_t clock; + volatile spi1_mem_c_user_reg_t user; + volatile spi1_mem_c_user1_reg_t user1; + volatile spi1_mem_c_user2_reg_t user2; + volatile spi1_mem_c_mosi_dlen_reg_t mosi_dlen; + volatile spi1_mem_c_miso_dlen_reg_t miso_dlen; + volatile spi1_mem_c_rd_status_reg_t rd_status; uint32_t reserved_030; - volatile spi_mem_misc_reg_t misc; - volatile spi_mem_tx_crc_reg_t tx_crc; - volatile spi_mem_cache_fctrl_reg_t cache_fctrl; + volatile spi1_mem_c_misc_reg_t misc; + volatile spi1_mem_c_tx_crc_reg_t tx_crc; + volatile spi1_mem_c_cache_fctrl_reg_t cache_fctrl; uint32_t reserved_040[6]; volatile uint32_t data_buf[16]; - volatile spi_mem_flash_waiti_ctrl_reg_t flash_waiti_ctrl; - volatile spi_mem_flash_sus_ctrl_reg_t flash_sus_ctrl; - volatile spi_mem_flash_sus_cmd_reg_t flash_sus_cmd; - volatile spi_mem_sus_status_reg_t sus_status; - uint32_t reserved_0a8; - volatile spi_mem_flash_waiti_ctrl1_reg_t flash_waiti_ctrl1; - uint32_t reserved_0b0[4]; - volatile spi_mem_int_ena_reg_t int_ena; - volatile spi_mem_int_clr_reg_t int_clr; - volatile spi_mem_int_raw_reg_t int_raw; - volatile spi_mem_int_st_reg_t int_st; + volatile spi1_mem_c_flash_waiti_ctrl_reg_t flash_waiti_ctrl; + volatile spi1_mem_c_flash_sus_ctrl_reg_t flash_sus_ctrl; + volatile spi1_mem_c_flash_sus_cmd_reg_t flash_sus_cmd; + volatile spi1_mem_c_sus_status_reg_t sus_status; + uint32_t reserved_0a8[6]; + volatile spi1_mem_c_int_ena_reg_t int_ena; + volatile spi1_mem_c_int_clr_reg_t int_clr; + volatile spi1_mem_c_int_raw_reg_t int_raw; + volatile spi1_mem_c_int_st_reg_t int_st; uint32_t reserved_0d0; - volatile spi_mem_ddr_reg_t ddr; + volatile spi1_mem_c_ddr_reg_t ddr; uint32_t reserved_0d8[42]; - volatile spi_mem_timing_cali_reg_t timing_cali; + volatile spi1_mem_c_timing_cali_reg_t timing_cali; uint32_t reserved_184[31]; - volatile spi_mem_clock_gate_reg_t clock_gate; + volatile spi1_mem_c_clock_gate_reg_t clock_gate; uint32_t reserved_204[126]; - volatile spi_mem_date_reg_t date; + volatile spi1_mem_c_date_reg_t date; } spi1_mem_c_dev_t; - #ifndef __cplusplus _Static_assert(sizeof(spi1_mem_c_dev_t) == 0x400, "Invalid size of spi1_mem_c_dev_t structure"); #endif diff --git a/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h b/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h index 47a4b4d14b..5dc83b69bb 100644 --- a/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h +++ b/components/soc/esp32s31/register/soc/spi1_mem_s_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 OR MIT */ @@ -121,7 +121,7 @@ typedef union { uint32_t flash_read:1; }; uint32_t val; -} spi_mem_cmd_reg_t; +} spi1_mem_s_cmd_reg_t; /** Type of addr register * SPI1 address register @@ -135,7 +135,7 @@ typedef union { uint32_t usr_addr_value:32; }; uint32_t val; -} spi_mem_addr_reg_t; +} spi1_mem_s_addr_reg_t; /** Type of user register * SPI1 user register. @@ -201,7 +201,7 @@ typedef union { uint32_t usr_command:1; }; uint32_t val; -} spi_mem_user_reg_t; +} spi1_mem_s_user_reg_t; /** Type of user1 register * SPI1 user1 register. @@ -220,7 +220,7 @@ typedef union { uint32_t usr_addr_bitlen:6; }; uint32_t val; -} spi_mem_user1_reg_t; +} spi1_mem_s_user1_reg_t; /** Type of user2 register * SPI1 user2 register. @@ -238,7 +238,7 @@ typedef union { uint32_t usr_command_bitlen:4; }; uint32_t val; -} spi_mem_user2_reg_t; +} spi1_mem_s_user2_reg_t; /** Group: Control and configuration registers */ @@ -301,7 +301,7 @@ typedef union { */ uint32_t fread_dual:1; /** resandres : R/W; bitpos: [15]; default: 1; - * The Device ID is read out to SPI_MEM_RD_STATUS register, this bit combine with + * The Device ID is read out to SPI1_MEM_S_RD_STATUS register, this bit combine with * spi_mem_flash_res bit. 1: enable 0: disable. * This field is only for internal debugging purposes. Do not use it in applications. */ @@ -342,7 +342,7 @@ typedef union { uint32_t reserved_25:7; }; uint32_t val; -} spi_mem_ctrl_reg_t; +} spi1_mem_s_ctrl_reg_t; /** Type of ctrl1 register * SPI1 control1 register. @@ -356,19 +356,26 @@ typedef union { */ uint32_t clk_mode:2; /** cs_hold_dly_res : R/W; bitpos: [11:2]; default: 1023; - * After RES/DP/HPM/PES command is sent, SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * - * 128) SPI_CLK cycles. + * After RES/DP/HPM command is sent, SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * + * 512) SPI_CLK cycles. + * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t cs_hold_dly_res:10; - /** cs_hold_dly_per : R/W; bitpos: [21:12]; default: 1023; - * After PER command is sent, SPI1 waits (SPI_MEM_CS_HOLD_DLY_PER[9:0] * 128) SPI_CLK - * cycles. + /** cs_hold_dly_per : R/W; bitpos: [20:12]; default: 511; + * After PER command is sent, SPI1 waits (SPI1_MEM_S_CS_HOLD_DLY_PER[8:0] * 128) + * SPI_CLK cycles. */ - uint32_t cs_hold_dly_per:10; - uint32_t reserved_22:10; + uint32_t cs_hold_dly_per:9; + uint32_t reserved_21:2; + /** cs_hold_dly_per_en : R/W; bitpos: [23]; default: 0; + * 1: use SPI1_MEM_S_CS_HOLD_DLY_PER for per, use SPI1_MEM_S_CS_HOLD_DELAY_RES for + * pes/dp/hpm . 0: use SPI1_MEM_S_CS_HOLD_DELAY_RES for pes/dp/hpm/per . + */ + uint32_t cs_hold_dly_per_en:1; + uint32_t reserved_24:8; }; uint32_t val; -} spi_mem_ctrl1_reg_t; +} spi1_mem_s_ctrl1_reg_t; /** Type of ctrl2 register * SPI1 control2 register. @@ -382,7 +389,7 @@ typedef union { uint32_t sync_reset:1; }; uint32_t val; -} spi_mem_ctrl2_reg_t; +} spi1_mem_s_ctrl2_reg_t; /** Type of clock register * SPI1 clock division control register. @@ -390,16 +397,16 @@ typedef union { typedef union { struct { /** clkcnt_l : R/W; bitpos: [7:0]; default: 3; - * In the master mode it must be equal to SPI_MEM_CLKCNT_N. + * In the master mode it must be equal to SPI1_MEM_S_CLKCNT_N. */ uint32_t clkcnt_l:8; /** clkcnt_h : R/W; bitpos: [15:8]; default: 1; - * In the master mode it must be floor((SPI_MEM_CLKCNT_N+1)/2-1). + * In the master mode it must be floor((SPI1_MEM_S_CLKCNT_N+1)/2-1). */ uint32_t clkcnt_h:8; /** clkcnt_n : R/W; bitpos: [23:16]; default: 3; * In the master mode it is the divider of spi_mem_clk. So spi_mem_clk frequency is - * system/(SPI_MEM_CLKCNT_N+1) + * system/(SPI1_MEM_S_CLKCNT_N+1) */ uint32_t clkcnt_n:8; uint32_t reserved_24:7; @@ -409,7 +416,7 @@ typedef union { uint32_t clk_equ_sysclk:1; }; uint32_t val; -} spi_mem_clock_reg_t; +} spi1_mem_s_clock_reg_t; /** Type of mosi_dlen register * SPI1 send data bit length control register. @@ -423,7 +430,7 @@ typedef union { uint32_t reserved_10:22; }; uint32_t val; -} spi_mem_mosi_dlen_reg_t; +} spi1_mem_s_mosi_dlen_reg_t; /** Type of miso_dlen register * SPI1 receive data bit length control register. @@ -437,7 +444,7 @@ typedef union { uint32_t reserved_10:22; }; uint32_t val; -} spi_mem_miso_dlen_reg_t; +} spi1_mem_s_miso_dlen_reg_t; /** Type of rd_status register * SPI1 status register. @@ -453,20 +460,10 @@ typedef union { * This field is only for internal debugging purposes. Do not use it in applications. */ uint32_t wb_mode:8; - /** wb_mode_bitlen : R/W; bitpos: [26:24]; default: 0; - * Mode bits length for flash fast read mode. - * This field is only for internal debugging purposes. Do not use it in applications. - */ - uint32_t wb_mode_bitlen:3; - /** wb_mode_en : R/W; bitpos: [27]; default: 0; - * Mode bits is valid while this bit is enable. 1: enable 0: disable. - * This field is only for internal debugging purposes. Do not use it in applications. - */ - uint32_t wb_mode_en:1; - uint32_t reserved_28:4; + uint32_t reserved_24:8; }; uint32_t val; -} spi_mem_rd_status_reg_t; +} spi1_mem_s_rd_status_reg_t; /** Type of misc register * SPI1 misc register @@ -495,7 +492,7 @@ typedef union { uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_misc_reg_t; +} spi1_mem_s_misc_reg_t; /** Type of cache_fctrl register * SPI1 bit mode control register. @@ -548,7 +545,7 @@ typedef union { uint32_t reserved_9:23; }; uint32_t val; -} spi_mem_cache_fctrl_reg_t; +} spi1_mem_s_cache_fctrl_reg_t; /** Type of flash_waiti_ctrl register * SPI1 wait idle control register @@ -571,9 +568,9 @@ typedef union { */ uint32_t waiti_addr_en:1; /** waiti_addr_cyclelen : R/W; bitpos: [4:3]; default: 0; - * When SPI_MEM_WAITI_ADDR_EN is set, the cycle length of sent out address is - * (SPI_MEM_WAITI_ADDR_CYCLELEN[1:0] + 1) SPI bus clock cycles. It is not active when - * SPI_MEM_WAITI_ADDR_EN is cleared. + * When SPI1_MEM_S_WAITI_ADDR_EN is set, the cycle length of sent out address is + * (SPI1_MEM_S_WAITI_ADDR_CYCLELEN[1:0] + 1) SPI bus clock cycles. It is not active + * when SPI1_MEM_S_WAITI_ADDR_EN is cleared. */ uint32_t waiti_addr_cyclelen:2; uint32_t reserved_5:4; @@ -591,7 +588,7 @@ typedef union { uint32_t waiti_cmd:16; }; uint32_t val; -} spi_mem_flash_waiti_ctrl_reg_t; +} spi1_mem_s_flash_waiti_ctrl_reg_t; /** Type of flash_sus_ctrl register * SPI1 flash suspend control register @@ -611,13 +608,13 @@ typedef union { */ uint32_t flash_pes:1; /** flash_per_wait_en : R/W; bitpos: [2]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after + * 1: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after * program erase resume command is sent. 0: SPI1 does not wait after program erase * resume command is sent. */ uint32_t flash_per_wait_en:1; /** flash_pes_wait_en : R/W; bitpos: [3]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after + * 1: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4 or *128) SPI_CLK cycles after * program erase suspend command is sent. 0: SPI1 does not wait after program erase * suspend command is sent. */ @@ -635,7 +632,7 @@ typedef union { * The mask value when check SUS/SUS1/SUS2 status bit. If the read status value is * status_in[15:0](only status_in[7:0] is valid when only one byte of data is read * out, status_in[15:0] is valid when two bytes of data are read out), SUS/SUS1/SUS2 = - * status_in[15:0]^ SPI_MEM_PESR_END_MSK[15:0]. + * status_in[15:0]^ SPI1_MEM_S_PESR_END_MSK[15:0]. */ uint32_t pesr_end_msk:16; /** fmem_rd_sus_2b : R/W; bitpos: [22]; default: 0; @@ -654,13 +651,13 @@ typedef union { */ uint32_t pes_end_en:1; /** sus_timeout_cnt : R/W; bitpos: [31:25]; default: 4; - * When SPI1 checks SUS/SUS1/SUS2 bits fail for SPI_MEM_SUS_TIMEOUT_CNT[6:0] times, it - * will be treated as check pass. + * When SPI1 checks SUS/SUS1/SUS2 bits fail for SPI1_MEM_S_SUS_TIMEOUT_CNT[6:0] times, + * it will be treated as check pass. */ uint32_t sus_timeout_cnt:7; }; uint32_t val; -} spi_mem_flash_sus_ctrl_reg_t; +} spi1_mem_s_flash_sus_ctrl_reg_t; /** Type of flash_sus_cmd register * SPI1 flash suspend command register @@ -678,7 +675,7 @@ typedef union { uint32_t wait_pesr_command:16; }; uint32_t val; -} spi_mem_flash_sus_cmd_reg_t; +} spi1_mem_s_flash_sus_cmd_reg_t; /** Type of sus_status register * SPI1 flash suspend status register @@ -690,40 +687,40 @@ typedef union { */ uint32_t flash_sus:1; /** wait_pesr_cmd_2b : R/W; bitpos: [1]; default: 0; - * 1: SPI1 sends out SPI_MEM_WAIT_PESR_COMMAND[15:0] to check SUS/SUS1/SUS2 bit. 0: - * SPI1 sends out SPI_MEM_WAIT_PESR_COMMAND[7:0] to check SUS/SUS1/SUS2 bit. + * 1: SPI1 sends out SPI1_MEM_S_WAIT_PESR_COMMAND[15:0] to check SUS/SUS1/SUS2 bit. 0: + * SPI1 sends out SPI1_MEM_S_WAIT_PESR_COMMAND[7:0] to check SUS/SUS1/SUS2 bit. */ uint32_t wait_pesr_cmd_2b:1; /** flash_hpm_dly_128 : R/W; bitpos: [2]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after HPM - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after HPM command is sent. + * 1: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after HPM + * command is sent. 0: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after HPM command is sent. */ uint32_t flash_hpm_dly_128:1; /** flash_res_dly_128 : R/W; bitpos: [3]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after RES - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after RES command is sent. + * 1: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after RES + * command is sent. 0: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after RES command is sent. */ uint32_t flash_res_dly_128:1; /** flash_dp_dly_128 : R/W; bitpos: [4]; default: 0; - * 1: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after DP - * command is sent. 0: SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles - * after DP command is sent. + * 1: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after DP + * command is sent. 0: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK + * cycles after DP command is sent. */ uint32_t flash_dp_dly_128:1; /** flash_per_dly_128 : R/W; bitpos: [5]; default: 0; - * Valid when SPI_MEM_FLASH_PER_WAIT_EN is 1. 1: SPI1 waits - * (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PER command is sent. 0: - * SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PER command is - * sent. + * Valid when SPI1_MEM_S_FLASH_PER_WAIT_EN is 1. 1: SPI1 waits + * (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PER command is sent. + * 0: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PER + * command is sent. */ uint32_t flash_per_dly_128:1; /** flash_pes_dly_128 : R/W; bitpos: [6]; default: 0; - * Valid when SPI_MEM_FLASH_PES_WAIT_EN is 1. 1: SPI1 waits - * (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PES command is sent. 0: - * SPI1 waits (SPI_MEM_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PES command is - * sent. + * Valid when SPI1_MEM_S_FLASH_PES_WAIT_EN is 1. 1: SPI1 waits + * (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 128) SPI_CLK cycles after PES command is sent. + * 0: SPI1 waits (SPI1_MEM_S_CS_HOLD_DELAY_RES[9:0] * 4) SPI_CLK cycles after PES + * command is sent. */ uint32_t flash_pes_dly_128:1; /** spi0_lock_en : R/W; bitpos: [7]; default: 0; @@ -742,25 +739,7 @@ typedef union { uint32_t flash_per_command:16; }; uint32_t val; -} spi_mem_sus_status_reg_t; - -/** Type of flash_waiti_ctrl1 register - * SPI1 wait idle control register - */ -typedef union { - struct { - /** waiti_idle_delay_time : R/W; bitpos: [9:0]; default: 0; - * SPI1 wait idle gap time configuration. SPI1 slv fsm will count during SPI1 IDLE. - */ - uint32_t waiti_idle_delay_time:10; - /** waiti_idle_delay_time_en : R/W; bitpos: [10]; default: 0; - * Enable SPI1 wait idle gap time count function. 1: Enable. 0: Disable. - */ - uint32_t waiti_idle_delay_time_en:1; - uint32_t reserved_11:21; - }; - uint32_t val; -} spi_mem_flash_waiti_ctrl1_reg_t; +} spi1_mem_s_sus_status_reg_t; /** Type of ddr register * SPI1 DDR control register @@ -798,8 +777,8 @@ typedef union { uint32_t fmem_usr_ddr_dqs_thd:7; /** fmem_ddr_dqs_loop : R/W; bitpos: [21]; default: 0; * 1: Do not need the input of SPI_DQS signal, SPI0 starts to receive data when - * spi0_slv_st is in SPI_MEM_DIN state. It is used when there is no SPI_DQS signal or - * SPI_DQS signal is not stable. 0: SPI0 starts to store data at the positive and + * spi0_slv_st is in SPI1_MEM_S_DIN state. It is used when there is no SPI_DQS signal + * or SPI_DQS signal is not stable. 0: SPI0 starts to store data at the positive and * negative edge of SPI_DQS. */ uint32_t fmem_ddr_dqs_loop:1; @@ -835,7 +814,7 @@ typedef union { uint32_t reserved_31:1; }; uint32_t val; -} spi_mem_ddr_reg_t; +} spi1_mem_s_ddr_reg_t; /** Type of clock_gate register * SPI1 clk_gate register @@ -849,7 +828,7 @@ typedef union { uint32_t reserved_1:31; }; uint32_t val; -} spi_mem_clock_gate_reg_t; +} spi1_mem_s_clock_gate_reg_t; /** Group: Status register */ @@ -864,7 +843,7 @@ typedef union { uint32_t tx_crc_data:32; }; uint32_t val; -} spi_mem_tx_crc_reg_t; +} spi1_mem_s_tx_crc_reg_t; /** Group: Memory data buffer register */ @@ -879,7 +858,7 @@ typedef union { uint32_t buf0:32; }; uint32_t val; -} spi_mem_w0_reg_t; +} spi1_mem_s_w0_reg_t; /** Type of w1 register * SPI1 memory data buffer1 @@ -892,7 +871,7 @@ typedef union { uint32_t buf1:32; }; uint32_t val; -} spi_mem_w1_reg_t; +} spi1_mem_s_w1_reg_t; /** Type of w2 register * SPI1 memory data buffer2 @@ -905,7 +884,7 @@ typedef union { uint32_t buf2:32; }; uint32_t val; -} spi_mem_w2_reg_t; +} spi1_mem_s_w2_reg_t; /** Type of w3 register * SPI1 memory data buffer3 @@ -918,7 +897,7 @@ typedef union { uint32_t buf3:32; }; uint32_t val; -} spi_mem_w3_reg_t; +} spi1_mem_s_w3_reg_t; /** Type of w4 register * SPI1 memory data buffer4 @@ -931,7 +910,7 @@ typedef union { uint32_t buf4:32; }; uint32_t val; -} spi_mem_w4_reg_t; +} spi1_mem_s_w4_reg_t; /** Type of w5 register * SPI1 memory data buffer5 @@ -944,7 +923,7 @@ typedef union { uint32_t buf5:32; }; uint32_t val; -} spi_mem_w5_reg_t; +} spi1_mem_s_w5_reg_t; /** Type of w6 register * SPI1 memory data buffer6 @@ -957,7 +936,7 @@ typedef union { uint32_t buf6:32; }; uint32_t val; -} spi_mem_w6_reg_t; +} spi1_mem_s_w6_reg_t; /** Type of w7 register * SPI1 memory data buffer7 @@ -970,7 +949,7 @@ typedef union { uint32_t buf7:32; }; uint32_t val; -} spi_mem_w7_reg_t; +} spi1_mem_s_w7_reg_t; /** Type of w8 register * SPI1 memory data buffer8 @@ -983,7 +962,7 @@ typedef union { uint32_t buf8:32; }; uint32_t val; -} spi_mem_w8_reg_t; +} spi1_mem_s_w8_reg_t; /** Type of w9 register * SPI1 memory data buffer9 @@ -996,7 +975,7 @@ typedef union { uint32_t buf9:32; }; uint32_t val; -} spi_mem_w9_reg_t; +} spi1_mem_s_w9_reg_t; /** Type of w10 register * SPI1 memory data buffer10 @@ -1009,7 +988,7 @@ typedef union { uint32_t buf10:32; }; uint32_t val; -} spi_mem_w10_reg_t; +} spi1_mem_s_w10_reg_t; /** Type of w11 register * SPI1 memory data buffer11 @@ -1022,7 +1001,7 @@ typedef union { uint32_t buf11:32; }; uint32_t val; -} spi_mem_w11_reg_t; +} spi1_mem_s_w11_reg_t; /** Type of w12 register * SPI1 memory data buffer12 @@ -1035,7 +1014,7 @@ typedef union { uint32_t buf12:32; }; uint32_t val; -} spi_mem_w12_reg_t; +} spi1_mem_s_w12_reg_t; /** Type of w13 register * SPI1 memory data buffer13 @@ -1048,7 +1027,7 @@ typedef union { uint32_t buf13:32; }; uint32_t val; -} spi_mem_w13_reg_t; +} spi1_mem_s_w13_reg_t; /** Type of w14 register * SPI1 memory data buffer14 @@ -1061,7 +1040,7 @@ typedef union { uint32_t buf14:32; }; uint32_t val; -} spi_mem_w14_reg_t; +} spi1_mem_s_w14_reg_t; /** Type of w15 register * SPI1 memory data buffer15 @@ -1074,7 +1053,7 @@ typedef union { uint32_t buf15:32; }; uint32_t val; -} spi_mem_w15_reg_t; +} spi1_mem_s_w15_reg_t; /** Group: Interrupt registers */ @@ -1084,34 +1063,34 @@ typedef union { typedef union { struct { /** per_end_int_ena : R/W; bitpos: [0]; default: 0; - * The enable bit for SPI_MEM_PER_END_INT interrupt. + * The enable bit for SPI1_MEM_S_PER_END_INT interrupt. */ uint32_t per_end_int_ena:1; /** pes_end_int_ena : R/W; bitpos: [1]; default: 0; - * The enable bit for SPI_MEM_PES_END_INT interrupt. + * The enable bit for SPI1_MEM_S_PES_END_INT interrupt. */ uint32_t pes_end_int_ena:1; /** wpe_end_int_ena : R/W; bitpos: [2]; default: 0; - * The enable bit for SPI_MEM_WPE_END_INT interrupt. + * The enable bit for SPI1_MEM_S_WPE_END_INT interrupt. */ uint32_t wpe_end_int_ena:1; /** slv_st_end_int_ena : R/W; bitpos: [3]; default: 0; - * The enable bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The enable bit for SPI1_MEM_S_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_ena:1; /** mst_st_end_int_ena : R/W; bitpos: [4]; default: 0; - * The enable bit for SPI_MEM_MST_ST_END_INT interrupt. + * The enable bit for SPI1_MEM_S_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_ena:1; uint32_t reserved_5:5; /** brown_out_int_ena : R/W; bitpos: [10]; default: 0; - * The enable bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The enable bit for SPI1_MEM_S_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_ena:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_ena_reg_t; +} spi1_mem_s_int_ena_reg_t; /** Type of int_clr register * SPI1 interrupt clear register @@ -1119,34 +1098,34 @@ typedef union { typedef union { struct { /** per_end_int_clr : WT; bitpos: [0]; default: 0; - * The clear bit for SPI_MEM_PER_END_INT interrupt. + * The clear bit for SPI1_MEM_S_PER_END_INT interrupt. */ uint32_t per_end_int_clr:1; /** pes_end_int_clr : WT; bitpos: [1]; default: 0; - * The clear bit for SPI_MEM_PES_END_INT interrupt. + * The clear bit for SPI1_MEM_S_PES_END_INT interrupt. */ uint32_t pes_end_int_clr:1; /** wpe_end_int_clr : WT; bitpos: [2]; default: 0; - * The clear bit for SPI_MEM_WPE_END_INT interrupt. + * The clear bit for SPI1_MEM_S_WPE_END_INT interrupt. */ uint32_t wpe_end_int_clr:1; /** slv_st_end_int_clr : WT; bitpos: [3]; default: 0; - * The clear bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The clear bit for SPI1_MEM_S_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_clr:1; /** mst_st_end_int_clr : WT; bitpos: [4]; default: 0; - * The clear bit for SPI_MEM_MST_ST_END_INT interrupt. + * The clear bit for SPI1_MEM_S_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_clr:1; uint32_t reserved_5:5; /** brown_out_int_clr : WT; bitpos: [10]; default: 0; - * The status bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The status bit for SPI1_MEM_S_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_clr:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_clr_reg_t; +} spi1_mem_s_int_clr_reg_t; /** Type of int_raw register * SPI1 interrupt raw register @@ -1154,34 +1133,34 @@ typedef union { typedef union { struct { /** per_end_int_raw : R/WTC/SS; bitpos: [0]; default: 0; - * The raw bit for SPI_MEM_PER_END_INT interrupt. 1: Triggered when Auto Resume + * The raw bit for SPI1_MEM_S_PER_END_INT interrupt. 1: Triggered when Auto Resume * command (0x7A) is sent and flash is resumed successfully. 0: Others. */ uint32_t per_end_int_raw:1; /** pes_end_int_raw : R/WTC/SS; bitpos: [1]; default: 0; - * The raw bit for SPI_MEM_PES_END_INT interrupt.1: Triggered when Auto Suspend + * The raw bit for SPI1_MEM_S_PES_END_INT interrupt.1: Triggered when Auto Suspend * command (0x75) is sent and flash is suspended successfully. 0: Others. */ uint32_t pes_end_int_raw:1; /** wpe_end_int_raw : R/WTC/SS; bitpos: [2]; default: 0; - * The raw bit for SPI_MEM_WPE_END_INT interrupt. 1: Triggered when WRSR/PP/SE/BE/CE - * is sent and flash is already idle. 0: Others. + * The raw bit for SPI1_MEM_S_WPE_END_INT interrupt. 1: Triggered when + * WRSR/PP/SE/BE/CE is sent and flash is already idle. 0: Others. */ uint32_t wpe_end_int_raw:1; /** slv_st_end_int_raw : R/WTC/SS; bitpos: [3]; default: 0; - * The raw bit for SPI_MEM_SLV_ST_END_INT interrupt. 1: Triggered when spi1_slv_st is - * changed from non idle state to idle state. It means that SPI_CS raises high. 0: + * The raw bit for SPI1_MEM_S_SLV_ST_END_INT interrupt. 1: Triggered when spi1_slv_st + * is changed from non idle state to idle state. It means that SPI_CS raises high. 0: * Others */ uint32_t slv_st_end_int_raw:1; /** mst_st_end_int_raw : R/WTC/SS; bitpos: [4]; default: 0; - * The raw bit for SPI_MEM_MST_ST_END_INT interrupt. 1: Triggered when spi1_mst_st is - * changed from non idle state to idle state. 0: Others. + * The raw bit for SPI1_MEM_S_MST_ST_END_INT interrupt. 1: Triggered when spi1_mst_st + * is changed from non idle state to idle state. 0: Others. */ uint32_t mst_st_end_int_raw:1; uint32_t reserved_5:5; /** brown_out_int_raw : R/WTC/SS; bitpos: [10]; default: 0; - * The raw bit for SPI_MEM_BROWN_OUT_INT interrupt. 1: Triggered condition is that + * The raw bit for SPI1_MEM_S_BROWN_OUT_INT interrupt. 1: Triggered condition is that * chip is losing power and RTC module sends out brown out close flash request to * SPI1. After SPI1 sends out suspend command to flash, this interrupt is triggered * and MSPI returns to idle state. 0: Others. @@ -1190,7 +1169,7 @@ typedef union { uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_raw_reg_t; +} spi1_mem_s_int_raw_reg_t; /** Type of int_st register * SPI1 interrupt status register @@ -1198,34 +1177,34 @@ typedef union { typedef union { struct { /** per_end_int_st : RO; bitpos: [0]; default: 0; - * The status bit for SPI_MEM_PER_END_INT interrupt. + * The status bit for SPI1_MEM_S_PER_END_INT interrupt. */ uint32_t per_end_int_st:1; /** pes_end_int_st : RO; bitpos: [1]; default: 0; - * The status bit for SPI_MEM_PES_END_INT interrupt. + * The status bit for SPI1_MEM_S_PES_END_INT interrupt. */ uint32_t pes_end_int_st:1; /** wpe_end_int_st : RO; bitpos: [2]; default: 0; - * The status bit for SPI_MEM_WPE_END_INT interrupt. + * The status bit for SPI1_MEM_S_WPE_END_INT interrupt. */ uint32_t wpe_end_int_st:1; /** slv_st_end_int_st : RO; bitpos: [3]; default: 0; - * The status bit for SPI_MEM_SLV_ST_END_INT interrupt. + * The status bit for SPI1_MEM_S_SLV_ST_END_INT interrupt. */ uint32_t slv_st_end_int_st:1; /** mst_st_end_int_st : RO; bitpos: [4]; default: 0; - * The status bit for SPI_MEM_MST_ST_END_INT interrupt. + * The status bit for SPI1_MEM_S_MST_ST_END_INT interrupt. */ uint32_t mst_st_end_int_st:1; uint32_t reserved_5:5; /** brown_out_int_st : RO; bitpos: [10]; default: 0; - * The status bit for SPI_MEM_BROWN_OUT_INT interrupt. + * The status bit for SPI1_MEM_S_BROWN_OUT_INT interrupt. */ uint32_t brown_out_int_st:1; uint32_t reserved_11:21; }; uint32_t val; -} spi_mem_int_st_reg_t; +} spi1_mem_s_int_st_reg_t; /** Group: Timing registers */ @@ -1246,7 +1225,7 @@ typedef union { uint32_t reserved_5:27; }; uint32_t val; -} spi_mem_timing_cali_reg_t; +} spi1_mem_s_timing_cali_reg_t; /** Group: Version register */ @@ -1255,71 +1234,70 @@ typedef union { */ typedef union { struct { - /** date : R/W; bitpos: [27:0]; default: 37786176; + /** date : R/W; bitpos: [27:0]; default: 38801712; * Version control register */ uint32_t date:28; uint32_t reserved_28:4; }; uint32_t val; -} spi_mem_date_reg_t; +} spi1_mem_s_date_reg_t; -typedef struct { - volatile spi_mem_cmd_reg_t cmd; - volatile spi_mem_addr_reg_t addr; - volatile spi_mem_ctrl_reg_t ctrl; - volatile spi_mem_ctrl1_reg_t ctrl1; - volatile spi_mem_ctrl2_reg_t ctrl2; - volatile spi_mem_clock_reg_t clock; - volatile spi_mem_user_reg_t user; - volatile spi_mem_user1_reg_t user1; - volatile spi_mem_user2_reg_t user2; - volatile spi_mem_mosi_dlen_reg_t mosi_dlen; - volatile spi_mem_miso_dlen_reg_t miso_dlen; - volatile spi_mem_rd_status_reg_t rd_status; +typedef struct spi1_mem_s_dev_s { + volatile spi1_mem_s_cmd_reg_t cmd; + volatile spi1_mem_s_addr_reg_t addr; + volatile spi1_mem_s_ctrl_reg_t ctrl; + volatile spi1_mem_s_ctrl1_reg_t ctrl1; + volatile spi1_mem_s_ctrl2_reg_t ctrl2; + volatile spi1_mem_s_clock_reg_t clock; + volatile spi1_mem_s_user_reg_t user; + volatile spi1_mem_s_user1_reg_t user1; + volatile spi1_mem_s_user2_reg_t user2; + volatile spi1_mem_s_mosi_dlen_reg_t mosi_dlen; + volatile spi1_mem_s_miso_dlen_reg_t miso_dlen; + volatile spi1_mem_s_rd_status_reg_t rd_status; uint32_t reserved_030; - volatile spi_mem_misc_reg_t misc; - volatile spi_mem_tx_crc_reg_t tx_crc; - volatile spi_mem_cache_fctrl_reg_t cache_fctrl; + volatile spi1_mem_s_misc_reg_t misc; + volatile spi1_mem_s_tx_crc_reg_t tx_crc; + volatile spi1_mem_s_cache_fctrl_reg_t cache_fctrl; uint32_t reserved_040[6]; - volatile spi_mem_w0_reg_t w0; - volatile spi_mem_w1_reg_t w1; - volatile spi_mem_w2_reg_t w2; - volatile spi_mem_w3_reg_t w3; - volatile spi_mem_w4_reg_t w4; - volatile spi_mem_w5_reg_t w5; - volatile spi_mem_w6_reg_t w6; - volatile spi_mem_w7_reg_t w7; - volatile spi_mem_w8_reg_t w8; - volatile spi_mem_w9_reg_t w9; - volatile spi_mem_w10_reg_t w10; - volatile spi_mem_w11_reg_t w11; - volatile spi_mem_w12_reg_t w12; - volatile spi_mem_w13_reg_t w13; - volatile spi_mem_w14_reg_t w14; - volatile spi_mem_w15_reg_t w15; - volatile spi_mem_flash_waiti_ctrl_reg_t flash_waiti_ctrl; - volatile spi_mem_flash_sus_ctrl_reg_t flash_sus_ctrl; - volatile spi_mem_flash_sus_cmd_reg_t flash_sus_cmd; - volatile spi_mem_sus_status_reg_t sus_status; - uint32_t reserved_0a8; - volatile spi_mem_flash_waiti_ctrl1_reg_t flash_waiti_ctrl1; - uint32_t reserved_0b0[4]; - volatile spi_mem_int_ena_reg_t int_ena; - volatile spi_mem_int_clr_reg_t int_clr; - volatile spi_mem_int_raw_reg_t int_raw; - volatile spi_mem_int_st_reg_t int_st; + volatile spi1_mem_s_w0_reg_t w0; + volatile spi1_mem_s_w1_reg_t w1; + volatile spi1_mem_s_w2_reg_t w2; + volatile spi1_mem_s_w3_reg_t w3; + volatile spi1_mem_s_w4_reg_t w4; + volatile spi1_mem_s_w5_reg_t w5; + volatile spi1_mem_s_w6_reg_t w6; + volatile spi1_mem_s_w7_reg_t w7; + volatile spi1_mem_s_w8_reg_t w8; + volatile spi1_mem_s_w9_reg_t w9; + volatile spi1_mem_s_w10_reg_t w10; + volatile spi1_mem_s_w11_reg_t w11; + volatile spi1_mem_s_w12_reg_t w12; + volatile spi1_mem_s_w13_reg_t w13; + volatile spi1_mem_s_w14_reg_t w14; + volatile spi1_mem_s_w15_reg_t w15; + volatile spi1_mem_s_flash_waiti_ctrl_reg_t flash_waiti_ctrl; + volatile spi1_mem_s_flash_sus_ctrl_reg_t flash_sus_ctrl; + volatile spi1_mem_s_flash_sus_cmd_reg_t flash_sus_cmd; + volatile spi1_mem_s_sus_status_reg_t sus_status; + uint32_t reserved_0a8[6]; + volatile spi1_mem_s_int_ena_reg_t int_ena; + volatile spi1_mem_s_int_clr_reg_t int_clr; + volatile spi1_mem_s_int_raw_reg_t int_raw; + volatile spi1_mem_s_int_st_reg_t int_st; uint32_t reserved_0d0; - volatile spi_mem_ddr_reg_t ddr; + volatile spi1_mem_s_ddr_reg_t ddr; uint32_t reserved_0d8[42]; - volatile spi_mem_timing_cali_reg_t timing_cali; + volatile spi1_mem_s_timing_cali_reg_t timing_cali; uint32_t reserved_184[31]; - volatile spi_mem_clock_gate_reg_t clock_gate; + volatile spi1_mem_s_clock_gate_reg_t clock_gate; uint32_t reserved_204[126]; - volatile spi_mem_date_reg_t date; + volatile spi1_mem_s_date_reg_t date; } spi1_mem_s_dev_t; +extern spi1_mem_s_dev_t SPIMEM3; #ifndef __cplusplus _Static_assert(sizeof(spi1_mem_s_dev_t) == 0x400, "Invalid size of spi1_mem_s_dev_t structure"); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 4cf2e9cee9..e0601f9787 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -205,7 +205,7 @@ void IRAM_ATTR spi_flash_set_rom_required_regs(void) #endif } -#if CONFIG_SPIRAM_MODE_OCT +#if CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM_MODE_OCT // This function will only be called when Octal PSRAM enabled. void IRAM_ATTR spi_flash_set_vendor_required_regs(void) { diff --git a/examples/system/xip_from_psram/README.md b/examples/system/xip_from_psram/README.md index 229381de18..9d14aa67e1 100644 --- a/examples/system/xip_from_psram/README.md +++ b/examples/system/xip_from_psram/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C61 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 | +| ----------------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- | # XIP (Execute-In-Place) From PSRAM Example From 4bea0ccb22de76953201811611079d27733eea80 Mon Sep 17 00:00:00 2001 From: armando Date: Thu, 26 Mar 2026 17:19:25 +0800 Subject: [PATCH 2/2] fix(cache): fixed cache sys clk not on issue --- .../src/esp32s31/bootloader_esp32s31.c | 8 -------- .../mspi_timing_tuning/mspi_timing_tuning.c | 16 +++++++++++++-- .../include/esp_private/mspi_timing_by_dqs.h | 20 +------------------ .../tuning_scheme_impl/mspi_timing_by_dqs.c | 10 ---------- components/hal/cache_hal.c | 2 ++ components/hal/esp32c2/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32c3/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32c5/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32c6/include/hal/cache_ll.h | 10 ++++++++++ .../hal/esp32c61/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32h2/include/hal/cache_ll.h | 9 +++++++++ .../hal/esp32h21/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32h4/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32p4/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32s2/include/hal/cache_ll.h | 9 +++++++++ components/hal/esp32s3/include/hal/cache_ll.h | 9 +++++++++ .../hal/esp32s31/include/hal/cache_ll.h | 13 ++++++++++++ 17 files changed, 130 insertions(+), 39 deletions(-) diff --git a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c index 1848300112..3771709893 100644 --- a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c +++ b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c @@ -23,7 +23,6 @@ #include "soc/rtc_wdt_reg.h" #include "hal/rwdt_ll.h" #endif -#include "soc/hp_sys_clkrst_reg.h" #include "soc/pmu_reg.h" #include "hal/regi2c_ctrl_ll.h" #include "hal/modem_lpcon_ll.h" @@ -32,13 +31,6 @@ ESP_LOG_ATTR_TAG(TAG, "boot.esp32s31"); static inline void bootloader_hardware_init(void) { - // IDF-15507: Work around ESP32-S31 cache/MSPI issues by keeping the cache path clocks ungated. - REG_SET_BIT(HP_SYS_CLKRST_CACHE_CTRL0_REG, - HP_SYS_CLKRST_REG_CPU_ACACHE_CPU_CLK_FORCE_ON | - HP_SYS_CLKRST_REG_ROM_ACACHE_MEM_CLK_FORCE_ON | - HP_SYS_CLKRST_REG_CPU_CACHE_CPU_CLK_FORCE_ON | - HP_SYS_CLKRST_REG_MSPI_CACHE_SYS_CLK_FORCE_ON); - /* Disable RF pll by default */ REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_RF_CIRCUIT, 0xFFFF); diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c b/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c index f6a7cc95a5..f73596385d 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/mspi_timing_tuning.c @@ -245,9 +245,9 @@ static void s_sweep_for_success_sample_points(uint8_t *reference_data, void *con } } - ESP_DRAM_LOGW(TAG, "test nums: %" PRIu32 ", test result: [id][good/bad][good_times]:", s_tuning_cfg_drv.sweep_test_nums); + ESP_DRAM_LOGD(TAG, "test nums: %" PRIu32 ", test result: [id][good/bad][good_times]:", s_tuning_cfg_drv.sweep_test_nums); for (config_idx = 0; config_idx < timing_config->available_config_num; config_idx++) { - ESP_DRAM_LOGW(TAG, "[%"PRIu32"][%s][%" PRIu32 "] ", config_idx, out_array[config_idx] == s_tuning_cfg_drv.sweep_test_nums ? "good" : "bad", out_array[config_idx]); + ESP_DRAM_LOGD(TAG, "[%"PRIu32"][%s][%" PRIu32 "] ", config_idx, out_array[config_idx] == s_tuning_cfg_drv.sweep_test_nums ? "good" : "bad", out_array[config_idx]); } } @@ -481,6 +481,18 @@ void mspi_timing_psram_tuning(void) /*------------------------------------------------------------------------------ * APIs to make SPI0 (and SPI1) FLASH work for high/low freq *----------------------------------------------------------------------------*/ +void __attribute__((weak)) mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi) +{ + (void)control_both_mspi; + //for compatibility, will be replaced by the actual implementation once flash timing tuning is ready +} + +void __attribute__((weak)) mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi) +{ + (void)control_both_mspi; + //for compatibility, will be replaced by the actual implementation once flash timing tuning is ready +} + uint32_t mspi_timing_get_psram_low_speed_freq_mhz(void) { return 20; diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h index aa73031da9..da104226e3 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -157,24 +157,6 @@ void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi); */ void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi); -/** - * @brief Set Flash timing tuning settings - * - * This is used when the system is going to high speed mode / MSPI needs to be run in high speed - * - * @param[in] control_both_mspi Control MSPI1 as well - */ -void mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi); - -/** - * @brief Clear Flash timing tuning settings - * - * This is used when the system is going into low speed mode / MSPI doesn't need to be run in high speed - * - * @param[in] control_both_mspi Control MSPI1 as well - */ -void mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi); - #endif //#if SOC_MEMSPI_TIMING_TUNING_BY_DQS #ifdef __cplusplus diff --git a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c index 134d56afcb..ce0acc8f55 100644 --- a/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c +++ b/components/esp_hw_support/mspi/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c @@ -240,13 +240,3 @@ void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi) } } } - -void mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi) -{ - //for compatibility -} - -void mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi) -{ - //for compatibility -} diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index b325c6b358..7f8d81e567 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -81,6 +81,8 @@ void cache_hal_init(const cache_hal_config_t *config) { s_cache_hal_init_ctx(); + cache_ll_clk_init(); + if (CACHE_LL_LEVEL_EXT_MEM == 1) { cache_ll_enable_cache(1, CACHE_TYPE_ALL, CACHE_LL_ID_ALL, ctx.l1.i_autoload_en, ctx.l1.d_autoload_en); } else if (CACHE_LL_LEVEL_EXT_MEM == 2) { diff --git a/components/hal/esp32c2/include/hal/cache_ll.h b/components/hal/esp32c2/include/hal/cache_ll.h index b5c99596be..4e2ccc8135 100644 --- a/components/hal/esp32c2/include/hal/cache_ll.h +++ b/components/hal/esp32c2/include/hal/cache_ll.h @@ -53,6 +53,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32c3/include/hal/cache_ll.h b/components/hal/esp32c3/include/hal/cache_ll.h index 7a154ab6ad..794eef2bc0 100644 --- a/components/hal/esp32c3/include/hal/cache_ll.h +++ b/components/hal/esp32c3/include/hal/cache_ll.h @@ -52,6 +52,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32c5/include/hal/cache_ll.h b/components/hal/esp32c5/include/hal/cache_ll.h index 35ee12189e..2259404f83 100644 --- a/components/hal/esp32c5/include/hal/cache_ll.h +++ b/components/hal/esp32c5/include/hal/cache_ll.h @@ -43,6 +43,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32c6/include/hal/cache_ll.h b/components/hal/esp32c6/include/hal/cache_ll.h index 49c8491a79..889222d4a6 100644 --- a/components/hal/esp32c6/include/hal/cache_ll.h +++ b/components/hal/esp32c6/include/hal/cache_ll.h @@ -1,3 +1,4 @@ + /* * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * @@ -42,6 +43,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32c61/include/hal/cache_ll.h b/components/hal/esp32c61/include/hal/cache_ll.h index 794080f651..cdc56f6098 100644 --- a/components/hal/esp32c61/include/hal/cache_ll.h +++ b/components/hal/esp32c61/include/hal/cache_ll.h @@ -42,6 +42,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32h2/include/hal/cache_ll.h b/components/hal/esp32h2/include/hal/cache_ll.h index bd46e1a080..2fc06873a7 100644 --- a/components/hal/esp32h2/include/hal/cache_ll.h +++ b/components/hal/esp32h2/include/hal/cache_ll.h @@ -42,6 +42,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32h21/include/hal/cache_ll.h b/components/hal/esp32h21/include/hal/cache_ll.h index 43bb39c9c0..eb057060e0 100644 --- a/components/hal/esp32h21/include/hal/cache_ll.h +++ b/components/hal/esp32h21/include/hal/cache_ll.h @@ -43,6 +43,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if Cache auto preload is enabled or not. * diff --git a/components/hal/esp32h4/include/hal/cache_ll.h b/components/hal/esp32h4/include/hal/cache_ll.h index 91f1d7c7c5..45eef992f8 100644 --- a/components/hal/esp32h4/include/hal/cache_ll.h +++ b/components/hal/esp32h4/include/hal/cache_ll.h @@ -43,6 +43,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if L1 ICache autoload is enabled or not * diff --git a/components/hal/esp32p4/include/hal/cache_ll.h b/components/hal/esp32p4/include/hal/cache_ll.h index cd17ad9a46..81e32032f5 100644 --- a/components/hal/esp32p4/include/hal/cache_ll.h +++ b/components/hal/esp32p4/include/hal/cache_ll.h @@ -63,6 +63,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /*------------------------------------------------------------------------------ * Autoload *----------------------------------------------------------------------------*/ diff --git a/components/hal/esp32s2/include/hal/cache_ll.h b/components/hal/esp32s2/include/hal/cache_ll.h index 3186ff744e..b5738e0674 100644 --- a/components/hal/esp32s2/include/hal/cache_ll.h +++ b/components/hal/esp32s2/include/hal/cache_ll.h @@ -40,6 +40,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if ICache auto preload is enabled or not * diff --git a/components/hal/esp32s3/include/hal/cache_ll.h b/components/hal/esp32s3/include/hal/cache_ll.h index 75b9a7a8bd..910e984014 100644 --- a/components/hal/esp32s3/include/hal/cache_ll.h +++ b/components/hal/esp32s3/include/hal/cache_ll.h @@ -55,6 +55,15 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + //for compatibility +} + /** * @brief Check if ICache auto preload is enabled or not * diff --git a/components/hal/esp32s31/include/hal/cache_ll.h b/components/hal/esp32s31/include/hal/cache_ll.h index 489bc28b6b..0c65ca723a 100644 --- a/components/hal/esp32s31/include/hal/cache_ll.h +++ b/components/hal/esp32s31/include/hal/cache_ll.h @@ -15,6 +15,7 @@ #include "hal/cache_types.h" #include "hal/assert.h" #include "esp32s31/rom/cache.h" +#include "soc/hp_sys_clkrst_struct.h" #ifdef __cplusplus extern "C" { @@ -51,6 +52,18 @@ typedef enum { CACHE_LL_PRELOAD_ARBITRARY = 2, } cache_ll_preload_strategy_t; +/** + * @brief Initialize the cache clock + */ +__attribute__((always_inline)) +static inline void cache_ll_clk_init(void) +{ + HP_SYS_CLKRST.cache_ctrl0.reg_cpu_acache_cpu_clk_force_on = 1; + HP_SYS_CLKRST.cache_ctrl0.reg_rom_acache_mem_clk_force_on = 1; + HP_SYS_CLKRST.cache_ctrl0.reg_cpu_cache_cpu_clk_force_on = 1; + HP_SYS_CLKRST.cache_ctrl0.reg_mspi_cache_sys_clk_force_on = 1; +} + /*------------------------------------------------------------------------------ * Autoload *----------------------------------------------------------------------------*/