From b676f6080df710b49f5bc0dfc97364732d74ceda Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 9 Aug 2024 10:03:03 +0800 Subject: [PATCH 1/3] feature(spiram): Add spiram support on esp32c61 --- components/esp_psram/esp32c61/Kconfig.spiram | 48 ++++ .../esp_psram/test_apps/.build-test-rules.yml | 4 + .../esp_psram/test_apps/psram/README.md | 4 +- .../hal/esp32c5/include/hal/psram_ctrlr_ll.h | 4 +- .../hal/esp32c61/include/hal/psram_ctrlr_ll.h | 263 ++++++++++++++++++ .../hal/esp32s3/include/hal/psram_ctrlr_ll.h | 4 +- .../esp32c61/include/soc/Kconfig.soc_caps.in | 4 + .../soc/esp32c61/include/soc/io_mux_reg.h | 1 + components/soc/esp32c61/include/soc/soc.h | 2 +- .../soc/esp32c61/include/soc/soc_caps.h | 1 + 10 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 components/esp_psram/esp32c61/Kconfig.spiram create mode 100644 components/hal/esp32c61/include/hal/psram_ctrlr_ll.h diff --git a/components/esp_psram/esp32c61/Kconfig.spiram b/components/esp_psram/esp32c61/Kconfig.spiram new file mode 100644 index 0000000000..725b456a3c --- /dev/null +++ b/components/esp_psram/esp32c61/Kconfig.spiram @@ -0,0 +1,48 @@ +config SPIRAM + bool "Support for external, SPI-connected RAM" + default "n" + help + This enables support for an external SPI RAM chip, connected in parallel with the + main SPI flash chip. + +menu "SPI RAM config" + depends on SPIRAM + + choice SPIRAM_MODE + prompt "Mode of SPI RAM chip in use" + default SPIRAM_MODE_QUAD + + config SPIRAM_MODE_QUAD + bool "Quad Mode PSRAM" + + endchoice + + config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY + bool "Allow external memory as an argument to xTaskCreateStatic" + default y + help + Accessing memory in SPIRAM has certain restrictions, so task stacks allocated by xTaskCreate + are by default allocated from internal RAM. + + This option allows for passing memory allocated from SPIRAM to be passed to xTaskCreateStatic. + This should only be used for tasks where the stack is never accessed while the cache is disabled. + + choice SPIRAM_SPEED + prompt "Set RAM clock speed" + default SPIRAM_SPEED_40M + help + Select the speed for the SPI RAM chip. + + config SPIRAM_SPEED_80M + bool "80MHz clock speed" + config SPIRAM_SPEED_40M + bool "40Mhz clock speed" + endchoice + + config SPIRAM_SPEED + int + default 80 if SPIRAM_SPEED_80M + default 40 if SPIRAM_SPEED_40M + + source "$IDF_PATH/components/esp_psram/Kconfig.spiram.common" # insert non-chip-specific items here +endmenu diff --git a/components/esp_psram/test_apps/.build-test-rules.yml b/components/esp_psram/test_apps/.build-test-rules.yml index 88e2708734..b815394dba 100644 --- a/components/esp_psram/test_apps/.build-test-rules.yml +++ b/components/esp_psram/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/esp_psram/test_apps/psram: disable: - if: SOC_SPIRAM_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET in ["esp32c61"] + temporary: true + reason: No runner depends_components: - esp_psram - esp_mm diff --git a/components/esp_psram/test_apps/psram/README.md b/components/esp_psram/test_apps/psram/README.md index fe5c904716..6f2974f7f5 100644 --- a/components/esp_psram/test_apps/psram/README.md +++ b/components/esp_psram/test_apps/psram/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | --------- | -------- | -------- | -------- | This test app is used to test PSRAM diff --git a/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h b/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h index 7d9624c581..0a9946ff57 100644 --- a/components/hal/esp32c5/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32c5/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) { - SPIMEM1.misc.cs0_dis = (cs_id == 0) ? 0 : 1; - SPIMEM1.misc.cs1_dis = (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/psram_ctrlr_ll.h b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h new file mode 100644 index 0000000000..f5e799c400 --- /dev/null +++ b/components/hal/esp32c61/include/hal/psram_ctrlr_ll.h @@ -0,0 +1,263 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "soc/spi_mem_struct.h" +#include "soc/spi_mem_reg.h" +#include "soc/clk_tree_defs.h" +#include "rom/opi_flash.h" +#include "hal/psram_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSRAM_CTRLR_LL_MSPI_ID_0 0 +#define PSRAM_CTRLR_LL_MSPI_ID_1 1 + +#define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M + +/** + * @brief PSRAM enum for cs id. + */ +typedef enum { + PSRAM_LL_CS_ID_0 = 0, + PSRAM_LL_CS_ID_1 = 1, +} psram_ll_cs_id_t; + +/** + * @brief Set PSRAM write cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_wr_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_cache_sram_usr_wcmd = 1; + SPIMEM0.mem_sram_dwr_cmd.mem_cache_sram_usr_wr_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM0.mem_sram_dwr_cmd, mem_cache_sram_usr_wr_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM read cmd + * + * @param mspi_id mspi_id + * @param cmd_bitlen command bitlen + * @param cmd_val command value + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_cmd(uint32_t mspi_id, uint32_t cmd_bitlen, uint32_t cmd_val) +{ + (void)mspi_id; + HAL_ASSERT(cmd_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_cache_sram_usr_rcmd = 1; + SPIMEM0.mem_sram_drd_cmd.mem_cache_sram_usr_rd_cmd_bitlen = cmd_bitlen - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(SPIMEM0.mem_sram_drd_cmd, mem_cache_sram_usr_rd_cmd_value, cmd_val); +} + +/** + * @brief Set PSRAM addr bitlen + * + * @param mspi_id mspi_id + * @param addr_bitlen address bitlen + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_addr_bitlen(uint32_t mspi_id, uint32_t addr_bitlen) +{ + (void)mspi_id; + HAL_ASSERT(addr_bitlen > 0); + SPIMEM0.mem_cache_sctrl.mem_sram_addr_bitlen = addr_bitlen - 1; +} + +/** + * @brief Set PSRAM read dummy + * + * @param mspi_id mspi_id + * @param dummy_n dummy number + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_rd_dummy(uint32_t mspi_id, uint32_t dummy_n) +{ + (void)mspi_id; + HAL_ASSERT(dummy_n > 0); + SPIMEM0.mem_cache_sctrl.mem_usr_rd_sram_dummy = 1; + SPIMEM0.mem_cache_sctrl.mem_sram_rdummy_cyclelen = dummy_n - 1; +} + +/** + * @brief Set PSRAM bus clock + * + * @param mspi_id mspi_id + * @param clock_conf Configuration value for psram clock + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_bus_clock(uint32_t mspi_id, uint32_t clock_conf) +{ + SPIMEM0.mem_sram_clk.val = clock_conf; +} + +/** + * Calculate spi_flash clock frequency division parameters for register. + * + * @param clkdiv frequency division factor + * + * @return Register setting for the given clock division factor. + */ +static inline uint32_t psram_ctrlr_ll_calculate_clock_reg(uint8_t clkdiv) +{ + uint32_t div_parameter; + // See comments of `clock` in `spi_mem_struct.h` + if (clkdiv == 1) { + div_parameter = (1 << 31); + } else { + div_parameter = ((clkdiv - 1) | (((clkdiv - 1) / 2 & 0xff) << 8 ) | (((clkdiv - 1) & 0xff) << 16)); + } + return div_parameter; +} + +/** + * Configure the psram read mode + * + * @param mspi_id mspi_id + * @param read_mode read mode + */ +static inline void psram_ctrlr_ll_set_read_mode(uint32_t mspi_id, psram_hal_cmd_mode_t read_mode) +{ + typeof (SPIMEM0.mem_cache_sctrl) mem_cache_sctrl; + mem_cache_sctrl.val = SPIMEM0.mem_cache_sctrl.val; + + mem_cache_sctrl.val &= ~(SPI_MEM_USR_SRAM_DIO_M | SPI_MEM_USR_SRAM_QIO_M); + switch (read_mode) { + case PSRAM_HAL_CMD_SPI: + mem_cache_sctrl.mem_usr_sram_dio = 1; + break; + case PSRAM_HAL_CMD_QPI: + mem_cache_sctrl.mem_usr_sram_qio = 1; + break; + default: + abort(); + } + SPIMEM0.mem_cache_sctrl.val = mem_cache_sctrl.val; +} + +/** + * @brief Set CS setup + * + * @param mspi_id mspi_id + * @param setup_n cs setup time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_setup(uint32_t mspi_id, uint32_t setup_n) +{ + (void)mspi_id; + HAL_ASSERT(setup_n > 0); + SPIMEM0.smem_ac.smem_cs_setup = 1; + SPIMEM0.smem_ac.smem_cs_setup_time = setup_n - 1; +} + +/** + * @brief Set CS hold + * + * @param mspi_id mspi_id + * @param hold_n cs hold time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold(uint32_t mspi_id, uint32_t hold_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_n > 0); + SPIMEM0.smem_ac.smem_cs_hold = 1; + SPIMEM0.smem_ac.smem_cs_hold_time = hold_n - 1; +} + +/** + * @brief Set CS hold delay + * + * @param mspi_id mspi_id + * @param hold_delay_n cs hold delay time + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_set_cs_hold_delay(uint32_t mspi_id, uint32_t hold_delay_n) +{ + (void)mspi_id; + HAL_ASSERT(hold_delay_n > 0); + SPIMEM0.smem_ac.smem_cs_hold_delay = hold_delay_n - 1; +} + +/** + * @brief PSRAM common transaction + * + * See `opi_flash.h` for parameters + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_rom_spiflash_read_mode_t mode, + uint32_t cmd, uint32_t cmd_bitlen, + uint32_t addr, uint32_t addr_bitlen, + uint32_t dummy_bits, + uint8_t* mosi_data, uint32_t mosi_bitlen, + uint8_t* miso_data, uint32_t miso_bitlen, + uint32_t cs_mask, + bool is_write_erase_operation) +{ + esp_rom_spi_cmd_t conf = { + .cmd = cmd, + .cmdBitLen = cmd_bitlen, + .addr = &addr, + .addrBitLen = addr_bitlen, + .txData = (uint32_t *)mosi_data, + .txDataBitLen = mosi_bitlen, + .rxData = (uint32_t *)miso_data, + .rxDataBitLen = miso_bitlen, + .dummyBitLen = dummy_bits, + }; + esp_rom_spi_cmd_config(mspi_id, &conf); + esp_rom_spi_cmd_start(mspi_id, miso_data, miso_bitlen / 8, cs_mask, is_write_erase_operation); +} + +/** + * Select which pin to use for the psram + * + * @param mspi_id mspi_id + * @param cs_id cs_id for psram to use. + */ +__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; +} + +/** + * Enable the psram quad command + * + * @param mspi_id mspi_id + * @param ena true if enable, otherwise false + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_enable_quad_command(uint32_t mspi_id, bool ena) +{ + SPIMEM1.ctrl.fcmd_quad = ena; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h b/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h index 8de7d5b3d1..ff8245bdf7 100644 --- a/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32s3/include/hal/psram_ctrlr_ll.h @@ -210,8 +210,8 @@ static inline void psram_ctrlr_ll_common_transaction_base(uint32_t mspi_id, esp_ */ static inline void psram_ctrlr_ll_set_cs_pin(uint32_t mspi_id, psram_ll_cs_id_t cs_id) { - SPIMEM0.misc.cs0_dis = (cs_id == 0) ? 0 : 1; - SPIMEM0.misc.cs1_dis = (cs_id == 1) ? 0 : 1; + SPIMEM0.misc.cs0_dis = (cs_id == PSRAM_LL_CS_ID_0) ? 0 : 1; + SPIMEM0.misc.cs1_dis = (cs_id == PSRAM_LL_CS_ID_1) ? 0 : 1; } /** diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 0284406515..40acf52bf0 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -103,6 +103,10 @@ config SOC_ECDSA_SUPPORTED bool default y +config SOC_SPIRAM_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y diff --git a/components/soc/esp32c61/include/soc/io_mux_reg.h b/components/soc/esp32c61/include/soc/io_mux_reg.h index ea9dcaf0fc..ef551d6861 100644 --- a/components/soc/esp32c61/include/soc/io_mux_reg.h +++ b/components/soc/esp32c61/include/soc/io_mux_reg.h @@ -130,6 +130,7 @@ extern "C" { #define SPI_CLK_GPIO_NUM 20 #define SPI_D_GPIO_NUM 21 #define SPI_Q_GPIO_NUM 16 +#define SPI_CS1_GPIO_NUM 14 #define USB_INT_PHY0_DM_GPIO_NUM 12 #define USB_INT_PHY0_DP_GPIO_NUM 13 diff --git a/components/soc/esp32c61/include/soc/soc.h b/components/soc/esp32c61/include/soc/soc.h index c2317dec73..97d0eafd5c 100644 --- a/components/soc/esp32c61/include/soc/soc.h +++ b/components/soc/esp32c61/include/soc/soc.h @@ -192,7 +192,7 @@ #define SOC_MEM_INTERNAL_LOW1 0x40800000 #define SOC_MEM_INTERNAL_HIGH1 0x40850000 -#define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space +#define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) ///< Largest span of contiguous memory in the address space // Region of address space that holds peripherals #define SOC_PERIPHERAL_LOW 0x60000000 diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index f3bedfa321..fc316f7ef5 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -68,6 +68,7 @@ // \#define SOC_LP_I2C_SUPPORTED 0 //TODO: [ESP32C61] IDF-9330, IDF-9337 // \#define SOC_PM_SUPPORTED 1 #define SOC_ECDSA_SUPPORTED 1 +#define SOC_SPIRAM_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 From fad2c740b1d1d7aa241e670e6c3f1a5dfad32f67 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 16 Aug 2024 12:11:58 +0800 Subject: [PATCH 2/3] 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 */ From 271ca9f85ac63d27c7580c68028b16fdb9d61836 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Mon, 19 Aug 2024 12:20:11 +0800 Subject: [PATCH 3/3] feat(spiram): Add .noinit and .bss segement support on esp32c61 --- .../test_apps/.build-test-rules.yml | 3 -- .../esp_psram/test_apps/.build-test-rules.yml | 4 -- .../esp_system/ld/esp32c5/sections.ld.in | 2 +- .../esp_system/ld/esp32c61/memory.ld.in | 3 ++ .../esp_system/ld/esp32c61/sections.ld.in | 40 +++++++++++++++++++ .../esp_system/ld/esp32p4/sections.ld.in | 2 +- .../esp_system/ld/esp32s3/sections.ld.in | 2 +- .../soc/esp32c61/include/soc/clk_tree_defs.h | 1 + docs/docs_not_updated/esp32c5.txt | 1 - docs/docs_not_updated/esp32c61.txt | 1 - 10 files changed, 47 insertions(+), 12 deletions(-) diff --git a/components/esp_common/test_apps/.build-test-rules.yml b/components/esp_common/test_apps/.build-test-rules.yml index 41f3dd4ef0..c52d810e15 100644 --- a/components/esp_common/test_apps/.build-test-rules.yml +++ b/components/esp_common/test_apps/.build-test-rules.yml @@ -4,6 +4,3 @@ components/esp_common/test_apps/esp_common: disable: - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "psram_noinit" and SOC_SPIRAM_SUPPORTED != 1 - - if: CONFIG_NAME == "psram_noinit" and IDF_TARGET in ["esp32c61"] - temporary: true - reason: esp32c61 is not supported yet # TODO: IDF-9293 diff --git a/components/esp_psram/test_apps/.build-test-rules.yml b/components/esp_psram/test_apps/.build-test-rules.yml index b815394dba..88e2708734 100644 --- a/components/esp_psram/test_apps/.build-test-rules.yml +++ b/components/esp_psram/test_apps/.build-test-rules.yml @@ -3,10 +3,6 @@ components/esp_psram/test_apps/psram: disable: - if: SOC_SPIRAM_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET in ["esp32c61"] - temporary: true - reason: No runner depends_components: - esp_psram - esp_mm diff --git a/components/esp_system/ld/esp32c5/sections.ld.in b/components/esp_system/ld/esp32c5/sections.ld.in index 98c7f07519..7ebf3390dc 100644 --- a/components/esp_system/ld/esp32c5/sections.ld.in +++ b/components/esp_system/ld/esp32c5/sections.ld.in @@ -391,7 +391,7 @@ SECTIONS { . = ORIGIN(extern_ram_seg); . = . + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (0x10000); + . = ALIGN (_esp_mmu_page_size); } > extern_ram_seg #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY diff --git a/components/esp_system/ld/esp32c61/memory.ld.in b/components/esp_system/ld/esp32c61/memory.ld.in index d44779d39a..d352f7fc6f 100644 --- a/components/esp_system/ld/esp32c61/memory.ld.in +++ b/components/esp_system/ld/esp32c61/memory.ld.in @@ -78,6 +78,9 @@ MEMORY The aim of this is to keep data that will not be moved around and have a fixed address. */ lp_reserved_seg(RW) : org = 0x50000000 + 0x4000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM + + /* PSRAM seg */ + extern_ram_seg(RWX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20 } /* Heap ends at top of sram_seg */ diff --git a/components/esp_system/ld/esp32c61/sections.ld.in b/components/esp_system/ld/esp32c61/sections.ld.in index de877d27b7..a6db96dbb7 100644 --- a/components/esp_system/ld/esp32c61/sections.ld.in +++ b/components/esp_system/ld/esp32c61/sections.ld.in @@ -379,6 +379,46 @@ SECTIONS } > default_rodata_seg ASSERT_SECTIONS_GAP(.flash.rodata, .eh_frame_hdr) + + /* External RAM */ + /** + * This section is required to skip flash sections, because `extern_ram_seg` + * and `drom_seg` / `irom_seg` are on the same bus when app build use flash sections + */ + .ext_ram.dummy (NOLOAD): + { + . = ORIGIN(extern_ram_seg); + . = . + (_rodata_reserved_end - _flash_rodata_dummy_start); + . = ALIGN (_esp_mmu_page_size); + } > extern_ram_seg + +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + /* This section holds .ext_ram.bss data, and will be put in PSRAM */ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + mapping[extern_ram] + + ALIGNED_SYMBOL(4, _ext_ram_bss_end) + } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * This section holds data that won't be initialized when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + ALIGNED_SYMBOL(4, _ext_ram_noinit_end) + } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + .eh_frame_hdr : { #if CONFIG_COMPILER_CXX_EXCEPTIONS || CONFIG_ESP_SYSTEM_USE_EH_FRAME diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index e9a6833cfc..0a48714d3e 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -483,7 +483,7 @@ SECTIONS .ext_ram.dummy (NOLOAD): { . = ORIGIN(ext_ram_seg) + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (0x10000); + . = ALIGN (_esp_mmu_page_size); } > ext_ram_seg #endif //CONFIG_SPIRAM_XIP_FROM_PSRAM diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 527f8b9350..499a117a98 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -436,7 +436,7 @@ SECTIONS { . = ORIGIN(extern_ram_seg); . = . + (_rodata_reserved_end - _flash_rodata_dummy_start); - . = ALIGN (0x10000); + . = ALIGN (_esp_mmu_page_size); } > extern_ram_seg #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY diff --git a/components/soc/esp32c61/include/soc/clk_tree_defs.h b/components/soc/esp32c61/include/soc/clk_tree_defs.h index e5616319b5..540dbd419d 100644 --- a/components/soc/esp32c61/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c61/include/soc/clk_tree_defs.h @@ -355,6 +355,7 @@ 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_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select PLL_F64M as the default clock choice */ MSPI_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */ } soc_periph_mspi_clk_src_t; diff --git a/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index a6042ed486..1e9a0dd763 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -34,7 +34,6 @@ api-guides/esp-ble-mesh/ble-mesh-feature-list.rst api-guides/esp-ble-mesh/ble-mesh-terminology.rst api-guides/esp-ble-mesh/ble-mesh-architecture.rst api-guides/esp-ble-mesh/ble-mesh-faq.rst -api-guides/external-ram.rst api-guides/wifi-security.rst api-guides/openthread.rst third-party-tools/platformio.rst diff --git a/docs/docs_not_updated/esp32c61.txt b/docs/docs_not_updated/esp32c61.txt index 40c05dd997..6ec2fcb557 100644 --- a/docs/docs_not_updated/esp32c61.txt +++ b/docs/docs_not_updated/esp32c61.txt @@ -44,7 +44,6 @@ api-guides/esp-ble-mesh/ble-mesh-feature-list.rst api-guides/esp-ble-mesh/ble-mesh-terminology.rst api-guides/esp-ble-mesh/ble-mesh-architecture.rst api-guides/esp-ble-mesh/ble-mesh-faq.rst -api-guides/external-ram.rst api-guides/wifi-security.rst api-guides/index.rst api-guides/openthread.rst