mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
mspi: support 120M DDR flash and psram on S3 (experimental)
This commit is contained in:
parent
0026f73dcb
commit
6d4c0bb3aa
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user