From 192f01c65fbbaf219da326c1ffea117b8a422146 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 29 Nov 2024 21:36:58 +0800 Subject: [PATCH 1/2] fix(esp_system): hp periph clk should not be gated on core/system reset --- .../src/bootloader_console.c | 6 ++ components/esp_system/port/soc/esp32c6/clk.c | 2 +- components/esp_system/port/soc/esp32p4/clk.c | 55 ++++++++++--------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index f37e2e1870..eb83ae8b13 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -74,6 +74,12 @@ void bootloader_console_init(void) // Enable the peripheral uart_ll_enable_bus_clock(uart_num, true); uart_ll_reset_register(uart_num); + // Set clock source +#if SOC_UART_SUPPORT_XTAL_CLK + uart_ll_set_sclk(UART_LL_GET_HW(uart_num), (soc_module_clk_t)UART_SCLK_XTAL); +#else + uart_ll_set_sclk(UART_LL_GET_HW(uart_num), (soc_module_clk_t)UART_SCLK_APB); +#endif // Reset TX and RX FIFOs uart_ll_txfifo_rst(UART_LL_GET_HW(uart_num)); uart_ll_rxfifo_rst(UART_LL_GET_HW(uart_num)); diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index f360711f94..ca2b940060 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -316,8 +316,8 @@ __attribute__((weak)) void esp_perip_clk_init(void) if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CHIP_BROWN_OUT) \ || (rst_reason == RESET_REASON_SYS_RTC_WDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT)) { _lp_i2c_ll_enable_bus_clock(0, false); - _lp_uart_ll_enable_bus_clock(0, false); lp_uart_ll_sclk_disable(0); + _lp_uart_ll_enable_bus_clock(0, false); lp_core_ll_enable_bus_clock(false); _lp_clkrst_ll_enable_rng_clock(false); diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index 7a12446887..3d992d2573 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -243,9 +243,9 @@ __attribute__((weak)) void esp_perip_clk_init(void) } soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - if ((rst_reason != RESET_REASON_CPU0_SW) && (rst_reason != RESET_REASON_CPU_MWDT) \ - && (rst_reason != RESET_REASON_CPU_RWDT) && (rst_reason != RESET_REASON_CPU_JTAG) \ - && (rst_reason != RESET_REASON_CPU_LOCKUP)) { + // HP related clock control + if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN)) { + // hp_sys_clkrst register gets reset only if chip reset or pmu powers down hp _gdma_ll_enable_bus_clock(0, false); _gdma_ll_enable_bus_clock(1, false); _pau_ll_enable_bus_clock(false); @@ -356,33 +356,38 @@ __attribute__((weak)) void esp_perip_clk_init(void) #endif } + // LP related clock control if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) \ || (rst_reason == RESET_REASON_SYS_RWDT) || (rst_reason == RESET_REASON_SYS_BROWN_OUT)) { - _lp_uart_ll_enable_bus_clock(0, false); + // lpperi,lp peripheral registers get reset for reset level equal or higher than system reset lp_uart_ll_sclk_disable(0); + _lp_uart_ll_enable_bus_clock(0, false); _rtcio_ll_enable_io_clock(false); - // LP_Peri & Clock Control - _uart_ll_enable_pad_sleep_clock(&UART0, false); - _uart_ll_enable_pad_sleep_clock(&UART1, false); - _uart_ll_enable_pad_sleep_clock(&UART2, false); - _uart_ll_enable_pad_sleep_clock(&UART3, false); - _uart_ll_enable_pad_sleep_clock(&UART4, false); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_PARLIO_TX_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_PARLIO_RX_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S2_MCLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S1_MCLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S0_MCLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PLL_8M_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_AUDIO_PLL_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL2_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL1_CLK_EN); - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL0_CLK_EN); + + if (rst_reason == RESET_REASON_CHIP_POWER_ON) { + // lp_aon_clkrst, lp_system registers get reset only if chip reset + _uart_ll_enable_pad_sleep_clock(&UART0, false); + _uart_ll_enable_pad_sleep_clock(&UART1, false); + _uart_ll_enable_pad_sleep_clock(&UART2, false); + _uart_ll_enable_pad_sleep_clock(&UART3, false); + _uart_ll_enable_pad_sleep_clock(&UART4, false); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_PARLIO_TX_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_PARLIO_RX_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S2_MCLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S1_MCLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_I2S0_MCLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_PLL_8M_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_AUDIO_PLL_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL2_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL1_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL0_CLK_EN); #if !CONFIG_SPIRAM_BOOT_INIT - REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN); + REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN); #endif - REG_CLR_BIT(LP_SYSTEM_REG_HP_ROOT_CLK_CTRL_REG, LP_SYSTEM_REG_CPU_CLK_EN); + REG_CLR_BIT(LP_SYSTEM_REG_HP_ROOT_CLK_CTRL_REG, LP_SYSTEM_REG_CPU_CLK_EN); + } } } From 77e88f98cd1d158eb7de5cbdb13789da552142f2 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 12 Dec 2024 20:45:06 +0800 Subject: [PATCH 2/2] fix(esp_system): still gate hp periph clk on core/system reset for power saving Leaving only hp periph clk source should not be gated on core/system reset --- components/esp_system/port/soc/esp32p4/clk.c | 28 +++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index 3d992d2573..06974d098c 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -243,9 +243,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) } soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0); - // HP related clock control - if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN)) { + // HP modules related clock control + if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN) + || (rst_reason == RESET_REASON_SYS_BROWN_OUT) || (rst_reason == RESET_REASON_SYS_RWDT) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) + || (rst_reason == RESET_REASON_CORE_SW) || (rst_reason == RESET_REASON_CORE_MWDT) || (rst_reason == RESET_REASON_CORE_RWDT) || (rst_reason == RESET_REASON_CORE_PWR_GLITCH) || (rst_reason == RESET_REASON_CORE_EFUSE_CRC) || (rst_reason == RESET_REASON_CORE_USB_JTAG) || (rst_reason == RESET_REASON_CORE_USB_UART) + ) { // hp_sys_clkrst register gets reset only if chip reset or pmu powers down hp + // but at core reset and above, we will also disable HP modules' clock gating to save power consumption _gdma_ll_enable_bus_clock(0, false); _gdma_ll_enable_bus_clock(1, false); _pau_ll_enable_bus_clock(false); @@ -302,14 +306,6 @@ __attribute__((weak)) void esp_perip_clk_init(void) _psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false); #endif - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_REF_50M_CLK_EN); - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_REF_25M_CLK_EN); - // 240M CLK is for Key Management use, should not be gated - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_120M_CLK_EN); - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_80M_CLK_EN); - REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_20M_CLK_EN); - _spi_ll_enable_bus_clock(SPI2_HOST, false); _spi_ll_enable_bus_clock(SPI3_HOST, false); _spi_ll_enable_clock(SPI2_HOST, false); @@ -356,6 +352,18 @@ __attribute__((weak)) void esp_perip_clk_init(void) #endif } + // HP modules' clock source gating control + if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_CORE_PMU_PWR_DOWN)) { + // Only safe to disable these clock source gatings if all HP modules clock configurations has been reset + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_REF_50M_CLK_EN); + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_REF_25M_CLK_EN); + // 240M CLK is for Key Management use, should not be gated + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_120M_CLK_EN); + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_80M_CLK_EN); + REG_CLR_BIT(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_20M_CLK_EN); + } + // LP related clock control if ((rst_reason == RESET_REASON_CHIP_POWER_ON) || (rst_reason == RESET_REASON_SYS_SUPER_WDT) \ || (rst_reason == RESET_REASON_SYS_RWDT) || (rst_reason == RESET_REASON_SYS_BROWN_OUT)) {