Explorar el Código

change(psram): atomic set clock and reset

Armando hace 2 años
padre
commit
b75f8561e5

+ 11 - 1
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);

+ 29 - 2
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
  *