Skip to content

Commit dadcc7b

Browse files
committed
Merge branch 'feat/c5_eco2_psram_timing_tuning' into 'master'
mspi: psram 80M timing tuning on C5 ECO2 Closes IDF-13003 See merge request espressif/esp-idf!39232
2 parents 5133b89 + 7d5f89f commit dadcc7b

File tree

25 files changed

+970
-53
lines changed

25 files changed

+970
-53
lines changed

components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c5.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void IRAM_ATTR bootloader_init_mspi_clock(void)
5555
// SPLL clock on C5 is 480MHz , and mspi_pll needs 80MHz
5656
// in this stage, set divider as 6
5757
_mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_SPLL);
58-
mspi_ll_fast_set_hs_divider(6);
58+
mspi_timing_ll_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT);
5959
}
6060

6161
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)

components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void IRAM_ATTR bootloader_init_mspi_clock(void)
5252
// SPLL clock on C61 is 480MHz , and mspi_pll needs 80MHz
5353
// in this stage, set divider as 6
5454
_mspi_timing_ll_set_flash_clk_src(0, FLASH_CLK_SRC_DEFAULT);
55-
mspi_ll_fast_set_hs_divider(6);
55+
mspi_timing_ll_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT);
5656
}
5757

5858
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t *pfhdr)

components/esp_hw_support/CMakeLists.txt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,17 @@ if(NOT non_os_build)
134134

135135
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
136136
list(APPEND srcs "mspi_timing_tuning/mspi_timing_tuning.c")
137-
if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY)
138-
list(APPEND srcs "mspi_timing_tuning/mspi_timing_by_mspi_delay.c")
137+
if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY AND NOT CONFIG_IDF_TARGET_ESP32S3)
138+
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c")
139+
list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c")
140+
endif()
139141
endif()
142+
140143
if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS)
141-
list(APPEND srcs "mspi_timing_tuning/mspi_timing_by_dqs.c")
144+
list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_dqs.c")
142145
endif()
143146
if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY)
144-
list(APPEND srcs "mspi_timing_tuning/mspi_timing_by_flash_delay.c")
147+
list(APPEND srcs "mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_flash_delay.c")
145148
endif()
146149
endif()
147150

@@ -171,7 +174,8 @@ endif()
171174

172175
set(public_include_dirs "include" "include/soc" "include/soc/${target}"
173176
"dma/include" "ldo/include" "debug_probe/include"
174-
"mspi_timing_tuning/include" "power_supply/include")
177+
"mspi_timing_tuning/include" "mspi_timing_tuning/tuning_scheme_impl/include"
178+
"power_supply/include")
175179

176180
if(CONFIG_IDF_TARGET_ESP32H4)
177181
list(REMOVE_ITEM srcs

components/esp_hw_support/mspi_timing_tuning/mspi_timing_tuning.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
#include "esp_private/esp_cache_private.h"
1919
#include "esp_private/mspi_timing_tuning.h"
2020
#include "esp_private/mspi_timing_config.h"
21-
#include "mspi_timing_by_mspi_delay.h"
22-
#include "mspi_timing_by_dqs.h"
23-
#include "mspi_timing_by_flash_delay.h"
21+
#include "esp_private/mspi_timing_by_mspi_delay.h"
22+
#include "esp_private/mspi_timing_by_dqs.h"
23+
#include "esp_private/mspi_timing_by_flash_delay.h"
2424
#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY || SOC_MEMSPI_TIMING_TUNING_BY_DQS || SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY
2525
#include "mspi_timing_tuning_configs.h"
2626
#endif
@@ -233,6 +233,9 @@ static void s_sweep_for_success_sample_points(uint8_t *reference_data, void *con
233233
#endif
234234
if (memcmp(reference_data, read_data, sizeof(read_data)) == 0) {
235235
out_array[config_idx] += 1;
236+
ESP_EARLY_LOGV(TAG, "config_idx: %d, good", config_idx);
237+
} else {
238+
ESP_EARLY_LOGV(TAG, "config_idx: %d, bad", config_idx);
236239
}
237240
}
238241
}
@@ -619,9 +622,8 @@ void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing
619622
*----------------------------------------------------------------------------*/
620623
void mspi_timing_set_pin_drive_strength(void)
621624
{
622-
#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY
623-
//For now, set them all to 3. Need to check after QVL test results are out. TODO: IDF-3663
625+
#if CONFIG_IDF_TARGET_ESP32S3
624626
//Set default pin drive
625627
mspi_timing_ll_set_all_pin_drive(0, 3);
626-
#endif // #if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY
628+
#endif
627629
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
target_include_directories(${COMPONENT_LIB} PUBLIC . include)
2+
3+
set(srcs)
4+
5+
if(NOT BOOTLOADER_BUILD)
6+
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
7+
list(APPEND srcs "mspi_timing_config.c")
8+
endif()
9+
endif()
10+
11+
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <sys/param.h>
8+
#include "sdkconfig.h"
9+
#include "esp_attr.h"
10+
#include "esp_err.h"
11+
#include "esp_types.h"
12+
#include "esp_log.h"
13+
#include "soc/soc_caps.h"
14+
#include "esp_private/periph_ctrl.h"
15+
#include "esp_private/mspi_timing_config.h"
16+
#include "mspi_timing_tuning_configs.h"
17+
#include "hal/psram_ctrlr_ll.h"
18+
#include "hal/mspi_ll.h"
19+
20+
#define FLASH_LOW_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT
21+
#define FLASH_HIGH_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_CORE_CLOCK_MHZ
22+
#define PSRAM_LOW_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT
23+
#define PSRAM_HIGH_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_CORE_CLOCK_MHZ
24+
25+
const static char *TAG = "MSPI Timing";
26+
27+
//-------------------------------------MSPI Clock Setting-------------------------------------//
28+
static void s_mspi_flash_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
29+
{
30+
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
31+
}
32+
33+
static void s_mspi_psram_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
34+
{
35+
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
36+
}
37+
38+
void mspi_timing_config_set_flash_clock(uint32_t flash_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi)
39+
{
40+
uint32_t core_clock_mhz = 0;
41+
if (speed_mode == MSPI_TIMING_SPEED_MODE_LOW_PERF) {
42+
core_clock_mhz = FLASH_LOW_SPEED_CORE_CLOCK_MHZ;
43+
} else {
44+
core_clock_mhz = FLASH_HIGH_SPEED_CORE_CLOCK_MHZ;
45+
}
46+
//SPI0 and SPI1 share the register for core clock. So we only set SPI0 here.
47+
s_mspi_flash_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, core_clock_mhz);
48+
49+
uint32_t freqdiv = core_clock_mhz / flash_freq_mhz;
50+
ESP_EARLY_LOGV(TAG, "flash freqdiv: %d", freqdiv);
51+
assert(freqdiv > 0);
52+
uint32_t reg_val = mspi_timing_ll_calculate_clock_reg(freqdiv);
53+
mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_0, reg_val);
54+
if (control_both_mspi) {
55+
mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_1, reg_val);
56+
}
57+
}
58+
59+
void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi)
60+
{
61+
(void)control_both_mspi; // for compatibility
62+
uint32_t core_clock_mhz = 0;
63+
if (speed_mode == MSPI_TIMING_SPEED_MODE_LOW_PERF) {
64+
core_clock_mhz = PSRAM_LOW_SPEED_CORE_CLOCK_MHZ;
65+
} else {
66+
core_clock_mhz = PSRAM_HIGH_SPEED_CORE_CLOCK_MHZ;
67+
}
68+
//SPI0 and SPI1 share the register for core clock. So we only set SPI0 here.
69+
s_mspi_psram_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, core_clock_mhz);
70+
71+
uint32_t freqdiv = core_clock_mhz / psram_freq_mhz;
72+
ESP_EARLY_LOGV(TAG, "psram freqdiv: %d", freqdiv);
73+
assert(freqdiv > 0);
74+
uint32_t reg_val = mspi_timing_ll_calculate_clock_reg(freqdiv);
75+
mspi_timing_ll_set_psram_clock(MSPI_TIMING_LL_MSPI_ID_0, reg_val);
76+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#pragma once
7+
8+
#include "sdkconfig.h"
9+
10+
#define MSPI_TIMING_MSPI1_IS_INVOLVED CONFIG_ESPTOOLPY_FLASHFREQ_120M //This means esp flash driver needs to be notified
11+
#define MSPI_TIMING_CONFIG_NUM_MAX 32 //This should be larger than the max available timing config num
12+
#define MSPI_TIMING_TEST_DATA_LEN 128
13+
#define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0x100000
14+
15+
//--------------------------------------FLASH Sampling Mode --------------------------------------//
16+
#define MSPI_TIMING_FLASH_STR_MODE 1
17+
//--------------------------------------FLASH Module Clock --------------------------------------//
18+
#if CONFIG_ESPTOOLPY_FLASHFREQ_20M
19+
#define MSPI_TIMING_FLASH_MODULE_CLOCK 20
20+
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
21+
#define MSPI_TIMING_FLASH_MODULE_CLOCK 40
22+
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
23+
#define MSPI_TIMING_FLASH_MODULE_CLOCK 80
24+
#endif
25+
//------------------------------------FLASH Needs Tuning or not-------------------------------------//
26+
#if MSPI_TIMING_FLASH_STR_MODE
27+
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 80)
28+
#endif
29+
30+
//--------------------------------------PSRAM Sampling Mode --------------------------------------//
31+
#define MSPI_TIMING_PSRAM_STR_MODE 1
32+
//--------------------------------------PSRAM Module Clock --------------------------------------//
33+
#if CONFIG_SPIRAM
34+
#if CONFIG_SPIRAM_SPEED_40M
35+
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 40
36+
#elif CONFIG_SPIRAM_SPEED_80M
37+
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 80
38+
#endif
39+
#else //Disable PSRAM
40+
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz
41+
#endif
42+
//------------------------------------PSRAM Needs Tuning or not-------------------------------------//
43+
#if MSPI_TIMING_PSRAM_STR_MODE
44+
#define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40)
45+
#endif
46+
47+
///////////////////////////////////// FLASH CORE CLOCK /////////////////////////////////////
48+
#define MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 80
49+
50+
///////////////////////////////////// PSRAM CORE CLOCK /////////////////////////////////////
51+
#if CONFIG_SPIRAM_SPEED_80M
52+
#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 80
53+
#endif
54+
55+
//------------------------------------------Determine the Core Clock-----------------------------------------------//
56+
/**
57+
* @note
58+
* Limitation 1:
59+
* MSPI FLASH and PSRAM share the core clock register. Therefore,
60+
* the expected CORE CLOCK frequencies should be the same.
61+
*/
62+
#if MSPI_TIMING_FLASH_NEEDS_TUNING && MSPI_TIMING_PSRAM_NEEDS_TUNING
63+
ESP_STATIC_ASSERT(MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ == MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ, "FLASH and PSRAM Mode configuration are not supported");
64+
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ
65+
66+
//If only FLASH needs tuning, the core clock COULD be as FLASH expected
67+
#elif MSPI_TIMING_FLASH_NEEDS_TUNING && !MSPI_TIMING_PSRAM_NEEDS_TUNING
68+
ESP_STATIC_ASSERT(MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_PSRAM_MODULE_CLOCK == 0, "FLASH and PSRAM Mode configuration are not supported");
69+
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ
70+
71+
//If only PSRAM needs tuning, the core clock COULD be as PSRAM expected
72+
#elif !MSPI_TIMING_FLASH_NEEDS_TUNING && MSPI_TIMING_PSRAM_NEEDS_TUNING
73+
ESP_STATIC_ASSERT(MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_FLASH_MODULE_CLOCK == 0, "FLASH and PSRAM Mode configuration are not supported");
74+
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ
75+
76+
#else
77+
#define MSPI_TIMING_CORE_CLOCK_MHZ 80
78+
#endif
79+
80+
81+
//------------------------------------------Helper Macros to get FLASH/PSRAM tuning configs-----------------------------------------------//
82+
#define __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) \
83+
(mspi_timing_config_t) { .tuning_config_table = MSPI_TIMING_##type##_CONFIG_TABLE_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \
84+
.available_config_num = MSPI_TIMING_##type##_CONFIG_NUM_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \
85+
.default_config_id = MSPI_TIMING_##type##_DEFAULT_CONFIG_ID_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode }
86+
87+
#define _GET_TUNING_CONFIG(type, core_clock, module_clock, mode) __GET_TUNING_CONFIG(type, core_clock, module_clock, mode)
88+
89+
#define MSPI_TIMING_FLASH_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(FLASH, core_clock_mhz, module_clock_mhz, mode)
90+
#define MSPI_TIMING_PSRAM_GET_TUNING_CONFIG(core_clock_mhz, module_clock_mhz, mode) _GET_TUNING_CONFIG(PSRAM, core_clock_mhz, module_clock_mhz, mode)
91+
92+
93+
/**
94+
* Timing Tuning Parameters
95+
*/
96+
//PSRAM: core clock 80M, module clock 80M, STR mode
97+
#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE {{2, 2, 1}, {2, 1, 1}, {2, 0, 1}, {0, 0, 0}, {3, 1, 2}, {2, 3, 2}, {2, 2, 2}, {2, 1, 2}, {2, 0, 1}, {0, 0, 1}, {3, 1, 3}, {2, 3, 3}, {2, 2, 3}, {2, 1, 3}}
98+
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
99+
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 5

components/esp_hw_support/mspi_timing_tuning/port/esp32s3/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ set(srcs)
44

55
if(NOT BOOTLOADER_BUILD)
66
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
7-
list(APPEND srcs "mspi_timing_config.c")
7+
list(APPEND srcs "mspi_timing_config.c" "mspi_timing_by_mspi_delay.c")
88
endif()
99
endif()
1010

11-
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
11+
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})

components/esp_hw_support/mspi_timing_tuning/mspi_timing_by_mspi_delay.c renamed to components/esp_hw_support/mspi_timing_tuning/port/esp32s3/mspi_timing_by_mspi_delay.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "hal/clk_tree_ll.h"
2424
#include "hal/regi2c_ctrl_ll.h"
2525
#include "esp_private/mspi_timing_config.h"
26-
#include "mspi_timing_by_mspi_delay.h"
26+
#include "esp_private/mspi_timing_by_mspi_delay.h"
2727
#include "bootloader_flash.h"
2828
#include "esp32s3/rom/spi_flash.h"
2929
#include "esp32s3/rom/opi_flash.h"

components/esp_hw_support/mspi_timing_tuning/mspi_timing_by_dqs.h renamed to components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include/esp_private/mspi_timing_by_dqs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <stdint.h>
1515
#include "soc/soc_caps.h"
1616
#if SOC_MEMSPI_TIMING_TUNING_BY_DQS
17-
#include "mspi_timing_types.h"
17+
#include "esp_private/mspi_timing_impl_types.h"
1818
#include "mspi_timing_tuning_configs.h"
1919
#include "hal/mspi_ll.h"
2020
#endif

0 commit comments

Comments
 (0)