feat(system): gate the HP peripheral clock by default for esp32c6 and esp32h2

This commit is contained in:
wuzhenghui
2023-12-11 17:02:06 +08:00
parent 48e6629987
commit 0528c8b4f4
2 changed files with 138 additions and 185 deletions

View File

@@ -20,6 +20,21 @@
#include "soc/i2s_reg.h"
#include "esp_cpu.h"
#include "hal/wdt_hal.h"
#include "hal/uart_ll.h"
#include "hal/i2c_ll.h"
#include "hal/rmt_ll.h"
#include "hal/ledc_ll.h"
#include "hal/timer_ll.h"
#include "hal/twai_ll.h"
#include "hal/i2s_ll.h"
#include "hal/pcnt_ll.h"
#include "hal/etm_ll.h"
#include "hal/mcpwm_ll.h"
#include "hal/parlio_ll.h"
#include "hal/gdma_ll.h"
#include "hal/spi_ll.h"
#include "hal/clk_gate_ll.h"
#include "hal/temperature_sensor_ll.h"
#include "esp_private/esp_modem_clock.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
@@ -193,102 +208,65 @@ __attribute__((weak)) void esp_perip_clk_init(void)
: SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0);
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
#if 0 // TODO: IDF-5658
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
uint32_t common_perip_clk1 = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
} else {
common_perip_clk = SYSTEM_WDG_CLK_EN |
SYSTEM_I2S0_CLK_EN |
if (rst_reason != RESET_REASON_CPU0_MWDT0 && rst_reason != RESET_REASON_CPU0_MWDT1 \
&& rst_reason != RESET_REASON_CPU0_SW && rst_reason != RESET_REASON_CPU0_RTC_WDT \
&& RESET_REASON_CPU0_JTAG) {
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
uart_ll_enable_bus_clock(UART_NUM_0, false);
#elif CONFIG_ESP_CONSOLE_UART_NUM != 1
uart_ll_enable_bus_clock(UART_NUM_1, false);
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
i2c_ll_enable_bus_clock(0, false);
i2c_ll_enable_controller_clock(&I2C0, false);
rmt_ll_enable_bus_clock(0, false);
rmt_ll_enable_group_clock(0, false);
ledc_ll_enable_clock(&LEDC, false);
ledc_ll_enable_bus_clock(false);
timer_ll_enable_clock(&TIMERG0, 0, false);
timer_ll_enable_clock(&TIMERG1, 0, false);
_timer_ll_enable_bus_clock(0, false);
_timer_ll_enable_bus_clock(1, false);
twai_ll_enable_clock(0, false);
twai_ll_enable_bus_clock(0, false);
twai_ll_enable_clock(1, false);
twai_ll_enable_bus_clock(1, false);
i2s_ll_enable_bus_clock(0, false);
i2s_ll_tx_disable_clock(&I2S0);
i2s_ll_rx_disable_clock(&I2S0);
pcnt_ll_enable_bus_clock(0, false);
etm_ll_enable_bus_clock(0, false);
mcpwm_ll_enable_bus_clock(0, false);
mcpwm_ll_group_enable_clock(0, false);
parlio_ll_rx_enable_clock(&PARL_IO, false);
parlio_ll_tx_enable_clock(&PARL_IO, false);
parlio_ll_enable_bus_clock(0, false);
gdma_ll_force_enable_reg_clock(&GDMA, false);
gdma_ll_enable_bus_clock(0, false);
#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
spi_ll_enable_bus_clock(SPI1_HOST, false);
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_LEDC_CLK_EN |
SYSTEM_TIMERGROUP1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_TWAI_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
spi_ll_enable_bus_clock(SPI2_HOST, false);
temperature_sensor_ll_bus_clk_enable(false);
common_perip_clk1 = 0;
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
SYSTEM_CRYPTO_SHA_CLK_EN |
SYSTEM_CRYPTO_RSA_CLK_EN;
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_UNUSED_BIT12;
periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE);
// TODO: Replace with hal implementation
REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN);
REG_CLR_BIT(PCR_RETENTION_CONF_REG, PCR_RETENTION_CLK_EN);
REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN);
}
//Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state.
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_UHCI1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_I2C_EXT1_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
* the current is not reduced when disable I2S clock.
*/
// TOCK(check replacement)
// REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
// REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
/* Disable some peripheral clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
/* Disable hardware crypto clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
/* Disable WiFi/BT/SDIO clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
/* Set WiFi light sleep clock source to RTC slow clock */
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW);
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
#endif
}

View File

@@ -16,11 +16,27 @@
#include "esp32h2/rom/ets_sys.h"
#include "esp32h2/rom/uart.h"
#include "soc/soc.h"
#include "soc/pcr_reg.h"
#include "soc/rtc.h"
#include "soc/rtc_periph.h"
#include "soc/i2s_reg.h"
#include "soc/pcr_reg.h"
#include "hal/wdt_hal.h"
#include "hal/uart_ll.h"
#include "hal/i2c_ll.h"
#include "hal/rmt_ll.h"
#include "hal/ledc_ll.h"
#include "hal/timer_ll.h"
#include "hal/twai_ll.h"
#include "hal/i2s_ll.h"
#include "hal/pcnt_ll.h"
#include "hal/etm_ll.h"
#include "hal/mcpwm_ll.h"
#include "hal/parlio_ll.h"
#include "hal/gdma_ll.h"
#include "hal/spi_ll.h"
#include "hal/clk_gate_ll.h"
#include "hal/temperature_sensor_ll.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
#include "esp_private/esp_pmu.h"
@@ -186,103 +202,62 @@ __attribute__((weak)) void esp_perip_clk_init(void)
: ESP_PD_DOMAIN_MAX);
esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON);
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
// ESP32H2-TODO: IDF-5658
#if 0
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
uint32_t common_perip_clk1 = 0;
soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW ||
rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) {
common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG);
hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG);
wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG);
} else {
common_perip_clk = SYSTEM_WDG_CLK_EN |
SYSTEM_I2S0_CLK_EN |
if (rst_reason != RESET_REASON_CPU0_MWDT0 && rst_reason != RESET_REASON_CPU0_MWDT1 \
&& rst_reason != RESET_REASON_CPU0_SW && rst_reason != RESET_REASON_CPU0_RTC_WDT) {
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
uart_ll_enable_bus_clock(UART_NUM_0, false);
#elif CONFIG_ESP_CONSOLE_UART_NUM != 1
uart_ll_enable_bus_clock(UART_NUM_1, false);
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
i2c_ll_enable_bus_clock(0, false);
i2c_ll_enable_bus_clock(1, false);
i2c_ll_enable_controller_clock(&I2C0, false);
i2c_ll_enable_controller_clock(&I2C1, false);
rmt_ll_enable_bus_clock(0, false);
rmt_ll_enable_group_clock(0, false);
ledc_ll_enable_clock(&LEDC, false);
ledc_ll_enable_bus_clock(false);
timer_ll_enable_clock(&TIMERG0, 0, false);
timer_ll_enable_clock(&TIMERG1, 0, false);
_timer_ll_enable_bus_clock(0, false);
_timer_ll_enable_bus_clock(1, false);
twai_ll_enable_clock(0, false);
twai_ll_enable_bus_clock(0, false);
i2s_ll_enable_bus_clock(0, false);
i2s_ll_tx_disable_clock(&I2S0);
i2s_ll_rx_disable_clock(&I2S0);
pcnt_ll_enable_bus_clock(0, false);
etm_ll_enable_bus_clock(0, false);
mcpwm_ll_enable_bus_clock(0, false);
mcpwm_ll_group_enable_clock(0, false);
parlio_ll_rx_enable_clock(&PARL_IO, false);
parlio_ll_tx_enable_clock(&PARL_IO, false);
parlio_ll_enable_bus_clock(0, false);
gdma_ll_force_enable_reg_clock(&GDMA, false);
gdma_ll_enable_bus_clock(0, false);
#if CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
spi_ll_enable_bus_clock(SPI1_HOST, false);
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_LEDC_CLK_EN |
SYSTEM_TIMERGROUP1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_TWAI_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
spi_ll_enable_bus_clock(SPI2_HOST, false);
temperature_sensor_ll_bus_clk_enable(false);
common_perip_clk1 = 0;
hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN |
SYSTEM_CRYPTO_SHA_CLK_EN |
SYSTEM_CRYPTO_RSA_CLK_EN;
wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN |
SYSTEM_WIFI_CLK_BT_EN_M |
SYSTEM_WIFI_CLK_UNUSED_BIT5 |
SYSTEM_WIFI_CLK_UNUSED_BIT12;
periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_ASSIST_DEBUG_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_RSA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_AES_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_SHA_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_ECC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_HMAC_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_DS_MODULE);
periph_ll_disable_clk_set_rst(PERIPH_ECDSA_MODULE);
// TODO: Replace with hal implementation
REG_CLR_BIT(PCR_TRACE_CONF_REG, PCR_TRACE_CLK_EN);
REG_CLR_BIT(PCR_MEM_MONITOR_CONF_REG, PCR_MEM_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_CONF_REG, PCR_PVT_MONITOR_CLK_EN);
REG_CLR_BIT(PCR_PVT_MONITOR_FUNC_CLK_CONF_REG, PCR_PVT_MONITOR_FUNC_CLK_EN);
}
//Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state.
common_perip_clk |= SYSTEM_I2S0_CLK_EN |
#if CONFIG_ESP_CONSOLE_UART_NUM != 0
SYSTEM_UART_CLK_EN |
#endif
#if CONFIG_ESP_CONSOLE_UART_NUM != 1
SYSTEM_UART1_CLK_EN |
#endif
SYSTEM_SPI2_CLK_EN |
SYSTEM_I2C_EXT0_CLK_EN |
SYSTEM_UHCI0_CLK_EN |
SYSTEM_RMT_CLK_EN |
SYSTEM_UHCI1_CLK_EN |
SYSTEM_SPI3_CLK_EN |
SYSTEM_SPI4_CLK_EN |
SYSTEM_I2C_EXT1_CLK_EN |
SYSTEM_I2S1_CLK_EN |
SYSTEM_SPI2_DMA_CLK_EN |
SYSTEM_SPI3_DMA_CLK_EN;
common_perip_clk1 = 0;
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
* the current is not reduced when disable I2S clock.
*/
// TOCK(check replacement)
// REG_SET_FIELD(I2S_CLKM_CONF_REG(0), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
// REG_SET_FIELD(I2S_CLKM_CONF_REG(1), I2S_CLK_SEL, I2S_CLK_AUDIO_PLL);
/* Disable some peripheral clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, common_perip_clk);
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, common_perip_clk1);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, common_perip_clk1);
/* Disable hardware crypto clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN1_REG, hwcrypto_perip_clk);
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, hwcrypto_perip_clk);
/* Disable WiFi/BT/SDIO clocks. */
CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
/* Set WiFi light sleep clock source to RTC slow clock */
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW);
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
#endif
}