Skip to content

Commit b32c31e

Browse files
committed
Merge branch 'feat/c5_flash_timing_tuning' into 'master'
flash: flash timing tuning support on c5 Closes IDF-8649 See merge request espressif/esp-idf!40763
2 parents aa1c21f + 65db12c commit b32c31e

File tree

6 files changed

+129
-15
lines changed

6 files changed

+129
-15
lines changed

components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ const static char *TAG = "MSPI Timing";
2727
//-------------------------------------MSPI Clock Setting-------------------------------------//
2828
static void s_mspi_flash_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
2929
{
30+
ESP_EARLY_LOGV(TAG, "flash core clock: %d", core_clock_mhz);
3031
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
3132
}
3233

3334
static void s_mspi_psram_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
3435
{
36+
ESP_EARLY_LOGV(TAG, "psram core clock: %d", core_clock_mhz);
3537
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
3638
}
3739

components/esp_hw_support/mspi_timing_tuning/port/esp32c5/mspi_timing_tuning_configs.h

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
#pragma once
77

88
#include "sdkconfig.h"
9+
#include "esp_assert.h"
10+
#include "esp_flash_partitions.h"
911

10-
#define MSPI_TIMING_MSPI1_IS_INVOLVED CONFIG_ESPTOOLPY_FLASHFREQ_120M //This means esp flash driver needs to be notified
12+
#define MSPI_TIMING_MSPI1_IS_INVOLVED (CONFIG_ESPTOOLPY_FLASHFREQ_80M || CONFIG_ESPTOOLPY_FLASHFREQ_120M) //This means esp flash driver needs to be notified
1113
#define MSPI_TIMING_CONFIG_NUM_MAX 32 //This should be larger than the max available timing config num
1214
#define MSPI_TIMING_TEST_DATA_LEN 128
1315
#define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0x100000
16+
#define MSPI_TIMING_FLASH_TEST_DATA_ADDR ESP_BOOTLOADER_OFFSET
1417

1518
//--------------------------------------FLASH Sampling Mode --------------------------------------//
1619
#define MSPI_TIMING_FLASH_STR_MODE 1
@@ -21,10 +24,12 @@
2124
#define MSPI_TIMING_FLASH_MODULE_CLOCK 40
2225
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
2326
#define MSPI_TIMING_FLASH_MODULE_CLOCK 80
27+
#elif CONFIG_ESPTOOLPY_FLASHFREQ_120M
28+
#define MSPI_TIMING_FLASH_MODULE_CLOCK 120
2429
#endif
2530
//------------------------------------FLASH Needs Tuning or not-------------------------------------//
2631
#if MSPI_TIMING_FLASH_STR_MODE
27-
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 80)
32+
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 40)
2833
#endif
2934

3035
//--------------------------------------PSRAM Sampling Mode --------------------------------------//
@@ -44,12 +49,15 @@
4449
#define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40)
4550
#endif
4651

47-
///////////////////////////////////// FLASH CORE CLOCK /////////////////////////////////////
52+
///////////////////////////////////// FLASH/PSRAM CORE CLOCK /////////////////////////////////////
53+
#if ((CONFIG_ESPTOOLPY_FLASHFREQ_80M && !CONFIG_SPIRAM) || (CONFIG_ESPTOOLPY_FLASHFREQ_80M && CONFIG_SPIRAM_SPEED_80M))
4854
#define MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 80
49-
50-
///////////////////////////////////// PSRAM CORE CLOCK /////////////////////////////////////
51-
#if CONFIG_SPIRAM_SPEED_80M
5255
#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 80
56+
#define MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX 6
57+
#else
58+
#define MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 240
59+
#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 240
60+
#define MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX 4
5361
#endif
5462

5563
//------------------------------------------Determine the Core Clock-----------------------------------------------//
@@ -93,7 +101,32 @@ ESP_STATIC_ASSERT(MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_FLASH_MO
93101
/**
94102
* Timing Tuning Parameters
95103
*/
104+
//FLASH: core clock 240M, module clock 120M, STR mode
105+
#define MSPI_TIMING_FLASH_CONFIG_TABLE_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE {{2, 0, 1}, {0, 0, 0}, {2, 2, 2}, {2, 1, 2}, {2, 0, 2}, {0, 0, 1}, {2, 2, 3}, {2, 1, 3}, {2, 0, 3}, {0, 0, 2}, {2, 2, 4}, {2, 1, 4}}
106+
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 12
107+
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 4
108+
109+
//FLASH: core clock 240M, module clock 80M, STR mode
110+
#define MSPI_TIMING_FLASH_CONFIG_TABLE_CORE_CLK_240M_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, 2}, {0, 0, 1}, {3, 1, 3}, {2, 3, 3}, {2, 2, 3}, {2, 1, 3}}
111+
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 14
112+
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 4
113+
114+
//FLASH: core clock 80M, module clock 80M, STR mode
115+
#define MSPI_TIMING_FLASH_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, 2}, {0, 0, 1}, {3, 1, 3}, {2, 3, 3}, {2, 2, 3}, {2, 1, 3}}
116+
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
117+
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 4
118+
119+
//PSRAM: core clock 240M, module clock 120M, STR mode
120+
#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE {{2, 0, 1}, {0, 0, 0}, {2, 2, 2}, {2, 1, 2}, {2, 0, 2}, {0, 0, 1}, {2, 2, 3}, {2, 1, 3}, {2, 0, 3}, {0, 0, 2}, {2, 2, 4}, {2, 1, 4}}
121+
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 12
122+
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 4
123+
124+
//PSRAM: core clock 240M, module clock 80M, STR mode
125+
#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_240M_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, 2}, {0, 0, 1}, {3, 1, 3}, {2, 3, 3}, {2, 2, 3}, {2, 1, 3}}
126+
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 14
127+
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 4
128+
96129
//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, 2}, {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
130+
#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, 2}, {0, 0, 1}, {3, 1, 3}, {2, 3, 3}, {2, 2, 3}, {2, 1, 3}}
131+
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
132+
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 4

components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/mspi_timing_by_mspi_delay.c

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "esp_private/mspi_timing_config.h"
2626
#include "esp_private/mspi_timing_by_mspi_delay.h"
2727
#include "mspi_timing_tuning_configs.h"
28+
#include "bootloader_flash.h"
2829

2930
#define QPI_PSRAM_FAST_READ 0XEB
3031
#define QPI_PSRAM_WRITE 0X38
@@ -33,6 +34,33 @@
3334
const static char *TAG = "MSPI Timing";
3435

3536
//-------------------------------------FLASH timing tuning register config-------------------------------------//
37+
void mspi_timing_get_flash_tuning_configs(mspi_timing_config_t *config)
38+
{
39+
#if MSPI_TIMING_FLASH_DTR_MODE
40+
#define FLASH_MODE DTR_MODE
41+
#else //MSPI_TIMING_FLASH_STR_MODE
42+
#define FLASH_MODE STR_MODE
43+
#endif
44+
45+
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M
46+
*config = MSPI_TIMING_FLASH_GET_TUNING_CONFIG(MSPI_TIMING_CORE_CLOCK_MHZ, 80, FLASH_MODE);
47+
#elif CONFIG_ESPTOOLPY_FLASHFREQ_120M
48+
*config = MSPI_TIMING_FLASH_GET_TUNING_CONFIG(MSPI_TIMING_CORE_CLOCK_MHZ, 120, FLASH_MODE);
49+
#else
50+
assert(false && "should never reach here");
51+
#endif
52+
53+
#undef FLASH_MODE
54+
}
55+
56+
void mspi_timing_flash_init(uint32_t flash_freq_mhz)
57+
{
58+
mspi_timing_config_set_flash_clock(flash_freq_mhz, MSPI_TIMING_SPEED_MODE_NORMAL_PERF, true);
59+
60+
//Power on HCLK
61+
mspi_timinng_ll_enable_flash_timing_adjust_clk(MSPI_TIMING_LL_MSPI_ID_0);
62+
}
63+
3664
static void s_set_flash_din_mode_num(uint8_t mspi_id, uint8_t din_mode, uint8_t din_num)
3765
{
3866
mspi_timing_ll_set_flash_din_mode(mspi_id, din_mode);
@@ -44,6 +72,33 @@ static void s_set_flash_extra_dummy(uint8_t mspi_id, uint8_t extra_dummy)
4472
mspi_timing_ll_set_flash_extra_dummy(mspi_id, extra_dummy);
4573
}
4674

75+
void mspi_timing_config_flash_set_tuning_regs(const void *configs, uint8_t id)
76+
{
77+
const mspi_timing_tuning_param_t *params = &((mspi_timing_config_t *)configs)->tuning_config_table[id];
78+
/**
79+
* 1. SPI_MEM_DINx_MODE(1), SPI_MEM_DINx_NUM(1) are meaningless
80+
* SPI0 and SPI1 share the SPI_MEM_DINx_MODE(0), SPI_MEM_DINx_NUM(0) for FLASH timing tuning
81+
* 2. We use SPI1 to get the best Flash timing tuning (mode and num) config
82+
*/
83+
s_set_flash_din_mode_num(MSPI_TIMING_LL_MSPI_ID_0, params->spi_din_mode, params->spi_din_num);
84+
s_set_flash_extra_dummy(MSPI_TIMING_LL_MSPI_ID_1, params->extra_dummy_len);
85+
}
86+
87+
//-------------------------------------------FLASH Read/Write------------------------------------------//
88+
void mspi_timing_config_flash_read_data(uint8_t *buf, uint32_t addr, uint32_t len)
89+
{
90+
if (bootloader_flash_is_octal_mode_enabled()) {
91+
// note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state.
92+
// but after we change the timing settings, we might not read correct idle status via RDSR.
93+
// so, here we should use a read API that won't check idle status.
94+
mspi_timing_ll_clear_fifo(MSPI_TIMING_LL_MSPI_ID_1);
95+
// to add opi read api here when octal flash is used
96+
assert(false);
97+
} else {
98+
esp_rom_spiflash_read(addr, (uint32_t *)buf, len);
99+
}
100+
}
101+
47102
//-------------------------------------PSRAM timing tuning register config-------------------------------------//
48103
void mspi_timing_psram_init(uint32_t psram_freq_mhz)
49104
{
@@ -218,7 +273,14 @@ static uint32_t s_select_best_tuning_config_str(const mspi_timing_config_t *conf
218273
//tuning is FAIL, select default point, and generate a warning
219274
best_point = configs->default_config_id;
220275
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %"PRIu32"", best_point);
221-
} else {
276+
}
277+
#if MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX
278+
else if (consecutive_length > MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX) {
279+
best_point = configs->default_config_id;
280+
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %"PRIu32"", best_point);
281+
}
282+
#endif
283+
else {
222284
best_point = end - consecutive_length / 2;
223285
ESP_EARLY_LOGI(TAG, "tuning success, best point is index %"PRIu32"", best_point);
224286
}
@@ -360,9 +422,6 @@ uint32_t mspi_timing_config_get_flash_clock_reg(void)
360422

361423
uint8_t mspi_timing_config_get_flash_extra_dummy(void)
362424
{
363-
#if MSPI_TIMING_FLASH_NEEDS_TUNING
364-
return s_flash_best_timing_tuning_config.extra_dummy_len;
365-
#else
425+
//use hw extra dummy
366426
return 0;
367-
#endif
368427
}

components/hal/esp32c5/include/hal/mspi_ll.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ extern "C" {
3838
#define MSPI_LL_CORE_CLOCK_120_MHZ 120
3939
#define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ
4040

41-
4241
/*---------------------------------------------------------------
4342
MSPI
4443
---------------------------------------------------------------*/
@@ -59,6 +58,9 @@ static inline __attribute__((always_inline)) void mspi_timing_ll_set_core_clock(
5958
case 120:
6059
divider = 4;
6160
break;
61+
case 240:
62+
divider = 2;
63+
break;
6264
default:
6365
HAL_ASSERT(false);
6466
}
@@ -109,6 +111,19 @@ static inline uint32_t mspi_timing_ll_calculate_clock_reg(uint8_t clkdiv)
109111
return div_parameter;
110112
}
111113

114+
/**
115+
* Clear MSPI hw fifo
116+
*
117+
* @param mspi_id SPI0 / SPI1
118+
*/
119+
__attribute__((always_inline))
120+
static inline void mspi_timing_ll_clear_fifo(uint8_t mspi_id)
121+
{
122+
for (int i = 0; i < 16; i++) {
123+
REG_WRITE(SPI_MEM_W0_REG(mspi_id) + i * 4, 0);
124+
}
125+
}
126+
112127
/*---------------------------------------------------------------
113128
FLASH
114129
---------------------------------------------------------------*/

components/soc/esp32c5/include/soc/Kconfig.soc_caps.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,10 @@ config SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY
12511251
bool
12521252
default y
12531253

1254+
config SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED
1255+
bool
1256+
default y
1257+
12541258
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
12551259
bool
12561260
default y

components/soc/esp32c5/include/soc/soc_caps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@
491491
#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1)
492492
#define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1)
493493

494+
#define SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED 1
494495
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
495496
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1
496497
#define SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED 1

0 commit comments

Comments
 (0)