mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
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
This commit is contained in:
@@ -27,11 +27,13 @@ const static char *TAG = "MSPI Timing";
|
||||
//-------------------------------------MSPI Clock Setting-------------------------------------//
|
||||
static void s_mspi_flash_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "flash core clock: %d", core_clock_mhz);
|
||||
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
|
||||
}
|
||||
|
||||
static void s_mspi_psram_set_core_clock(uint8_t mspi_id, uint32_t core_clock_mhz)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "psram core clock: %d", core_clock_mhz);
|
||||
mspi_timing_ll_set_core_clock(mspi_id, core_clock_mhz);
|
||||
}
|
||||
|
||||
|
@@ -6,11 +6,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_assert.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
|
||||
#define MSPI_TIMING_MSPI1_IS_INVOLVED CONFIG_ESPTOOLPY_FLASHFREQ_120M //This means esp flash driver needs to be notified
|
||||
#define MSPI_TIMING_MSPI1_IS_INVOLVED (CONFIG_ESPTOOLPY_FLASHFREQ_80M || CONFIG_ESPTOOLPY_FLASHFREQ_120M) //This means esp flash driver needs to be notified
|
||||
#define MSPI_TIMING_CONFIG_NUM_MAX 32 //This should be larger than the max available timing config num
|
||||
#define MSPI_TIMING_TEST_DATA_LEN 128
|
||||
#define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0x100000
|
||||
#define MSPI_TIMING_FLASH_TEST_DATA_ADDR ESP_BOOTLOADER_OFFSET
|
||||
|
||||
//--------------------------------------FLASH Sampling Mode --------------------------------------//
|
||||
#define MSPI_TIMING_FLASH_STR_MODE 1
|
||||
@@ -21,10 +24,12 @@
|
||||
#define MSPI_TIMING_FLASH_MODULE_CLOCK 40
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||
#define MSPI_TIMING_FLASH_MODULE_CLOCK 80
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
||||
#define MSPI_TIMING_FLASH_MODULE_CLOCK 120
|
||||
#endif
|
||||
//------------------------------------FLASH Needs Tuning or not-------------------------------------//
|
||||
#if MSPI_TIMING_FLASH_STR_MODE
|
||||
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 80)
|
||||
#define MSPI_TIMING_FLASH_NEEDS_TUNING (MSPI_TIMING_FLASH_MODULE_CLOCK > 40)
|
||||
#endif
|
||||
|
||||
//--------------------------------------PSRAM Sampling Mode --------------------------------------//
|
||||
@@ -44,12 +49,15 @@
|
||||
#define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////// FLASH CORE CLOCK /////////////////////////////////////
|
||||
///////////////////////////////////// FLASH/PSRAM CORE CLOCK /////////////////////////////////////
|
||||
#if ((CONFIG_ESPTOOLPY_FLASHFREQ_80M && !CONFIG_SPIRAM) || (CONFIG_ESPTOOLPY_FLASHFREQ_80M && CONFIG_SPIRAM_SPEED_80M))
|
||||
#define MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 80
|
||||
|
||||
///////////////////////////////////// PSRAM CORE CLOCK /////////////////////////////////////
|
||||
#if CONFIG_SPIRAM_SPEED_80M
|
||||
#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 80
|
||||
#define MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX 6
|
||||
#else
|
||||
#define MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 240
|
||||
#define MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ 240
|
||||
#define MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX 4
|
||||
#endif
|
||||
|
||||
//------------------------------------------Determine the Core Clock-----------------------------------------------//
|
||||
@@ -93,7 +101,32 @@ ESP_STATIC_ASSERT(MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_FLASH_MO
|
||||
/**
|
||||
* Timing Tuning Parameters
|
||||
*/
|
||||
//FLASH: core clock 240M, module clock 120M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 12
|
||||
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 4
|
||||
|
||||
//FLASH: core clock 240M, module clock 80M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 14
|
||||
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 4
|
||||
|
||||
//FLASH: core clock 80M, module clock 80M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
|
||||
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 4
|
||||
|
||||
//PSRAM: core clock 240M, module clock 120M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 12
|
||||
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE 4
|
||||
|
||||
//PSRAM: core clock 240M, module clock 80M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 14
|
||||
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_240M_MODULE_CLK_80M_STR_MODE 4
|
||||
|
||||
//PSRAM: core clock 80M, module clock 80M, STR mode
|
||||
#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}}
|
||||
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
|
||||
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 5
|
||||
#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}}
|
||||
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 14
|
||||
#define MSPI_TIMING_PSRAM_DEFAULT_CONFIG_ID_CORE_CLK_80M_MODULE_CLK_80M_STR_MODE 4
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "esp_private/mspi_timing_config.h"
|
||||
#include "esp_private/mspi_timing_by_mspi_delay.h"
|
||||
#include "mspi_timing_tuning_configs.h"
|
||||
#include "bootloader_flash.h"
|
||||
|
||||
#define QPI_PSRAM_FAST_READ 0XEB
|
||||
#define QPI_PSRAM_WRITE 0X38
|
||||
@@ -33,6 +34,33 @@
|
||||
const static char *TAG = "MSPI Timing";
|
||||
|
||||
//-------------------------------------FLASH timing tuning register config-------------------------------------//
|
||||
void mspi_timing_get_flash_tuning_configs(mspi_timing_config_t *config)
|
||||
{
|
||||
#if MSPI_TIMING_FLASH_DTR_MODE
|
||||
#define FLASH_MODE DTR_MODE
|
||||
#else //MSPI_TIMING_FLASH_STR_MODE
|
||||
#define FLASH_MODE STR_MODE
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||
*config = MSPI_TIMING_FLASH_GET_TUNING_CONFIG(MSPI_TIMING_CORE_CLOCK_MHZ, 80, FLASH_MODE);
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
||||
*config = MSPI_TIMING_FLASH_GET_TUNING_CONFIG(MSPI_TIMING_CORE_CLOCK_MHZ, 120, FLASH_MODE);
|
||||
#else
|
||||
assert(false && "should never reach here");
|
||||
#endif
|
||||
|
||||
#undef FLASH_MODE
|
||||
}
|
||||
|
||||
void mspi_timing_flash_init(uint32_t flash_freq_mhz)
|
||||
{
|
||||
mspi_timing_config_set_flash_clock(flash_freq_mhz, MSPI_TIMING_SPEED_MODE_NORMAL_PERF, true);
|
||||
|
||||
//Power on HCLK
|
||||
mspi_timinng_ll_enable_flash_timing_adjust_clk(MSPI_TIMING_LL_MSPI_ID_0);
|
||||
}
|
||||
|
||||
static void s_set_flash_din_mode_num(uint8_t mspi_id, uint8_t din_mode, uint8_t din_num)
|
||||
{
|
||||
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)
|
||||
mspi_timing_ll_set_flash_extra_dummy(mspi_id, extra_dummy);
|
||||
}
|
||||
|
||||
void mspi_timing_config_flash_set_tuning_regs(const void *configs, uint8_t id)
|
||||
{
|
||||
const mspi_timing_tuning_param_t *params = &((mspi_timing_config_t *)configs)->tuning_config_table[id];
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
s_set_flash_din_mode_num(MSPI_TIMING_LL_MSPI_ID_0, params->spi_din_mode, params->spi_din_num);
|
||||
s_set_flash_extra_dummy(MSPI_TIMING_LL_MSPI_ID_1, params->extra_dummy_len);
|
||||
}
|
||||
|
||||
//-------------------------------------------FLASH Read/Write------------------------------------------//
|
||||
void mspi_timing_config_flash_read_data(uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
if (bootloader_flash_is_octal_mode_enabled()) {
|
||||
// note that in spi_flash_read API, there is a wait-idle stage, since flash can only be read in idle state.
|
||||
// but after we change the timing settings, we might not read correct idle status via RDSR.
|
||||
// so, here we should use a read API that won't check idle status.
|
||||
mspi_timing_ll_clear_fifo(MSPI_TIMING_LL_MSPI_ID_1);
|
||||
// to add opi read api here when octal flash is used
|
||||
assert(false);
|
||||
} else {
|
||||
esp_rom_spiflash_read(addr, (uint32_t *)buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------PSRAM timing tuning register config-------------------------------------//
|
||||
void mspi_timing_psram_init(uint32_t psram_freq_mhz)
|
||||
{
|
||||
@@ -218,7 +273,14 @@ static uint32_t s_select_best_tuning_config_str(const mspi_timing_config_t *conf
|
||||
//tuning is FAIL, select default point, and generate a warning
|
||||
best_point = configs->default_config_id;
|
||||
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %"PRIu32"", best_point);
|
||||
} else {
|
||||
}
|
||||
#if MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX
|
||||
else if (consecutive_length > MSPI_TIMING_FLASH_CONSECUTIVE_LEN_MAX) {
|
||||
best_point = configs->default_config_id;
|
||||
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %"PRIu32"", best_point);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
best_point = end - consecutive_length / 2;
|
||||
ESP_EARLY_LOGI(TAG, "tuning success, best point is index %"PRIu32"", best_point);
|
||||
}
|
||||
@@ -360,9 +422,6 @@ uint32_t mspi_timing_config_get_flash_clock_reg(void)
|
||||
|
||||
uint8_t mspi_timing_config_get_flash_extra_dummy(void)
|
||||
{
|
||||
#if MSPI_TIMING_FLASH_NEEDS_TUNING
|
||||
return s_flash_best_timing_tuning_config.extra_dummy_len;
|
||||
#else
|
||||
//use hw extra dummy
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@@ -38,7 +38,6 @@ extern "C" {
|
||||
#define MSPI_LL_CORE_CLOCK_120_MHZ 120
|
||||
#define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
MSPI
|
||||
---------------------------------------------------------------*/
|
||||
@@ -59,6 +58,9 @@ static inline __attribute__((always_inline)) void mspi_timing_ll_set_core_clock(
|
||||
case 120:
|
||||
divider = 4;
|
||||
break;
|
||||
case 240:
|
||||
divider = 2;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
@@ -109,6 +111,19 @@ static inline uint32_t mspi_timing_ll_calculate_clock_reg(uint8_t clkdiv)
|
||||
return div_parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear MSPI hw fifo
|
||||
*
|
||||
* @param mspi_id SPI0 / SPI1
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void mspi_timing_ll_clear_fifo(uint8_t mspi_id)
|
||||
{
|
||||
for (int i = 0; i < 16; i++) {
|
||||
REG_WRITE(SPI_MEM_W0_REG(mspi_id) + i * 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
FLASH
|
||||
---------------------------------------------------------------*/
|
||||
|
@@ -1251,6 +1251,10 @@ config SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
@@ -491,6 +491,7 @@
|
||||
#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1)
|
||||
#define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1)
|
||||
|
||||
#define SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1
|
||||
#define SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED 1
|
||||
|
Reference in New Issue
Block a user