]> granicus.if.org Git - esp-idf/commitdiff
Disable some peripheral clocks when cpu starts
authorXiaXiaotian <xiaxiaotian@espressif.com>
Tue, 8 Aug 2017 08:58:58 +0000 (16:58 +0800)
committerXiaXiaotian <xiaxiaotian@espressif.com>
Tue, 29 Aug 2017 03:18:42 +0000 (11:18 +0800)
    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.

components/esp32/clk.c
components/esp32/cpu_start.c
components/esp32/include/esp_clk.h
components/soc/esp32/include/soc/dport_reg.h

index ab589fcdcfa65573540dd2f53f685ba868a3b8cd..f9be8dac5798eac870c9a8a2a0a9c40c144c8625 100644 (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);
+}
index 7fec14f3c310dae682ea64d51329369d54779355..574179c08d0065bdc885723ef60c89504d93b9f0 100644 (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);
index 7b9c64c69280d4f56051ca52961f10f767031b72..5c6f5cb8710a00cf59af1b655ebbf5e8709bfcfd 100644 (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);
+
index 56e18246d7996beb9d97eb9cd193caa7e3a986c4..98e6036526a759971cdfe55da3fb401ebbae4bd7 100644 (file)
 #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)