From fad2c740b1d1d7aa241e670e6c3f1a5dfad32f67 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 16 Aug 2024 12:11:58 +0800 Subject: [PATCH] feature(spi_flash): Promote the c61 mspi clock frequency from 40 to 80M --- .../src/bootloader_flash_config_esp32c61.c | 8 +++ components/esptool_py/Kconfig.projbuild | 6 +- .../include/hal/mspi_timing_tuning_ll.h | 69 +++++++++++++++++++ .../hal/esp32c61/include/hal/psram_ctrlr_ll.h | 4 +- .../esp32c61/include/hal/spimem_flash_ll.h | 36 +++------- .../soc/esp32c61/include/soc/clk_tree_defs.h | 15 ++++ 6 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 components/hal/esp32c61/include/hal/mspi_timing_tuning_ll.h diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c index d65e6915ae..06d3db2796 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c @@ -24,6 +24,7 @@ #include "hal/mmu_ll.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" +#include "hal/mspi_timing_tuning_ll.h" static const char *TAG __attribute__((unused)) = "boot.esp32c61"; @@ -197,6 +198,13 @@ static void bootloader_spi_flash_resume(void) esp_err_t bootloader_init_spi_flash(void) { + + // Set source mspi pll clock as 80M in bootloader stage. + // SPLL clock on C61 is 480MHz , and mspi_pll needs 80MHz + // in this stage, set divider as 6 + mspi_ll_clock_src_sel(MSPI_CLK_SRC_SPLL); + mspi_ll_fast_set_hs_divider(6); + bootloader_init_flash_configure(); bootloader_spi_flash_resume(); bootloader_flash_unlock(); diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index fac3998ae1..4e2b5ed432 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -91,9 +91,7 @@ menu "Serial flasher config" choice ESPTOOLPY_FLASHFREQ prompt "Flash SPI speed" - # TODO: [ESP32C5] IDF-8649 switch back to 80M - # TODO: [ESP32C61] IDF-9256 - default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C61 + default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32 default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2 config ESPTOOLPY_FLASHFREQ_120M @@ -153,7 +151,7 @@ menu "Serial flasher config" config ESPTOOLPY_FLASHFREQ_80M_DEFAULT bool default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6 - default y if IDF_TARGET_ESP32C5 + default y if IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C61 help This is an invisible item, used to define the targets that defaults to use 80MHz Flash SPI speed. diff --git a/components/hal/esp32c61/include/hal/mspi_timing_tuning_ll.h b/components/hal/esp32c61/include/hal/mspi_timing_tuning_ll.h new file mode 100644 index 0000000000..9a01d99830 --- /dev/null +++ b/components/hal/esp32c61/include/hal/mspi_timing_tuning_ll.h @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/clk_tree_defs.h" +#include "soc/pcr_struct.h" +#include "hal/misc.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************** MSPI pll clock configurations **************************/ + +/** + * @brief Select mspi clock source + * + * @param clk_src the clock source of mspi clock + */ +static inline __attribute__((always_inline)) void mspi_ll_clock_src_sel(soc_periph_mspi_clk_src_t clk_src) +{ + switch (clk_src) { + case MSPI_CLK_SRC_XTAL: + PCR.mspi_clk_conf.mspi_func_clk_sel = 0; + break; + case MSPI_CLK_SRC_RC_FAST: + PCR.mspi_clk_conf.mspi_func_clk_sel = 1; + break; + case MSPI_CLK_SRC_SPLL: + PCR.mspi_clk_conf.mspi_func_clk_sel = 2; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL) + * + * @param divider Divider. + */ +static inline __attribute__((always_inline)) void mspi_ll_fast_set_hs_divider(uint32_t divider) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, divider - 1); +} + +/** + * @brief Enable the mspi bus clock + * + * @param enable enable the bus clock + */ +static inline __attribute__((always_inline)) void mspi_ll_enable_bus_clock(bool enable) +{ + PCR.mspi_conf.mspi_clk_en = enable; +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h index f5e799c400..0a9946ff57 100644 --- a/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h @@ -242,8 +242,8 @@ static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_ __attribute__((always_inline)) static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) { - SPIMEM0.mem_misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; - SPIMEM0.mem_misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; + SPIMEM1.misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; + SPIMEM1.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; } /** diff --git a/components/hal/esp32c61/include/hal/spimem_flash_ll.h b/components/hal/esp32c61/include/hal/spimem_flash_ll.h index 6a690b6a46..4a2507d03f 100644 --- a/components/hal/esp32c61/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c61/include/hal/spimem_flash_ll.h @@ -27,8 +27,8 @@ #include "hal/spi_flash_types.h" #include "soc/pcr_struct.h" #include "esp_rom_sys.h" - -// TODO: [ESP32C61] IDF-9314, inherit from c6 +#include "hal/clk_tree_ll.h" +#include "soc/clk_tree_defs.h" #ifdef __cplusplus extern "C" { @@ -628,39 +628,25 @@ static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_ */ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void) { -#if CONFIG_IDF_ENV_FPGA - // in FPGA, mspi source freq is fixed to 80M - return 80; -#else - // MAY CAN IMPROVE (ONLY rc_fast case is incorrect)! - // TODO: Default is PLL480M, this is hard-coded. - // In the future, we can get the CPU clock source by calling interface. - uint8_t clock_val = 0; - switch (PCR.mspi_clk_conf.mspi_fast_div_num) { + int source_clk_mhz = 0; + + switch (PCR.mspi_clk_conf.mspi_func_clk_sel) + { case 0: - clock_val = 40; + source_clk_mhz = clk_ll_xtal_get_freq_mhz(); break; case 1: - clock_val = 20; + source_clk_mhz = (SOC_CLK_RC_FAST_FREQ_APPROX/(1 * 1000 * 1000)); break; case 2: - clock_val = 10; - break; - case 3: - clock_val = 120; - break; - case 4: - clock_val = 96; - break; - case 5: - clock_val = 80; + source_clk_mhz = clk_ll_bbpll_get_freq_mhz(); break; default: - HAL_ASSERT(false); + break; } + uint8_t clock_val = source_clk_mhz / (PCR.mspi_clk_conf.mspi_fast_div_num + 1); return clock_val; -#endif } /** diff --git a/components/soc/esp32c61/include/soc/clk_tree_defs.h b/components/soc/esp32c61/include/soc/clk_tree_defs.h index 3a52fefe79..e5616319b5 100644 --- a/components/soc/esp32c61/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c61/include/soc/clk_tree_defs.h @@ -343,6 +343,21 @@ typedef enum { LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */ } soc_periph_ledc_clk_src_legacy_t; +//////////////////////////////////////////////////MSPI/////////////////////////////////////////////////////////////////// +/** + * @brief Array initializer for all supported clock sources of MSPI digital controller + */ +#define SOC_MSPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_SPLL} +/** + * @brief MSPI digital controller clock source + */ +typedef enum { + MSPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + MSPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + MSPI_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SPLL as the source clock */ + MSPI_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */ +} soc_periph_mspi_clk_src_t; + //////////////////////////////////////////////CLOCK OUTPUT/////////////////////////////////////////////////////////// typedef enum { CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */