From 6d4c0bb3aa773893d49bbeb96c86d8f0b57883f6 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 28 Mar 2023 17:03:47 +0800 Subject: [PATCH] mspi: support 120M DDR flash and psram on S3 (experimental) --- .../esp_hw_support/mspi_timing_config.h | 50 +++---- .../esp_hw_support/mspi_timing_tuning.c | 128 ++++++++++++++++-- .../port/esp32s3/mspi_timing_config.c | 23 ++-- .../port/esp32s3/mspi_timing_tuning_configs.h | 22 +++ .../test_apps/mspi/sdkconfig.ci.f8r8_120ddr | 6 + .../mspi/sdkconfig.ci.f8r8_120ddr_120ddr | 10 ++ .../test_apps/mspi/sdkconfig.defaults | 5 +- components/esp_psram/esp32s3/Kconfig.spiram | 1 - components/esptool_py/Kconfig.projbuild | 2 +- .../hal/esp32s3/include/hal/clk_tree_ll.h | 40 ++++++ .../hal/esp32s3/include/hal/spimem_flash_ll.h | 3 + 11 files changed, 234 insertions(+), 56 deletions(-) create mode 100644 components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr create mode 100644 components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr_120ddr diff --git a/components/esp_hw_support/mspi_timing_config.h b/components/esp_hw_support/mspi_timing_config.h index 16ea72789a..78de3dadf9 100644 --- a/components/esp_hw_support/mspi_timing_config.h +++ b/components/esp_hw_support/mspi_timing_config.h @@ -139,43 +139,45 @@ void mspi_timing_config_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t le /*------------------------------------------------------------------------------------------------- * SPI1 Timing Tuning APIs - * These APIs are only used in `spi_flash_timing_tuning.c/sweep_for_success_sample_points()` for - * configuring SPI1 timing tuning related registers to find best tuning parameter + * + * These APIs are only used in `mspi_timing_tuning.c` for configuring SPI1 timing + * tuning related registers to find best tuning parameter for Flash and PSRAM *-------------------------------------------------------------------------------------------------*/ /** - * @brief Tune Flash Din Mode and Num of SPI1 - * @param din_mode Din mode - * @param din_num Din num + * @brief Tune Flash timing registers for SPI1 accessing Flash + * + * @param[in] params Timing parameters */ -void mspi_timing_config_flash_tune_din_num_mode(uint8_t din_mode, uint8_t din_num); +void mspi_timing_config_flash_set_tuning_regs(const mspi_timing_tuning_param_t *params); /** - * @brief Tune Flash extra dummy of SPI1 - * @param extra_dummy extra dummy bits + * @brief Tune PSRAM timing registers for SPI1 accessing PSRAM + * + * @param[in] params Timing parameters + */ +void mspi_timing_config_psram_set_tuning_regs(const mspi_timing_tuning_param_t *params); + + +/*------------------------------------------------------------------------------------------------- + * APIs for coordination with ESP Flash driver + *-------------------------------------------------------------------------------------------------*/ +/** + * SPI1 register info get APIs. These APIs inform `mspi_timing_tuning.c` (driver layer) of the SPI1 flash settings. + * In this way, other components (e.g.: esp_flash driver) can get the info from it (`mspi_timing_tuning.c`). */ -void mspi_timing_config_flash_tune_dummy(uint8_t extra_dummy); /** - * @brief Tune PSRAM Din Mode and Num of SPI1 - * @param din_mode Din mode - * @param din_num Din num - */ -void mspi_timing_config_psram_tune_din_num_mode(uint8_t din_mode, uint8_t din_num); - -/** - * @brief Tune PSRAM extra dummy of SPI1 - * @param extra_dummy extra dummy bits - */ -void mspi_timing_config_psram_tune_dummy(uint8_t extra_dummy); - -/** - * SPI1 register info get APIs. These APIs inform `spi_flash_timing_tuning.c` (driver layer) of the SPI1 flash settings. - * In this way, other components (e.g.: esp_flash driver) can get the info from it (`spi_flash_timing_tuning.c`). + * @brief Get CS timing + * + * @param[out] setup_time Setup time + * @param[out] hold_time Hold time */ void mspi_timing_config_get_cs_timing(uint8_t *setup_time, uint32_t *hold_time); /** * @brief Get Flash clock reg val + * + * @return Flash clock reg val */ uint32_t mspi_timing_config_get_flash_clock_reg(void); diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index ee565b353f..64f05074b9 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -15,8 +15,11 @@ #include "soc/io_mux_reg.h" #include "esp_private/mspi_timing_tuning.h" #include "soc/soc.h" +#include "soc/rtc.h" #include "hal/spi_flash_hal.h" #include "hal/mspi_timing_tuning_ll.h" +#include "hal/clk_tree_ll.h" +#include "hal/regi2c_ctrl_ll.h" #include "mspi_timing_config.h" #if CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/cache.h" @@ -107,7 +110,7 @@ static void init_spi1_for_tuning(bool is_flash) * We use different SPI1 timing tuning config to read data to see if current MSPI sampling is successful. * The sampling result will be stored in an array. In this array, successful item will be 1, failed item will be 0. */ -static void sweep_for_success_sample_points(uint8_t *reference_data, const mspi_timing_config_t *config, bool is_flash, uint8_t *out_array) +static void sweep_for_success_sample_points(const uint8_t *reference_data, const mspi_timing_config_t *config, bool is_flash, uint8_t *out_array) { uint32_t config_idx = 0; uint8_t read_data[MSPI_TIMING_TEST_DATA_LEN] = {0}; @@ -116,20 +119,21 @@ static void sweep_for_success_sample_points(uint8_t *reference_data, const mspi_ memset(read_data, 0, MSPI_TIMING_TEST_DATA_LEN); #if MSPI_TIMING_FLASH_NEEDS_TUNING if (is_flash) { - mspi_timing_config_flash_tune_din_num_mode(config->tuning_config_table[config_idx].spi_din_mode, config->tuning_config_table[config_idx].spi_din_num); - mspi_timing_config_flash_tune_dummy(config->tuning_config_table[config_idx].extra_dummy_len); + mspi_timing_config_flash_set_tuning_regs(&(config->tuning_config_table[config_idx])); mspi_timing_config_flash_read_data(read_data, MSPI_TIMING_FLASH_TEST_DATA_ADDR, sizeof(read_data)); } #endif #if MSPI_TIMING_PSRAM_NEEDS_TUNING if (!is_flash) { - mspi_timing_config_psram_tune_din_num_mode(config->tuning_config_table[config_idx].spi_din_mode, config->tuning_config_table[config_idx].spi_din_num); - mspi_timing_config_psram_tune_dummy(config->tuning_config_table[config_idx].extra_dummy_len); + mspi_timing_config_psram_set_tuning_regs(&(config->tuning_config_table[config_idx])); mspi_timing_config_psram_read_data(read_data, MSPI_TIMING_PSRAM_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); } #endif if (memcmp(reference_data, read_data, sizeof(read_data)) == 0) { out_array[config_idx] = 1; + ESP_EARLY_LOGD(TAG, "%d, good", config_idx); + } else { + ESP_EARLY_LOGD(TAG, "%d, bad", config_idx); } } } @@ -164,14 +168,77 @@ static void find_max_consecutive_success_points(uint8_t *array, uint32_t size, u *out_end_index = match_num == size ? size : end; } +#if (MSPI_TIMING_FLASH_DTR_MODE || MSPI_TIMING_PSRAM_DTR_MODE) && (MSPI_TIMING_CORE_CLOCK_MHZ == 240) +static bool get_working_pll_freq(const uint8_t *reference_data, bool is_flash, uint32_t *out_max_freq, uint32_t *out_min_freq) +{ + uint8_t read_data[MSPI_TIMING_TEST_DATA_LEN] = {0}; + rtc_cpu_freq_config_t previous_config; + rtc_clk_cpu_freq_get_config(&previous_config); + + uint32_t big_num = MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MAX * 2; //This number should be larger than MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MAX, for error handling + uint32_t max_freq = 0; + uint32_t min_freq = big_num; + rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); + + //BBPLL CALIBRATION START + regi2c_ctrl_ll_bbpll_calibration_start(); + for (int pll_mhz_tuning = MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MIN; pll_mhz_tuning <= MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MAX; pll_mhz_tuning += 8) { + /** + * pll_mhz = xtal_mhz * (oc_div + 4) / (oc_ref_div + 1) + */ + clk_ll_bbpll_set_frequency_for_mspi_tuning(xtal_freq, pll_mhz_tuning, ((pll_mhz_tuning / 4) - 4), 9); + + memset(read_data, 0, MSPI_TIMING_TEST_DATA_LEN); + if (is_flash) { + mspi_timing_config_flash_read_data(read_data, MSPI_TIMING_FLASH_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); + } else { + mspi_timing_config_psram_read_data(read_data, MSPI_TIMING_PSRAM_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); + } + + if (memcmp(read_data, reference_data, MSPI_TIMING_TEST_DATA_LEN) == 0) { + max_freq = MAX(pll_mhz_tuning, max_freq); + min_freq = MIN(pll_mhz_tuning, min_freq); + + //Continue to find successful cases + continue; + } + + if (max_freq != 0) { + //The first fail case after successful case(s) is the end + break; + } + + //If no break, no successful case found, continue to find successful cases + } + + //restore PLL config + clk_ll_bbpll_set_freq_mhz(previous_config.source_freq_mhz); + clk_ll_bbpll_set_config(previous_config.source_freq_mhz, xtal_freq); + + //WAIT CALIBRATION DONE + while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + + //BBPLL CALIBRATION STOP + regi2c_ctrl_ll_bbpll_calibration_stop(); + + + *out_max_freq = max_freq; + *out_min_freq = min_freq; + + return (max_freq != 0); +} +#endif //Frequency Scanning + #if MSPI_TIMING_FLASH_DTR_MODE || MSPI_TIMING_PSRAM_DTR_MODE -static uint32_t select_best_tuning_config_dtr(mspi_timing_config_t *config, uint32_t consecutive_length, uint32_t end) +static uint32_t select_best_tuning_config_dtr(mspi_timing_config_t *config, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_flash) { #if (MSPI_TIMING_CORE_CLOCK_MHZ == 160) //Core clock 160M DTR best point scheme - uint32_t best_point; + (void) reference_data; + (void) is_flash; + uint32_t best_point = 0; - //Define these magic number in macros in `spi_timing_config.h`. TODO: IDF-3663 + //These numbers will probably be same on other chips, if this version of algorithm is utilised if (consecutive_length <= 2 || consecutive_length >= 6) { //tuning is FAIL, select default point, and generate a warning best_point = config->default_config_id; @@ -187,6 +254,41 @@ static uint32_t select_best_tuning_config_dtr(mspi_timing_config_t *config, uint } return best_point; + +#elif (MSPI_TIMING_CORE_CLOCK_MHZ == 240) + + uint32_t best_point = 0; + uint32_t current_point = end + 1 - consecutive_length; + bool ret = false; + + //This `max_freq` is the max pll frequency that per MSPI timing tuning config can work + uint32_t max_freq = 0; + uint32_t temp_max_freq = 0; + uint32_t temp_min_freq = 0; + + for (; current_point <= end; current_point++) { + if (is_flash) { + mspi_timing_config_flash_set_tuning_regs(&(config->tuning_config_table[current_point])); + } else { + mspi_timing_config_psram_set_tuning_regs(&(config->tuning_config_table[current_point])); + } + + ret = get_working_pll_freq(reference_data, is_flash, &temp_max_freq, &temp_min_freq); + if (ret && temp_min_freq <= MSPI_TIMING_PLL_FREQ_SCAN_THRESH_MHZ_LOW && temp_max_freq >= MSPI_TIMING_PLL_FREQ_SCAN_THRESH_MHZ_HIGH && temp_max_freq > max_freq) { + max_freq = temp_max_freq; + best_point = current_point; + } + ESP_EARLY_LOGD(TAG, "sample point %d, max pll is %d mhz, min pll is %d\n", current_point, temp_max_freq, temp_min_freq); + } + if (max_freq == 0) { + ESP_EARLY_LOGW(TAG, "freq scan tuning fail, best point is fallen back to index %d", end + 1 - consecutive_length); + best_point = end + 1 - consecutive_length; + } else { + ESP_EARLY_LOGD(TAG, "freq scan success, max pll is %dmhz, best point is index %d", max_freq, best_point); + } + + return best_point; + #else //won't reach here abort(); @@ -221,19 +323,19 @@ static uint32_t select_best_tuning_config_str(mspi_timing_config_t *config, uint } #endif -static void select_best_tuning_config(mspi_timing_config_t *config, uint32_t consecutive_length, uint32_t end, bool is_flash) +static void select_best_tuning_config(mspi_timing_config_t *config, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_flash) { uint32_t best_point = 0; if (is_flash) { #if MSPI_TIMING_FLASH_DTR_MODE - best_point = select_best_tuning_config_dtr(config, consecutive_length, end); + best_point = select_best_tuning_config_dtr(config, consecutive_length, end, reference_data, is_flash); #elif MSPI_TIMING_FLASH_STR_MODE best_point = select_best_tuning_config_str(config, consecutive_length, end); #endif s_flash_best_timing_tuning_config = config->tuning_config_table[best_point]; } else { #if MSPI_TIMING_PSRAM_DTR_MODE - best_point = select_best_tuning_config_dtr(config, consecutive_length, end); + best_point = select_best_tuning_config_dtr(config, consecutive_length, end, reference_data, is_flash); #elif MSPI_TIMING_PSRAM_STR_MODE best_point = select_best_tuning_config_str(config, consecutive_length, end); #endif @@ -241,7 +343,7 @@ static void select_best_tuning_config(mspi_timing_config_t *config, uint32_t con } } -static void do_tuning(uint8_t *reference_data, mspi_timing_config_t *timing_config, bool is_flash) +static void do_tuning(const uint8_t *reference_data, mspi_timing_config_t *timing_config, bool is_flash) { /** * We use SPI1 to tune the timing: @@ -256,7 +358,7 @@ static void do_tuning(uint8_t *reference_data, mspi_timing_config_t *timing_conf init_spi1_for_tuning(is_flash); sweep_for_success_sample_points(reference_data, timing_config, is_flash, sample_result); find_max_consecutive_success_points(sample_result, MSPI_TIMING_CONFIG_NUM_DEFAULT, &consecutive_length, &last_success_point); - select_best_tuning_config(timing_config, consecutive_length, last_success_point, is_flash); + select_best_tuning_config(timing_config, consecutive_length, last_success_point, reference_data, is_flash); } #endif //#if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING diff --git a/components/esp_hw_support/port/esp32s3/mspi_timing_config.c b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c index 4f09c31604..7beecc59c1 100644 --- a/components/esp_hw_support/port/esp32s3/mspi_timing_config.c +++ b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c @@ -290,40 +290,33 @@ void mspi_timing_config_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t le * These APIs are only used in `spi_flash_timing_tuning.c/sweep_for_success_sample_points()` for * configuring SPI1 timing tuning related registers to find best tuning parameter *-------------------------------------------------------------------------------------------------*/ -void mspi_timing_config_flash_tune_din_num_mode(uint8_t din_mode, uint8_t din_num) +void mspi_timing_config_flash_set_tuning_regs(const mspi_timing_tuning_param_t *params) { /** * 1. SPI_MEM_DINx_MODE(1), SPI_MEM_DINx_NUM(1) are meaningless * SPI0 and SPI1 share the SPI_MEM_DINx_MODE(0), SPI_MEM_DINx_NUM(0) for FLASH timing tuning * 2. We use SPI1 to get the best Flash timing tuning (mode and num) config */ - mspi_timing_config_flash_set_din_mode_num(0, din_mode, din_num); + mspi_timing_config_flash_set_din_mode_num(0, params->spi_din_mode, params->spi_din_num); + mspi_timing_config_flash_set_extra_dummy(1, params->extra_dummy_len); } -void mspi_timing_config_flash_tune_dummy(uint8_t extra_dummy) -{ - mspi_timing_config_flash_set_extra_dummy(1, extra_dummy); -} - -void mspi_timing_config_psram_tune_din_num_mode(uint8_t din_mode, uint8_t din_num) +void mspi_timing_config_psram_set_tuning_regs(const mspi_timing_tuning_param_t *params) { /** * 1. SPI_MEM_SPI_SMEM_DINx_MODE(1), SPI_MEM_SPI_SMEM_DINx_NUM(1) are meaningless * SPI0 and SPI1 share the SPI_MEM_SPI_SMEM_DINx_MODE(0), SPI_MEM_SPI_SMEM_DINx_NUM(0) for PSRAM timing tuning * 2. We use SPI1 to get the best PSRAM timing tuning (mode and num) config */ - mspi_timing_config_psram_set_din_mode_num(0, din_mode, din_num); -} + mspi_timing_config_psram_set_din_mode_num(0, params->spi_din_mode, params->spi_din_num); -void mspi_timing_config_psram_tune_dummy(uint8_t extra_dummy) -{ #if CONFIG_SPIRAM_MODE_OCT //On 728, for SPI1, flash and psram share the extra dummy register - mspi_timing_config_flash_set_extra_dummy(1, extra_dummy); + mspi_timing_config_flash_set_extra_dummy(1, params->extra_dummy_len); #elif CONFIG_SPIRAM_MODE_QUAD //Update this `s_psram_extra_dummy`, the `s_psram_read_data` will set dummy according to this `s_psram_extra_dummy` - s_psram_extra_dummy = extra_dummy; - mspi_timing_ll_set_quad_flash_dummy(1, extra_dummy - 1); + s_psram_extra_dummy = params->extra_dummy_len; + mspi_timing_ll_set_quad_flash_dummy(1, s_psram_extra_dummy - 1); #endif } diff --git a/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h b/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h index 3a538ae387..274dbd3dec 100644 --- a/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h +++ b/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h @@ -128,6 +128,11 @@ #endif #endif //PSRAM 120M STR +//PSRAM 120M STR +#if MSPI_TIMING_PSRAM_DTR_MODE && CONFIG_SPIRAM_SPEED_120M +#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 240 +#endif //PSRAM 120M DTR + //------------------------------------------Determine the Core Clock-----------------------------------------------// /** @@ -233,3 +238,20 @@ ESP_STATIC_ASSERT(CHECK_POWER_OF_2(MSPI_TIMING_CORE_CLOCK_MHZ / MSPI_TIMING_PSRA #define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE {{2, 0, 1}, {0, 0, 0}, {2, 2, 2}, {1, 0, 1}, {2, 0, 2}, {0, 0, 1}, {2, 2, 3}, {1, 0, 2}, {2, 0, 3}, {0, 0, 2}, {2, 2, 4}, {1, 0, 3}} #define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 12 #define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 2 + +//PSRAM: core clock 240M, module clock 120M, DTR mode +#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_240M_MODULE_CLK_120M_DTR_MODE {{0, 0, 0}, {4, 1, 2}, {1, 0, 1}, {4, 0, 2}, {0, 0, 1}, {4, 1, 3}, {1, 0, 2}, {4, 0, 3}, {0, 0, 2}, {4, 1, 4}, {1, 0, 3}, {4, 0, 4}, {0, 0, 3}, {4, 1, 5}} +#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_DTR_MODE 14 +#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_120M_DTR_MODE 1 + +//------------------------------------------Frequency Scanning Related-----------------------------------------------// +/** + * On ESP32S3, only module clock 120M, DDR mode needs frequency scan. Frequency scanning is to get the max workable PLL + * frequency under each successfull timing tuning configuration. PLL frequency may fluctuate under high temperature, + * this method is to get the tuning configuration that can work under higher PLL frequency. + */ +#define MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MIN 440 +#define MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MAX 600 +#define MSPI_TIMING_PLL_FREQ_SCAN_THRESH_MHZ_LOW 448 +#define MSPI_TIMING_PLL_FREQ_SCAN_THRESH_MHZ_HIGH 520 +#define MSPI_TIMING_PLL_FREQ_SCAN_STEP_MHZ_MODULE_CLK_120M 8 diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr new file mode 100644 index 0000000000..9289b41d45 --- /dev/null +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr @@ -0,0 +1,6 @@ +# F8R8, Flash 120M DDR, PSRAM disable + +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr_120ddr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr_120ddr new file mode 100644 index 0000000000..290f4c92d9 --- /dev/null +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_120ddr_120ddr @@ -0,0 +1,10 @@ +# F8R8, Flash 120M DDR, PSRAM 120M DDR + +CONFIG_ESPTOOLPY_OCT_FLASH=y +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_120M=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.defaults b/components/esp_hw_support/test_apps/mspi/sdkconfig.defaults index 8e11bd6bd3..1a9b8b56c1 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.defaults +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.defaults @@ -1,5 +1,6 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_ESP_TASK_WDT_EN=n -CONFIG_SPIRAM_RODATA=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/components/esp_psram/esp32s3/Kconfig.spiram b/components/esp_psram/esp32s3/Kconfig.spiram index 771019c600..08fee9fd81 100644 --- a/components/esp_psram/esp32s3/Kconfig.spiram +++ b/components/esp_psram/esp32s3/Kconfig.spiram @@ -82,7 +82,6 @@ menu "SPI RAM config" Select the speed for the SPI RAM chip. config SPIRAM_SPEED_120M - depends on SPIRAM_MODE_QUAD bool "120MHz clock speed" config SPIRAM_SPEED_80M bool "80MHz clock speed" diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 15eab2919a..48b1ab6ebe 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -95,7 +95,7 @@ menu "Serial flasher config" config ESPTOOLPY_FLASHFREQ_120M bool "120 MHz" select SPI_FLASH_HPM_ENABLE - depends on SOC_MEMSPI_SRC_FREQ_120M && ESPTOOLPY_FLASH_SAMPLE_MODE_STR + depends on SOC_MEMSPI_SRC_FREQ_120M config ESPTOOLPY_FLASHFREQ_80M bool "80 MHz" depends on SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED diff --git a/components/hal/esp32s3/include/hal/clk_tree_ll.h b/components/hal/esp32s3/include/hal/clk_tree_ll.h index c2534134a7..c333775d6b 100644 --- a/components/hal/esp32s3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s3/include/hal/clk_tree_ll.h @@ -12,6 +12,7 @@ #include "soc/rtc.h" #include "soc/system_reg.h" #include "soc/rtc_cntl_reg.h" +#include "soc/regi2c_defs.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_bbpll.h" #include "hal/assert.h" @@ -682,6 +683,45 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v return REG_READ(RTC_SLOW_CLK_CAL_REG); } +/** + * @brief Configure PLL frequency for MSPI timing tuning + * @note Only used by the MSPI Timing tuning driver + * + * @param xtal_freq Xtal frequency + * @param pll_freq PLL frequency + * @param oc_div OC divider + * @param oc_ref_div OC ref divider + */ +static inline __attribute__((always_inline)) +void clk_ll_bbpll_set_frequency_for_mspi_tuning(rtc_xtal_freq_t xtal_freq, int pll_freq, uint8_t oc_div, uint8_t oc_ref_div) +{ + HAL_ASSERT(xtal_freq == RTC_XTAL_FREQ_40M); + uint32_t pll_reg = GET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD | + RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD); + HAL_ASSERT(pll_reg == 0); + + /* Set this register to let the digital part know 480M PLL is used */ + SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL); + uint8_t dr1 = 0; + uint8_t dr3 = 0; + uint8_t dchgp = 5; + uint8_t dcur = 3; + uint8_t dbias = 2; + uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (oc_ref_div); + uint8_t i2c_bbpll_div_7_0 = oc_div; + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B); + + uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); + REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 3); + REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/spimem_flash_ll.h b/components/hal/esp32s3/include/hal/spimem_flash_ll.h index 3c325bf839..4e8d5744f6 100644 --- a/components/hal/esp32s3/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32s3/include/hal/spimem_flash_ll.h @@ -575,6 +575,9 @@ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void) case 2: clock_val = 160; break; + case 3: + clock_val = 240; + break; default: abort(); }