mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 10:40:47 +03:00
fix(driver): fix drivers clock management
This commit is contained in:
@@ -66,6 +66,7 @@ typedef struct dvp_platform {
|
||||
|
||||
static dvp_platform_t s_platform;
|
||||
static const char *TAG = "dvp_cam";
|
||||
static soc_module_clk_t s_dvp_clk_src[CAP_DVP_PERIPH_NUM];
|
||||
|
||||
/**
|
||||
* @brief Claim DVP controller
|
||||
@@ -346,6 +347,11 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
|
||||
esp_rom_gpio_connect_out_signal(pin->xclk_io, cam_periph_signals.buses[ctlr_id].clk_sig, false, false);
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
// PLL 120M was selected in esp_perip_clk_init on esp32s31.
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, true));
|
||||
#endif
|
||||
|
||||
PERIPH_RCC_ACQUIRE_ATOMIC(cam_periph_signals.buses[ctlr_id].module, ref_count) {
|
||||
if (ref_count == 0) {
|
||||
cam_ll_enable_bus_clock(ctlr_id, true);
|
||||
@@ -354,6 +360,7 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true));
|
||||
s_dvp_clk_src[ctlr_id] = (soc_module_clk_t)clk_src;
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
cam_ll_enable_clk(ctlr_id, true);
|
||||
cam_ll_select_clk_src(ctlr_id, clk_src);
|
||||
@@ -458,6 +465,15 @@ esp_err_t esp_cam_ctlr_dvp_deinit(int ctlr_id)
|
||||
}
|
||||
}
|
||||
|
||||
if (s_dvp_clk_src[ctlr_id]) {
|
||||
esp_clk_tree_enable_src(s_dvp_clk_src[ctlr_id], false);
|
||||
s_dvp_clk_src[ctlr_id] = 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false);
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -18,7 +18,13 @@
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
|
||||
static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
|
||||
#if CONFIG_GPTIMER_ISR_CACHE_SAFE
|
||||
#define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define TEST_ALARM_CALLBACK_ATTR
|
||||
#endif // CONFIG_GPTIMER_ISR_CACHE_SAFE
|
||||
|
||||
TEST_ALARM_CALLBACK_ATTR static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
|
||||
{
|
||||
TaskHandle_t task_handle = (TaskHandle_t)user_data;
|
||||
BaseType_t high_task_wakeup;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "esp_private/etm_interface.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "esp_private/critical_section.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
|
||||
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||
|
||||
@@ -63,6 +64,9 @@ struct esp_etm_channel_t {
|
||||
_Atomic etm_chan_fsm_t fsm; // record ETM channel's driver state
|
||||
esp_etm_event_handle_t event; // which event is connect to the channel
|
||||
esp_etm_task_handle_t task; // which task is connect to the channel
|
||||
#if ETM_LL_SUPPORT(CLOCK_SRC)
|
||||
etm_clock_source_t clk_src; // function clock source enabled for this channel
|
||||
#endif
|
||||
};
|
||||
|
||||
// ETM driver platform, it's always a singleton
|
||||
@@ -272,6 +276,8 @@ esp_err_t esp_etm_new_channel(const esp_etm_channel_config_t *config, esp_etm_ch
|
||||
if (clk_src == 0) {
|
||||
clk_src = ETM_CLK_SRC_DEFAULT;
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed");
|
||||
chan->clk_src = clk_src;
|
||||
etm_ll_set_clock_source(group_id, clk_src);
|
||||
#endif
|
||||
|
||||
@@ -290,6 +296,11 @@ esp_err_t esp_etm_new_channel(const esp_etm_channel_config_t *config, esp_etm_ch
|
||||
|
||||
err:
|
||||
if (chan) {
|
||||
#if ETM_LL_SUPPORT(CLOCK_SRC)
|
||||
if (chan->clk_src != 0) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)chan->clk_src, false);
|
||||
}
|
||||
#endif
|
||||
etm_chan_destroy(chan);
|
||||
}
|
||||
return ret;
|
||||
@@ -310,6 +321,11 @@ esp_err_t esp_etm_del_channel(esp_etm_channel_handle_t chan)
|
||||
etm_ll_channel_set_task(group->hal.regs, chan_id, 0);
|
||||
|
||||
ESP_LOGD(TAG, "del etm channel (%d,%d)", group_id, chan_id);
|
||||
#if ETM_LL_SUPPORT(CLOCK_SRC)
|
||||
// Back to hardware default clock selection, otherwise it might get stuck when stopping the bus during sleep process.
|
||||
etm_ll_set_clock_source(group_id, ETM_CLK_SRC_XTAL);
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)chan->clk_src, false), TAG, "clock source disable failed");
|
||||
#endif
|
||||
// recycle memory resource
|
||||
ESP_RETURN_ON_ERROR(etm_chan_destroy(chan), TAG, "destroy etm channel failed");
|
||||
return ESP_OK;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "modem/modem_clock_impl.h"
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
@@ -212,7 +214,13 @@ static void IRAM_ATTR modem_clock_coex_configure(modem_clock_context_t *ctx, boo
|
||||
#if SOC_MODEM_CLOCK_SOC_PLL_SOURCE_CG_SUPPORTED
|
||||
static void IRAM_ATTR modem_clock_soc_pll_source_cg_configure(modem_clock_context_t *ctx, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F160M, true));
|
||||
}
|
||||
modem_clock_hal_enable_soc_pll_source_cg(ctx->hal, enable);
|
||||
if (!enable) {
|
||||
ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F160M, false));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -144,6 +144,9 @@ uint32_t rtc_clk_cal_internal(soc_clk_freq_calculation_src_t cal_clk_sel, uint32
|
||||
}
|
||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||
clk_ll_freq_calculation_set_divider(1);
|
||||
// Back to always on clock source, Otherwise, if the source for this calibration is subsequently turned off,
|
||||
// the next calibration will not be able to switch to the new calibration source.
|
||||
clk_ll_freq_calulation_set_target(CLK_CAL_RC_SLOW);
|
||||
|
||||
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
|
||||
if (cal_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
|
||||
|
||||
@@ -123,6 +123,9 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_lcd_i80_bus_t *bus = NULL;
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
bool pll_f120m_enabled = false;
|
||||
#endif
|
||||
ESP_RETURN_ON_FALSE(bus_config && ret_bus, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
// although LCD_CAM can support up to 24 data lines, we restrict users to only use 8 or 16 bit width
|
||||
ESP_RETURN_ON_FALSE(bus_config->bus_width == 8 || bus_config->bus_width == 16, ESP_ERR_INVALID_ARG,
|
||||
@@ -181,6 +184,11 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
#endif // I80_USE_RETENTION_LINK
|
||||
// initialize HAL layer, so we can call LL APIs later
|
||||
lcd_hal_init(&bus->hal, bus_id);
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
// PLL 120M was selected in esp_perip_clk_init on esp32s31.
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, true), err, TAG, "clock source enable failed");
|
||||
pll_f120m_enabled = true;
|
||||
#endif
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_enable_clock(bus->hal.dev, true);
|
||||
}
|
||||
@@ -264,6 +272,11 @@ err:
|
||||
esp_clk_tree_enable_src(bus->clk_src, false);
|
||||
bus->clk_src = SOC_MOD_CLK_INVALID;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
if (pll_f120m_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (bus->pm_lock) {
|
||||
esp_pm_lock_delete(bus->pm_lock);
|
||||
@@ -287,6 +300,9 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus)
|
||||
esp_clk_tree_enable_src(bus->clk_src, false);
|
||||
bus->clk_src = SOC_MOD_CLK_INVALID;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false), err, TAG, "clock source disable failed");
|
||||
#endif
|
||||
#if I80_USE_RETENTION_LINK
|
||||
const periph_retention_module_t module_id = soc_i80_lcd_retention_info[bus_id].retention_module;
|
||||
sleep_retention_module_detach(module_id);
|
||||
|
||||
@@ -173,6 +173,9 @@ struct esp_rgb_panel_t {
|
||||
uint32_t fb_behind_cache: 1; // Whether the frame buffer is behind the cache
|
||||
uint32_t bb_behind_cache: 1; // Whether the bounce buffer is behind the cache
|
||||
uint32_t user_fb: 1; // Whether the frame buffer is provided by user
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
uint32_t pll_f120m_enabled: 1; // Whether PLL_F120M was enabled for this panel instance
|
||||
#endif
|
||||
} flags;
|
||||
// hook fields
|
||||
esp_lcd_panel_draw_bitmap_hook_t draw_bitmap_hook; // Draw bitmap hook function
|
||||
@@ -265,6 +268,12 @@ static esp_err_t lcd_rgb_panel_destroy(esp_rgb_panel_t *rgb_panel)
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_enable_clock(rgb_panel->hal.dev, false);
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
if (rgb_panel->flags.pll_f120m_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false);
|
||||
rgb_panel->flags.pll_f120m_enabled = 0;
|
||||
}
|
||||
#endif
|
||||
if (rgb_panel->clk_src) {
|
||||
esp_clk_tree_enable_src(rgb_panel->clk_src, false);
|
||||
}
|
||||
@@ -419,6 +428,11 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
|
||||
lcd_hal_init(&rgb_panel->hal, panel_id);
|
||||
lcd_hal_context_t *hal = &rgb_panel->hal;
|
||||
// enable clock
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
// PLL 120M was selected in esp_perip_clk_init on esp32s31.
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, true), err, TAG, "clock source enable failed");
|
||||
rgb_panel->flags.pll_f120m_enabled = 1;
|
||||
#endif
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_enable_clock(hal->dev, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user