diff --git a/components/esp_psram/device/esp_psram_impl_ap_hex.c b/components/esp_psram/device/esp_psram_impl_ap_hex.c index eae11e6363..6f0eb248e6 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_hex.c +++ b/components/esp_psram/device/esp_psram_impl_ap_hex.c @@ -8,10 +8,15 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_log.h" +#include "esp_private/periph_ctrl.h" #include "../esp_psram_impl.h" #include "rom/opi_flash.h" #include "hal/psram_ctrlr_ll.h" +// Reset and Clock Control registers are mixing with other peripherals, so we need to use a critical section +#define PSRAM_RCC_ATOMIC() PERIPH_RCC_ATOMIC() + + #define AP_HEX_PSRAM_SYNC_READ 0x0000 #define AP_HEX_PSRAM_SYNC_WRITE 0x8080 #define AP_HEX_PSRAM_BURST_READ 0x2020 @@ -324,12 +329,17 @@ static void s_configure_psram_ecc(void) esp_err_t esp_psram_impl_enable(void) { + PSRAM_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_XTAL); + } + s_set_psram_cs_timing(); #if CONFIG_SPIRAM_ECC_ENABLE s_configure_psram_ecc(); #endif //enter MSPI slow mode to init PSRAM device registers - psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL); psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, 2); psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true); psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true); diff --git a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h index 4f0757f00d..3303ce81e2 100644 --- a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h @@ -274,7 +274,6 @@ static inline void psram_ctrlr_ll_enable_rd_splice(uint32_t mspi_id, bool en) SPIMEM2.mem_ctrl1.mem_ar_splice_en = en; } - /** * @brief Enable PSRAM module clock * @@ -285,9 +284,32 @@ __attribute__((always_inline)) static inline void psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en) { (void)mspi_id; - HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_pll_clk_en = en; + HP_SYS_CLKRST.soc_clk_ctrl0.reg_psram_sys_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(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_enable_module_clock(__VA_ARGS__) + +/** + * @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) +{ + (void)mspi_id; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_axi = 1; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_axi = 0; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_apb = 1; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_dual_mspi_apb = 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(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_reset_module_clock(__VA_ARGS__) + /** * @brief Select PSRAM clock source * @@ -317,9 +339,14 @@ static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph break; } + HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_pll_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.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(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_select_clk_source(__VA_ARGS__) + /** * @brief Set PSRAM core clock *