Disable some peripheral clocks when cpu starts

All peripheral clocks are default enabled after chip is powered on.
    When CPU starts, if reset reason is CPU reset, disable those clocks
    that are not enabled before reset. Otherwise, disable all those
    useless clocks.
    These peripheral clocks must be enabled when the peripherals are
    initialized and disabled when they are deinitialized.
This commit is contained in:
XiaXiaotian 2017-08-08 16:58:58 +08:00
parent 4da7ee1295
commit 4776f73ca4
4 changed files with 99 additions and 0 deletions

View file

@ -25,6 +25,8 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/dport_reg.h"
#include "soc/i2s_reg.h"
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
* Larger values increase startup delay. Smaller values may cause false positive
@ -125,3 +127,89 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
esp_clk_slowclk_cal_set(cal_val);
}
/* This function is not exposed as an API at this point.
* All peripheral clocks are default enabled after chip is powered on.
* This function disables some peripheral clocks when cpu starts.
* These peripheral clocks are enabled when the peripherals are initialized
* and disabled when they are de-initialized.
*/
void esp_perip_clk_init(void)
{
uint32_t common_perip_clk, hwcrypto_perip_clk, wifi_bt_sdio_clk = 0;
#if CONFIG_FREERTOS_UNICORE
RESET_REASON rst_reas[1];
#else
RESET_REASON rst_reas[2];
#endif
rst_reas[0] = rtc_get_reset_reason(0);
#if !CONFIG_FREERTOS_UNICORE
rst_reas[1] = rtc_get_reset_reason(1);
#endif
/* For reason that only reset CPU, do not disable the clocks
* that have been enabled before reset.
*/
if ((rst_reas[0] >= TGWDT_CPU_RESET && rst_reas[0] <= RTCWDT_CPU_RESET)
#if !CONFIG_FREERTOS_UNICORE
|| (rst_reas[1] >= TGWDT_CPU_RESET && rst_reas[1] <= RTCWDT_CPU_RESET)
#endif
) {
common_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
hwcrypto_perip_clk = ~DPORT_READ_PERI_REG(DPORT_PERI_CLK_EN_REG);
wifi_bt_sdio_clk = ~DPORT_READ_PERI_REG(DPORT_WIFI_CLK_EN_REG);
}
else {
common_perip_clk = DPORT_WDG_CLK_EN |
DPORT_I2S0_CLK_EN |
DPORT_UART1_CLK_EN |
DPORT_SPI_CLK_EN |
DPORT_I2C_EXT0_CLK_EN |
DPORT_UHCI0_CLK_EN |
DPORT_RMT_CLK_EN |
DPORT_PCNT_CLK_EN |
DPORT_LEDC_CLK_EN |
DPORT_UHCI1_CLK_EN |
DPORT_TIMERGROUP1_CLK_EN |
DPORT_SPI_CLK_EN_2 |
DPORT_PWM0_CLK_EN |
DPORT_I2C_EXT1_CLK_EN |
DPORT_CAN_CLK_EN |
DPORT_PWM1_CLK_EN |
DPORT_I2S1_CLK_EN |
DPORT_SPI_DMA_CLK_EN |
DPORT_UART2_CLK_EN |
DPORT_PWM2_CLK_EN |
DPORT_PWM3_CLK_EN;
hwcrypto_perip_clk = DPORT_PERI_EN_AES |
DPORT_PERI_EN_SHA |
DPORT_PERI_EN_RSA |
DPORT_PERI_EN_SECUREBOOT;
wifi_bt_sdio_clk = DPORT_WIFI_CLK_WIFI_EN |
DPORT_WIFI_CLK_BT_EN_M |
DPORT_WIFI_CLK_UNUSED_BIT5 |
DPORT_WIFI_CLK_UNUSED_BIT12 |
DPORT_WIFI_CLK_SDIOSLAVE_EN |
DPORT_WIFI_CLK_SDIO_HOST_EN |
DPORT_WIFI_CLK_EMAC_EN;
}
/* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock,
* the current is not reduced when disable I2S clock.
*/
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA);
DPORT_SET_PERI_REG_MASK(I2S_CLKM_CONF_REG(1), I2S_CLKA_ENA);
/* Disable some peripheral clocks. */
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, common_perip_clk);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, common_perip_clk);
/* Disable hardware crypto clocks. */
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, hwcrypto_perip_clk);
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, hwcrypto_perip_clk);
/* Disable WiFi/BT/SDIO clocks. */
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, wifi_bt_sdio_clk);
}

View file

@ -238,6 +238,7 @@ void start_cpu0_default(void)
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
#endif
esp_clk_init();
esp_perip_clk_init();
intr_matrix_clear();
#ifndef CONFIG_CONSOLE_UART_NONE
uart_div_modify(CONFIG_CONSOLE_UART_NUM, (rtc_clk_apb_freq_get() << 4) / CONFIG_CONSOLE_UART_BAUDRATE);

View file

@ -54,3 +54,11 @@ uint32_t esp_clk_slowclk_cal_get();
*/
void esp_clk_slowclk_cal_set(uint32_t value);
/**
* @brief Disables clock of some peripherals
*
* Called from cpu_start.c, not intended to be called from other places.
* This function disables clock of useless peripherals when cpu starts.
*/
void esp_perip_clk_init(void);

View file

@ -1055,6 +1055,8 @@
#define DPORT_WIFI_CLK_BT_EN_S 11
/* Remaining single bit clock masks */
#define DPORT_WIFI_CLK_SDIOSLAVE_EN BIT(4)
#define DPORT_WIFI_CLK_UNUSED_BIT5 BIT(5)
#define DPORT_WIFI_CLK_UNUSED_BIT12 BIT(12)
#define DPORT_WIFI_CLK_SDIO_HOST_EN BIT(13)
#define DPORT_WIFI_CLK_EMAC_EN BIT(14)
#define DPORT_WIFI_CLK_RNG_EN BIT(15)