ソースを参照

fix(adc): power settings not taking into effect on C6

gaoxu 2 年 前
コミット
817036f46f

+ 7 - 0
components/esp_hw_support/include/esp_private/esp_modem_clock.h

@@ -124,6 +124,13 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module);
  */
 void modem_clock_wifi_mac_reset(void);
 
+/**
+ * @brief Enable clock registers which shared by both modem and ADC. Need a ref count to enable/disable them
+ *
+ * @param enable true: enable; false: disable
+ */
+void modem_clock_shared_enable(bool enable);
+
 #ifdef __cplusplus
 }
 #endif

+ 27 - 0
components/esp_hw_support/modem_clock.c

@@ -53,6 +53,9 @@ typedef struct modem_clock_context {
     modem_clock_lpclk_src_t lpclk_src[PERIPH_MODEM_MODULE_NUM];
 } modem_clock_context_t;
 
+extern portMUX_TYPE rtc_spinlock;
+
+static int modem_clock_apb_80m_cnt;
 
 #if SOC_WIFI_SUPPORTED
 static void IRAM_ATTR modem_clock_wifi_mac_configure(modem_clock_context_t *ctx, bool enable)
@@ -102,7 +105,31 @@ static void IRAM_ATTR modem_clock_coex_configure(modem_clock_context_t *ctx, boo
 static void IRAM_ATTR modem_clock_fe_configure(modem_clock_context_t *ctx, bool enable)
 {
     modem_clock_hal_enable_fe_clock(ctx->hal, enable);
+    modem_clock_shared_enable(enable);
+}
+
+#if SOC_MODEM_CLOCK_IS_INDEPENDENT
+void modem_clock_shared_enable(bool enable)
+{
+    if(enable) {
+        portENTER_CRITICAL_SAFE(&rtc_spinlock);
+        modem_clock_apb_80m_cnt++;
+        if (modem_clock_apb_80m_cnt == 1) {
+            modem_clock_hal_enable_shared_clock(true);
+        }
+        portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+    } else {
+        portENTER_CRITICAL_SAFE(&rtc_spinlock);
+        modem_clock_apb_80m_cnt--;
+        if (modem_clock_apb_80m_cnt == 0) {
+            modem_clock_hal_enable_shared_clock(false);
+        } else if (modem_clock_apb_80m_cnt < 0) {
+            abort();
+        }
+        portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+    }
 }
+#endif // SOC_MODEM_CLOCK_IS_INDEPENDENT
 
 static void IRAM_ATTR modem_clock_i2c_master_configure(modem_clock_context_t *ctx, bool enable)
 {

+ 3 - 0
components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c

@@ -18,6 +18,7 @@
 #include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_private/sar_periph_ctrl.h"
+#include "esp_private/esp_modem_clock.h"
 #include "hal/sar_ctrl_ll.h"
 
 static const char *TAG = "sar_periph_ctrl";
@@ -55,6 +56,7 @@ static int s_pwdet_power_on_cnt;
 
 static void s_sar_power_acquire(void)
 {
+    modem_clock_shared_enable(true);
     portENTER_CRITICAL_SAFE(&rtc_spinlock);
     s_pwdet_power_on_cnt++;
     if (s_pwdet_power_on_cnt == 1) {
@@ -75,6 +77,7 @@ static void s_sar_power_release(void)
         sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM);
     }
     portEXIT_CRITICAL_SAFE(&rtc_spinlock);
+    modem_clock_shared_enable(false);
 }
 
 

+ 6 - 2
components/hal/esp32c6/modem_clock_hal.c

@@ -104,13 +104,17 @@ uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *
 void IRAM_ATTR modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable)
 {
     if (enable) {
-        modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable);
         modem_syscon_ll_enable_fe_cal_160m_clock(hal->syscon_dev, enable);
         modem_syscon_ll_enable_fe_160m_clock(hal->syscon_dev, enable);
-        modem_syscon_ll_enable_fe_80m_clock(hal->syscon_dev, enable);
     }
 }
 
+void IRAM_ATTR modem_clock_hal_enable_shared_clock(bool enable)
+{
+    modem_syscon_ll_enable_fe_apb_clock(&MODEM_SYSCON, enable);
+    modem_syscon_ll_enable_fe_80m_clock(&MODEM_SYSCON, enable);
+}
+
 void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t  divider)
 {
     modem_lpcon_ll_set_ble_rtc_timer_divisor_value(hal->lpcon_dev, divider);

+ 5 - 1
components/hal/esp32h2/modem_clock_hal.c

@@ -24,11 +24,15 @@ void IRAM_ATTR modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, b
     modem_lpcon_ll_enable_fe_mem_clock(hal->lpcon_dev, enable);
     modem_syscon_ll_enable_fe_sdm_clock(hal->syscon_dev, enable);
     modem_syscon_ll_enable_fe_adc_clock(hal->syscon_dev, enable);
-    modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable);
     modem_syscon_ll_enable_fe_32m_clock(hal->syscon_dev, enable);
     modem_syscon_ll_enable_fe_16m_clock(hal->syscon_dev, enable);
 }
 
+void IRAM_ATTR modem_clock_hal_enable_shared_clock(bool enable)
+{
+    modem_syscon_ll_enable_fe_apb_clock(&MODEM_SYSCON, enable);
+}
+
 void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t divider)
 {
     lp_clkrst_ll_set_ble_rtc_timer_divisor_value(&LP_CLKRST, divider);

+ 1 - 0
components/hal/include/hal/modem_clock_hal.h

@@ -29,6 +29,7 @@ uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *
 #endif
 
 void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable);
+void modem_clock_hal_enable_shared_clock(bool enable);
 
 #if SOC_BT_SUPPORTED
 void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t divider);