Merge branch 'bugfix/esp32c6_eco1_ble_lpclk_main_xtal' into 'master'

support 40 MHz XTAL as BLE low power clock source of esp32c6 eco1

Closes WIFI-5909 and WIFI-6114

See merge request espressif/esp-idf!24235
This commit is contained in:
Jiang Jiang Jian
2023-07-14 16:26:56 +08:00
13 changed files with 249 additions and 4 deletions
@@ -10,9 +10,11 @@
#include <stddef.h>
#include <stdint.h>
#include "esp_err.h"
#include "soc/soc_caps.h"
#include "soc/periph_defs.h"
#include "hal/modem_clock_types.h"
#include "esp_private/esp_pmu.h"
#if SOC_MODEM_CLOCK_IS_INDEPENDENT
#include "hal/modem_clock_hal.h"
@@ -77,6 +79,32 @@ void modem_clock_module_mac_reset(periph_module_t module);
*/
void modem_clock_domain_pmu_state_icg_map_init(void);
#if SOC_PMU_SUPPORTED
/**
* @brief Enable modem clock domain clock gate to gate it's output
*
* @param domain modem module clock domain
* @param mode PMU HP system ACTIVE, MODEM and SLEEP state
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if the argument value are not correct
*/
esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode);
/**
* @brief Disable modem clock domain clock gate to ungate it's output
*
* @param domain modem module clock domain
* @param mode PMU HP system ACTIVE, MODEM and SLEEP state
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if the argument value are not correct
*/
esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode);
#endif
/**
* @brief Select the modem module lowpower clock source and configure the clock divider
*
@@ -249,6 +249,15 @@ bool pmu_sleep_finish(void);
*/
void pmu_init(void);
/**
* @brief Enable or disable system clock in PMU HP sleep state
*
* This API only used for fix BLE 40 MHz low power clock source issue
*
* @param enable true to enable, false to disable
*/
void pmu_sleep_enable_hp_sleep_sysclk(bool enable);
#endif //#if SOC_PMU_SUPPORTED
@@ -108,6 +108,8 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries);
* or false for restore to register from memory
*/
void sleep_retention_do_extra_retention(bool backup_or_restore);
void sleep_retention_module_deinit(void);
#endif
/**
+55 -4
View File
@@ -16,6 +16,7 @@
#include "esp_private/esp_modem_clock.h"
#include "esp_private/esp_pmu.h"
#include "esp_sleep.h"
#include "hal/efuse_hal.h"
// Please define the frequently called modules in the low bit,
// which will improve the execution efficiency
@@ -180,6 +181,38 @@ void modem_clock_domain_pmu_state_icg_map_init(void)
{
modem_clock_domain_power_state_icg_map_init(MODEM_CLOCK_instance());
}
esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode)
{
if (domain >= MODEM_CLOCK_DOMAIN_MAX || domain < MODEM_CLOCK_DOMAIN_MODEM_APB) {
return ESP_ERR_INVALID_ARG;
}
if (mode > PMU_HP_ICG_MODEM_CODE_ACTIVE || mode < PMU_HP_ICG_MODEM_CODE_SLEEP) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain);
modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code & ~BIT(mode)));
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
return ESP_OK;
}
esp_err_t modem_clock_domain_clk_gate_disable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode)
{
if (domain >= MODEM_CLOCK_DOMAIN_MAX || domain < MODEM_CLOCK_DOMAIN_MODEM_APB) {
return ESP_ERR_INVALID_ARG;
}
if (mode > PMU_HP_ICG_MODEM_CODE_ACTIVE || mode < PMU_HP_ICG_MODEM_CODE_SLEEP) {
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain);
modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, (code | BIT(mode)));
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
return ESP_OK;
}
#endif // #if SOC_PM_SUPPORT_PMU_MODEM_STATE
static void IRAM_ATTR modem_clock_device_enable(modem_clock_context_t *ctx, uint32_t dev_map)
@@ -292,7 +325,7 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
modem_clock_hal_deselect_all_wifi_lpclk_source(MODEM_CLOCK_instance()->hal);
modem_clock_hal_select_wifi_lpclk_source(MODEM_CLOCK_instance()->hal, src);
modem_lpcon_ll_set_wifi_lpclk_divisor_value(MODEM_CLOCK_instance()->hal->lpcon_dev, divider);
modem_lpcon_ll_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal->lpcon_dev, true);
modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true);
break;
#endif // SOC_WIFI_SUPPORTED
@@ -302,6 +335,15 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, src);
modem_clock_hal_set_ble_rtc_timer_divisor_value(MODEM_CLOCK_instance()->hal, divider);
modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true);
#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
if (efuse_hal_chip_revision() != 0) {
if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
pmu_sleep_enable_hp_sleep_sysclk(true);
}
modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true);
modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP);
}
#endif
break;
#endif // SOC_BT_SUPPORTED
@@ -340,12 +382,14 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
{
assert(IS_MODEM_MODULE(module));
portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID;
switch (module)
{
#if SOC_WIFI_SUPPORTED
case PERIPH_WIFI_MODULE:
modem_clock_hal_deselect_all_wifi_lpclk_source(MODEM_CLOCK_instance()->hal);
modem_lpcon_ll_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal->lpcon_dev, false);
modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false);
break;
#endif // SOC_WIFI_SUPPORTED
@@ -353,6 +397,15 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
case PERIPH_BT_MODULE:
modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal);
modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, false);
#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND
if (efuse_hal_chip_revision() != 0) {
if (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
pmu_sleep_enable_hp_sleep_sysclk(false);
}
modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false);
modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFI, PMU_HP_ICG_MODEM_CODE_SLEEP);
}
#endif
break;
#endif // SOC_BT_SUPPORTED
case PERIPH_COEX_MODULE:
@@ -362,8 +415,6 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
default:
break;
}
modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID;
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \
@@ -294,3 +294,8 @@ bool pmu_sleep_finish(void)
{
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
}
void pmu_sleep_enable_hp_sleep_sysclk(bool enable)
{
pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable);
}
@@ -528,6 +528,15 @@ void sleep_retention_do_extra_retention(bool backup_or_restore)
_lock_release_recursive(&s_retention.lock);
assert(refs >= 0 && refs <= cnt_modules);
}
void sleep_retention_module_deinit(void)
{
_lock_acquire_recursive(&s_retention.lock);
if (s_retention.extra_refs) {
s_retention.extra_refs--;
}
_lock_release_recursive(&s_retention.lock);
}
#endif
#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG