mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
mspi: support octal flash 120M STR mode on esp32s3
This commit is contained in:
parent
f5a12f4900
commit
d325f4d557
@ -139,7 +139,7 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr)
|
|||||||
str = "20MHz";
|
str = "20MHz";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "SPI Speed : %s", str);
|
ESP_LOGI(TAG, "Boot SPI Speed : %s", str);
|
||||||
|
|
||||||
/* SPI mode could have been set to QIO during boot already,
|
/* SPI mode could have been set to QIO during boot already,
|
||||||
so test the SPI registers not the flash header */
|
so test the SPI registers not the flash header */
|
||||||
|
@ -123,6 +123,9 @@ menu "Serial flasher config"
|
|||||||
help
|
help
|
||||||
The SPI flash frequency to be used.
|
The SPI flash frequency to be used.
|
||||||
|
|
||||||
|
config ESPTOOLPY_FLASHFREQ_120M
|
||||||
|
depends on ESPTOOLPY_FLASHMODE_OPI_STR
|
||||||
|
bool "120 MHz"
|
||||||
config ESPTOOLPY_FLASHFREQ_80M
|
config ESPTOOLPY_FLASHFREQ_80M
|
||||||
bool "80 MHz"
|
bool "80 MHz"
|
||||||
config ESPTOOLPY_FLASHFREQ_40M
|
config ESPTOOLPY_FLASHFREQ_40M
|
||||||
@ -136,6 +139,9 @@ menu "Serial flasher config"
|
|||||||
|
|
||||||
config ESPTOOLPY_FLASHFREQ
|
config ESPTOOLPY_FLASHFREQ
|
||||||
string
|
string
|
||||||
|
# On some of the ESP chips, max boot frequency would be equal to (or even lower than) 80m.
|
||||||
|
# We currently define this to `80m`.
|
||||||
|
default "80m" if ESPTOOLPY_FLASHFREQ_120M
|
||||||
default "80m" if ESPTOOLPY_FLASHFREQ_80M
|
default "80m" if ESPTOOLPY_FLASHFREQ_80M
|
||||||
default "40m" if ESPTOOLPY_FLASHFREQ_40M
|
default "40m" if ESPTOOLPY_FLASHFREQ_40M
|
||||||
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
default "26m" if ESPTOOLPY_FLASHFREQ_26M
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 12
|
#define MSPI_TIMING_FLASH_CONFIG_NUM_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 12
|
||||||
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 2
|
#define MSPI_TIMING_FLASH_DEFAULT_CONFIG_ID_CORE_CLK_120M_MODULE_CLK_120M_STR_MODE 2
|
||||||
|
|
||||||
|
//Octal FLASH: core clock 240M, module clock 120M, STR mode
|
||||||
|
#define MSPI_TIMING_FLASH_CONFIG_TABLE_CORE_CLK_240M_MODULE_CLK_120M_STR_MODE {{1, 0, 0}, {0, 0, 0}, {1, 1, 1}, {2, 3, 2}, {1, 0, 1}, {0, 0, 1}, {1, 1, 2}, {2, 3, 3}, {1, 0, 2}, {0, 0, 2}, {1, 1, 3}, {2, 3, 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 2
|
||||||
|
|
||||||
//Octal PSRAM: core clock 80M, module clock 40M, DTR mode
|
//Octal PSRAM: core clock 80M, module clock 40M, DTR mode
|
||||||
#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_80M_MODULE_CLK_40M_DTR_MODE {{1, 0, 0}, {2, 1, 1}, {2, 0, 1}, {0, 0, 0}, {3, 1, 1}, {3, 0, 1}, {1, 0, 1}, {2, 1, 2}, {2, 0, 2}, {0, 0, 1}, {3, 1, 2}, {3, 0, 2}}
|
#define MSPI_TIMING_PSRAM_CONFIG_TABLE_CORE_CLK_80M_MODULE_CLK_40M_DTR_MODE {{1, 0, 0}, {2, 1, 1}, {2, 0, 1}, {0, 0, 0}, {3, 1, 1}, {3, 0, 1}, {1, 0, 1}, {2, 1, 2}, {2, 0, 2}, {0, 0, 1}, {3, 1, 2}, {3, 0, 2}}
|
||||||
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_40M_DTR_MODE 12
|
#define MSPI_TIMING_PSRAM_CONFIG_NUM_CORE_CLK_80M_MODULE_CLK_40M_DTR_MODE 12
|
||||||
|
@ -24,7 +24,7 @@ extern "C" {
|
|||||||
|
|
||||||
//-------------------------------------------FLASH Operation Mode and Corresponding Timing Tuning Parameter Table --------------------------------------//
|
//-------------------------------------------FLASH Operation Mode and Corresponding Timing Tuning Parameter Table --------------------------------------//
|
||||||
#define SPI_TIMING_FLASH_DTR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR || CONFIG_ESPTOOLPY_FLASHMODE_OIO_DTR)
|
#define SPI_TIMING_FLASH_DTR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_DTR || CONFIG_ESPTOOLPY_FLASHMODE_OIO_DTR)
|
||||||
#define SPI_TIMING_FLASH_STR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR || CONFIG_ESPTOOLPY_FLASHMODE_OIO_STR || CONFIG_ESPTOOLPY_FLASHMODE_OOUT_STR)
|
#define SPI_TIMING_FLASH_STR_MODE (CONFIG_ESPTOOLPY_FLASHMODE_OPI_STR || !CONFIG_ESPTOOLPY_OCT_FLASH)
|
||||||
|
|
||||||
/* Determine A feasible core clock below: SPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ and SPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ*/
|
/* Determine A feasible core clock below: SPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ and SPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ*/
|
||||||
//OCTAL FLASH
|
//OCTAL FLASH
|
||||||
@ -42,7 +42,7 @@ extern "C" {
|
|||||||
|
|
||||||
//OCT FLASH 120M STR
|
//OCT FLASH 120M STR
|
||||||
#if SPI_TIMING_FLASH_STR_MODE && CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
#if SPI_TIMING_FLASH_STR_MODE && CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
||||||
#define SPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 120
|
#define SPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ 240
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //#if CONFIG_ESPTOOLPY_OCT_FLASH
|
#endif //#if CONFIG_ESPTOOLPY_OCT_FLASH
|
||||||
|
@ -41,6 +41,13 @@
|
|||||||
|
|
||||||
__attribute__((unused)) static const char TAG[] = "spi_flash";
|
__attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||||
|
|
||||||
|
/* This pointer is defined in ROM and extern-ed on targets where CONFIG_SPI_FLASH_ROM_IMPL = y*/
|
||||||
|
#if !CONFIG_SPI_FLASH_ROM_IMPL
|
||||||
|
esp_flash_t *esp_flash_default_chip = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL
|
||||||
|
|
||||||
#ifdef CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
#ifdef CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||||
#define DEFAULT_FLASH_SPEED ESP_FLASH_80MHZ
|
#define DEFAULT_FLASH_SPEED ESP_FLASH_80MHZ
|
||||||
#elif defined CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
#elif defined CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
||||||
@ -264,13 +271,6 @@ esp_err_t spi_bus_remove_flash_device(esp_flash_t *chip)
|
|||||||
/* The default (ie initial boot) no-OS ROM esp_flash_os_functions_t */
|
/* The default (ie initial boot) no-OS ROM esp_flash_os_functions_t */
|
||||||
extern const esp_flash_os_functions_t esp_flash_noos_functions;
|
extern const esp_flash_os_functions_t esp_flash_noos_functions;
|
||||||
|
|
||||||
/* This pointer is defined in ROM and extern-ed on targets where CONFIG_SPI_FLASH_ROM_IMPL = y*/
|
|
||||||
#if !CONFIG_SPI_FLASH_ROM_IMPL
|
|
||||||
esp_flash_t *esp_flash_default_chip = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL
|
|
||||||
|
|
||||||
static DRAM_ATTR memspi_host_inst_t esp_flash_default_host;
|
static DRAM_ATTR memspi_host_inst_t esp_flash_default_host;
|
||||||
|
|
||||||
static DRAM_ATTR esp_flash_t default_chip = {
|
static DRAM_ATTR esp_flash_t default_chip = {
|
||||||
|
@ -42,6 +42,7 @@ void spi_timing_set_pin_drive_strength(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SPI_TIMING_FLASH_NEEDS_TUNING || SPI_TIMING_PSRAM_NEEDS_TUNING
|
#if SPI_TIMING_FLASH_NEEDS_TUNING || SPI_TIMING_PSRAM_NEEDS_TUNING
|
||||||
|
static char *TAG = "MSPI Timing";
|
||||||
static spi_timing_tuning_param_t s_flash_best_timing_tuning_config;
|
static spi_timing_tuning_param_t s_flash_best_timing_tuning_config;
|
||||||
static spi_timing_tuning_param_t s_psram_best_timing_tuning_config;
|
static spi_timing_tuning_param_t s_psram_best_timing_tuning_config;
|
||||||
|
|
||||||
@ -178,44 +179,85 @@ static void find_max_consecutive_success_points(uint8_t *array, uint32_t size, u
|
|||||||
*out_end_index = match_num == size ? size : end;
|
*out_end_index = match_num == size ? size : end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_best_tuning_config(spi_timing_config_t *config, uint32_t consecutive_length, uint32_t end, bool is_flash)
|
#if SPI_TIMING_FLASH_DTR_MODE || SPI_TIMING_PSRAM_DTR_MODE
|
||||||
|
static uint32_t select_best_tuning_config_dtr(spi_timing_config_t *config, uint32_t consecutive_length, uint32_t end)
|
||||||
{
|
{
|
||||||
#if (SPI_TIMING_FLASH_DTR_MODE && CONFIG_ESPTOOLPY_FLASHFREQ_80M) || (SPI_TIMING_PSRAM_DTR_MODE && CONFIG_SPIRAM_SPEED_80M)
|
#if (SPI_TIMING_CORE_CLOCK_MHZ == 160)
|
||||||
//80M DTR best point scheme
|
//Core clock 160M DTR best point scheme
|
||||||
uint32_t best_point;
|
uint32_t best_point;
|
||||||
/**
|
|
||||||
* If the consecutive success point list is no longer than 2, or all available points are successful,
|
//Define these magic number in macros in `spi_timing_config.h`. TODO: IDF-3663
|
||||||
* tuning is FAIL, select default point, and generate a warning
|
|
||||||
*/
|
|
||||||
//Define these magic number in macros in `spi_timing_config.h`. TODO: IDF-3146
|
|
||||||
if (consecutive_length <= 2 || consecutive_length >= 6) {
|
if (consecutive_length <= 2 || consecutive_length >= 6) {
|
||||||
|
//tuning is FAIL, select default point, and generate a warning
|
||||||
best_point = config->default_config_id;
|
best_point = config->default_config_id;
|
||||||
ESP_EARLY_LOGW("timing tuning:", "tuning fail, best point is %d\n", best_point + 1);
|
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %d", best_point);
|
||||||
} else if (consecutive_length <= 4) {
|
} else if (consecutive_length <= 4) {
|
||||||
//consevutive length : 3 or 4
|
//consecutive length : 3 or 4
|
||||||
best_point = end - 1;
|
best_point = end - 1;
|
||||||
ESP_EARLY_LOGD("timing tuning:","tuning success, best point is %d\n", best_point + 1);
|
ESP_EARLY_LOGD(TAG,"tuning success, best point is index %d", best_point);
|
||||||
} else {
|
} else {
|
||||||
//consecutive point list length equals 5
|
//consecutive point list length equals 5
|
||||||
best_point = end - 2;
|
best_point = end - 2;
|
||||||
ESP_EARLY_LOGD("timing tuning:","tuning success, best point is %d\n", best_point + 1);
|
ESP_EARLY_LOGD(TAG,"tuning success, best point is index %d", best_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_flash) {
|
return best_point;
|
||||||
s_flash_best_timing_tuning_config = config->tuning_config_table[best_point];
|
|
||||||
} else {
|
|
||||||
s_psram_best_timing_tuning_config = config->tuning_config_table[best_point];
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
//won't reach here
|
//won't reach here
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SPI_TIMING_FLASH_STR_MODE || SPI_TIMING_PSRAM_STR_MODE
|
||||||
|
static uint32_t select_best_tuning_config_str(spi_timing_config_t *config, uint32_t consecutive_length, uint32_t end)
|
||||||
|
{
|
||||||
|
#if (SPI_TIMING_CORE_CLOCK_MHZ == 120 || SPI_TIMING_CORE_CLOCK_MHZ == 240)
|
||||||
|
//STR best point scheme
|
||||||
|
uint32_t best_point;
|
||||||
|
|
||||||
|
if (consecutive_length <= 2|| consecutive_length >= 5) {
|
||||||
|
//tuning is FAIL, select default point, and generate a warning
|
||||||
|
best_point = config->default_config_id;
|
||||||
|
ESP_EARLY_LOGW(TAG, "tuning fail, best point is fallen back to index %d", best_point);
|
||||||
|
} else {
|
||||||
|
//consecutive length : 3 or 4
|
||||||
|
best_point = end - consecutive_length / 2;
|
||||||
|
ESP_EARLY_LOGD(TAG,"tuning success, best point is index %d", best_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
return best_point;
|
||||||
|
#else
|
||||||
|
//won't reach here
|
||||||
|
abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void select_best_tuning_config(spi_timing_config_t *config, uint32_t consecutive_length, uint32_t end, bool is_flash)
|
||||||
|
{
|
||||||
|
uint32_t best_point = 0;
|
||||||
|
if (is_flash) {
|
||||||
|
#if SPI_TIMING_FLASH_DTR_MODE
|
||||||
|
best_point = select_best_tuning_config_dtr(config, consecutive_length, end);
|
||||||
|
#else //#if SPI_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 SPI_TIMING_PSRAM_DTR_MODE
|
||||||
|
best_point = select_best_tuning_config_dtr(config, consecutive_length, end);
|
||||||
|
#else //#if SPI_TIMING_PSRAM_STR_MODE
|
||||||
|
best_point = select_best_tuning_config_str(config, consecutive_length, end);
|
||||||
|
#endif
|
||||||
|
s_psram_best_timing_tuning_config = config->tuning_config_table[best_point];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void do_tuning(uint8_t *reference_data, spi_timing_config_t *timing_config, bool is_flash)
|
static void do_tuning(uint8_t *reference_data, spi_timing_config_t *timing_config, bool is_flash)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* We use SPI1 to tune the FLASH timing:
|
* We use SPI1 to tune the timing:
|
||||||
* 1. Get all SPI1 sampling results.
|
* 1. Get all SPI1 sampling results.
|
||||||
* 2. Find the longest consecutive successful sampling points from the result above.
|
* 2. Find the longest consecutive successful sampling points from the result above.
|
||||||
* 3. The middle one will be the best sampling point.
|
* 3. The middle one will be the best sampling point.
|
||||||
|
Loading…
Reference in New Issue
Block a user