feat(psram): psram 80M timing tuning on c61

This commit is contained in:
armando
2025-07-28 11:25:28 +08:00
parent b32c31e500
commit 0189be39a0
7 changed files with 575 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
target_include_directories(${COMPONENT_LIB} PUBLIC . include)
set(srcs)
if(NOT BOOTLOADER_BUILD)
if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP)
list(APPEND srcs "mspi_timing_config.c")
endif()
endif()
target_sources(${COMPONENT_LIB} PRIVATE ${srcs})

View File

@@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_types.h"
#include "esp_log.h"
#include "soc/soc_caps.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/mspi_timing_config.h"
#include "mspi_timing_tuning_configs.h"
#include "hal/psram_ctrlr_ll.h"
#include "hal/mspi_ll.h"
#define FLASH_LOW_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT
#define FLASH_HIGH_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_CORE_CLOCK_MHZ
#define PSRAM_LOW_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT
#define PSRAM_HIGH_SPEED_CORE_CLOCK_MHZ MSPI_TIMING_CORE_CLOCK_MHZ
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);
}
void mspi_timing_config_set_flash_clock(uint32_t flash_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi)
{
uint32_t core_clock_mhz = 0;
if (speed_mode == MSPI_TIMING_SPEED_MODE_LOW_PERF) {
core_clock_mhz = FLASH_LOW_SPEED_CORE_CLOCK_MHZ;
} else {
core_clock_mhz = FLASH_HIGH_SPEED_CORE_CLOCK_MHZ;
}
//SPI0 and SPI1 share the register for core clock. So we only set SPI0 here.
s_mspi_flash_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, core_clock_mhz);
uint32_t freqdiv = core_clock_mhz / flash_freq_mhz;
ESP_EARLY_LOGV(TAG, "flash freqdiv: %d", freqdiv);
assert(freqdiv > 0);
uint32_t reg_val = mspi_timing_ll_calculate_clock_reg(freqdiv);
mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_0, reg_val);
if (control_both_mspi) {
mspi_timing_ll_set_flash_clock(MSPI_TIMING_LL_MSPI_ID_1, reg_val);
}
}
void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi)
{
(void)control_both_mspi; // for compatibility
uint32_t core_clock_mhz = 0;
if (speed_mode == MSPI_TIMING_SPEED_MODE_LOW_PERF) {
core_clock_mhz = PSRAM_LOW_SPEED_CORE_CLOCK_MHZ;
} else {
core_clock_mhz = PSRAM_HIGH_SPEED_CORE_CLOCK_MHZ;
}
//SPI0 and SPI1 share the register for core clock. So we only set SPI0 here.
s_mspi_psram_set_core_clock(MSPI_TIMING_LL_MSPI_ID_0, core_clock_mhz);
uint32_t freqdiv = core_clock_mhz / psram_freq_mhz;
ESP_EARLY_LOGV(TAG, "psram freqdiv: %d", freqdiv);
assert(freqdiv > 0);
uint32_t reg_val = mspi_timing_ll_calculate_clock_reg(freqdiv);
mspi_timing_ll_set_psram_clock(MSPI_TIMING_LL_MSPI_ID_0, reg_val);
}

View File

@@ -0,0 +1,119 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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_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
//--------------------------------------FLASH Sampling Mode --------------------------------------//
#define MSPI_TIMING_FLASH_STR_MODE 1
//--------------------------------------FLASH Module Clock --------------------------------------//
#if CONFIG_ESPTOOLPY_FLASHFREQ_20M
#define MSPI_TIMING_FLASH_MODULE_CLOCK 20
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
#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-------------------------------------//
#define MSPI_TIMING_FLASH_NEEDS_TUNING 0
//--------------------------------------PSRAM Sampling Mode --------------------------------------//
#define MSPI_TIMING_PSRAM_STR_MODE 1
//--------------------------------------PSRAM Module Clock --------------------------------------//
#if CONFIG_SPIRAM
#if CONFIG_SPIRAM_SPEED_40M
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 40
#elif CONFIG_SPIRAM_SPEED_80M
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 80
#endif
#else //Disable PSRAM
#define MSPI_TIMING_PSRAM_MODULE_CLOCK 10 //Define this to 10MHz
#endif
//------------------------------------PSRAM Needs Tuning or not-------------------------------------//
#if MSPI_TIMING_PSRAM_STR_MODE
#define MSPI_TIMING_PSRAM_NEEDS_TUNING (MSPI_TIMING_PSRAM_MODULE_CLOCK > 40)
#endif
///////////////////////////////////// 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
#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-----------------------------------------------//
/**
* @note
* Limitation 1:
* MSPI FLASH and PSRAM share the core clock register. Therefore,
* the expected CORE CLOCK frequencies should be the same.
*/
#if MSPI_TIMING_FLASH_NEEDS_TUNING && MSPI_TIMING_PSRAM_NEEDS_TUNING
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");
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ
//If only FLASH needs tuning, the core clock COULD be as FLASH expected
#elif MSPI_TIMING_FLASH_NEEDS_TUNING && !MSPI_TIMING_PSRAM_NEEDS_TUNING
ESP_STATIC_ASSERT(MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_PSRAM_MODULE_CLOCK == 0, "FLASH and PSRAM Mode configuration are not supported");
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_FLASH_EXPECTED_CORE_CLK_MHZ
//If only PSRAM needs tuning, the core clock COULD be as PSRAM expected
#elif !MSPI_TIMING_FLASH_NEEDS_TUNING && MSPI_TIMING_PSRAM_NEEDS_TUNING
ESP_STATIC_ASSERT(MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ % MSPI_TIMING_FLASH_MODULE_CLOCK == 0, "FLASH and PSRAM Mode configuration are not supported");
#define MSPI_TIMING_CORE_CLOCK_MHZ MSPI_TIMING_PSRAM_EXPECTED_CORE_CLK_MHZ
#else
#define MSPI_TIMING_CORE_CLOCK_MHZ 80
#endif
//------------------------------------------Helper Macros to get FLASH/PSRAM tuning configs-----------------------------------------------//
#define __GET_TUNING_CONFIG(type, core_clock, module_clock, mode) \
(mspi_timing_config_t) { .tuning_config_table = MSPI_TIMING_##type##_CONFIG_TABLE_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \
.available_config_num = MSPI_TIMING_##type##_CONFIG_NUM_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode, \
.default_config_id = MSPI_TIMING_##type##_DEFAULT_CONFIG_ID_CORE_CLK_##core_clock##M_MODULE_CLK_##module_clock##M_##mode }
#define _GET_TUNING_CONFIG(type, core_clock, module_clock, mode) __GET_TUNING_CONFIG(type, core_clock, module_clock, mode)
#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)
#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)
/**
* Timing Tuning Parameters
*/
//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 4

View File

@@ -23,6 +23,8 @@
#include "soc/soc.h"
#include "soc/clk_tree_defs.h"
#include "soc/pcr_struct.h"
#include "soc/spi_mem_struct.h"
#include "soc/spi_mem_reg.h"
#include "hal/misc.h"
#include "hal/assert.h"
@@ -99,6 +101,333 @@ static inline __attribute__((always_inline)) void mspi_timing_ll_enable_core_clo
}
/**
* Reset the MSPI clock
*/
static inline __attribute__((always_inline)) void _mspi_timing_ll_reset_mspi(void)
{
PCR.mspi_clk_conf.mspi_axi_rst_en = 1;
PCR.mspi_clk_conf.mspi_axi_rst_en = 0;
// Wait for mspi to be ready
while (!PCR.mspi_conf.mspi_ready) {
;
};
}
/**
* Calculate spi_flash clock frequency division parameters for register.
*
* @param clkdiv frequency division factor
*
* @return Register setting for the given clock division factor.
*/
static inline uint32_t mspi_timing_ll_calculate_clock_reg(uint8_t clkdiv)
{
uint32_t div_parameter;
// See comments of `clock` in `spi_mem_struct.h`
if (clkdiv == 1) {
div_parameter = (1 << 31);
} else {
div_parameter = ((clkdiv - 1) | (((clkdiv - 1) / 2 & 0xff) << 8 ) | (((clkdiv - 1) & 0xff) << 16));
}
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
---------------------------------------------------------------*/
/**
* @brief Set Flash clock
*
* @param mspi_id mspi_id
* @param clock_conf Configuration value for flash clock
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_flash_clock(uint32_t mspi_id, uint32_t clock_conf)
{
if (mspi_id == MSPI_TIMING_LL_MSPI_ID_0) {
SPIMEM0.mem_clock.val = clock_conf;
} else if (mspi_id == MSPI_TIMING_LL_MSPI_ID_1) {
SPIMEM1.clock.val = clock_conf;
}
}
/**
* Enable Flash timing adjust clock
*
* @param mspi_id SPI0 / SPI1
*/
__attribute__((always_inline))
static inline void mspi_timinng_ll_enable_flash_timing_adjust_clk(uint8_t mspi_id)
{
SPIMEM0.mem_timing_cali.mem_timing_clk_ena = true;
}
/**
* Set MSPI Flash din mode
*
* @param mspi_id SPI0 / SPI1
* @param din_mode Din mode value
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_flash_din_mode(uint8_t mspi_id, uint8_t din_mode)
{
uint32_t reg_val = (REG_READ(SPI_MEM_DIN_MODE_REG(mspi_id)) & (~(SPI_MEM_DIN0_MODE_M | SPI_MEM_DIN1_MODE_M | SPI_MEM_DIN2_MODE_M | SPI_MEM_DIN3_MODE_M | SPI_MEM_DIN4_MODE_M | SPI_MEM_DIN5_MODE_M | SPI_MEM_DIN6_MODE_M | SPI_MEM_DIN7_MODE_M | SPI_MEM_DINS_MODE_M)))
| (din_mode << SPI_MEM_DIN0_MODE_S) | (din_mode << SPI_MEM_DIN1_MODE_S) | (din_mode << SPI_MEM_DIN2_MODE_S) | (din_mode << SPI_MEM_DIN3_MODE_S)
| (din_mode << SPI_MEM_DIN4_MODE_S) | (din_mode << SPI_MEM_DIN5_MODE_S) | (din_mode << SPI_MEM_DIN6_MODE_S) | (din_mode << SPI_MEM_DIN7_MODE_S) | (din_mode << SPI_MEM_DINS_MODE_S);
REG_WRITE(SPI_MEM_DIN_MODE_REG(mspi_id), reg_val);
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Set MSPI Flash din num
*
* @param mspi_id SPI0 / SPI1
* @param din_num Din num value
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_flash_din_num(uint8_t mspi_id, uint8_t din_num)
{
uint32_t reg_val = (REG_READ(SPI_MEM_DIN_NUM_REG(mspi_id)) & (~(SPI_MEM_DIN0_NUM_M | SPI_MEM_DIN1_NUM_M | SPI_MEM_DIN2_NUM_M | SPI_MEM_DIN3_NUM_M | SPI_MEM_DIN4_NUM_M | SPI_MEM_DIN5_NUM_M | SPI_MEM_DIN6_NUM_M | SPI_MEM_DIN7_NUM_M | SPI_MEM_DINS_NUM_M)))
| (din_num << SPI_MEM_DIN0_NUM_S) | (din_num << SPI_MEM_DIN1_NUM_S) | (din_num << SPI_MEM_DIN2_NUM_S) | (din_num << SPI_MEM_DIN3_NUM_S)
| (din_num << SPI_MEM_DIN4_NUM_S) | (din_num << SPI_MEM_DIN5_NUM_S) | (din_num << SPI_MEM_DIN6_NUM_S) | (din_num << SPI_MEM_DIN7_NUM_S) | (din_num << SPI_MEM_DINS_NUM_S);
REG_WRITE(SPI_MEM_DIN_NUM_REG(mspi_id), reg_val);
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Set MSPI Flash extra dummy
*
* @param mspi_id SPI0 / SPI1
* @param extra_dummy Extra dummy
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_flash_extra_dummy(uint8_t mspi_id, uint8_t extra_dummy)
{
if (extra_dummy > 0) {
SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(mspi_id), SPI_MEM_TIMING_CALI_M);
SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(mspi_id), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy, SPI_MEM_EXTRA_DUMMY_CYCLELEN_S);
} else {
CLEAR_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(mspi_id), SPI_MEM_TIMING_CALI_M);
SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(mspi_id), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0, SPI_MEM_EXTRA_DUMMY_CYCLELEN_S);
}
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Get MSPI flash dummy info
*
* @param mspi_id SPI0 / SPI1
* @param usr_dummy User dummy
* @param extra_dummy Extra dummy
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_get_flash_dummy(uint8_t mspi_id, int *usr_dummy, int *extra_dummy)
{
*usr_dummy = REG_GET_FIELD(SPI_MEM_USER1_REG(mspi_id), SPI_MEM_USR_DUMMY_CYCLELEN);
*extra_dummy = REG_GET_FIELD(SPI_MEM_TIMING_CALI_REG(mspi_id), SPI_MEM_EXTRA_DUMMY_CYCLELEN);
}
/**
* Enable/Disable Flash variable dummy
*
* @param mspi_id SPI0 / SPI1
* @param enable Enable / Disable
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_enable_flash_variable_dummy(uint8_t mspi_id, bool enable)
{
REG_SET_FIELD(SPI_MEM_DDR_REG(mspi_id), SPI_FMEM_VAR_DUMMY, enable);
}
/**
* Get if cs setup is enabled or not
*
* @param mspi_id SPI0 / SPI1
*
* @return
* true: enabled; false: disabled
*/
__attribute__((always_inline))
static inline bool mspi_timing_ll_is_cs_setup_enabled(uint8_t mspi_id)
{
return REG_GET_BIT(SPI_MEM_USER_REG(mspi_id), SPI_MEM_CS_SETUP);
}
/**
* Get cs setup val
*
* @param mspi_id SPI0 / SPI1
*
* @return
* cs setup reg val
*/
static inline uint32_t mspi_timing_ll_get_cs_setup_val(uint8_t mspi_id)
{
return REG_GET_FIELD(SPI_MEM_CTRL2_REG(mspi_id), SPI_MEM_CS_SETUP_TIME);
}
/**
* Get if cs hold is enabled or not
*
* @param mspi_id SPI0 / SPI1
*
* @return
* true: enabled; false: disabled
*/
__attribute__((always_inline))
static inline bool mspi_timing_ll_is_cs_hold_enabled(uint8_t mspi_id)
{
return REG_GET_FIELD(SPI_MEM_USER_REG(mspi_id), SPI_MEM_CS_HOLD);
}
/**
* Get cs hold val
*
* @param mspi_id SPI0 / SPI1
*
* @return
* cs hold reg val
*/
static inline uint32_t mspi_timing_ll_get_cs_hold_val(uint8_t mspi_id)
{
return REG_GET_FIELD(SPI_MEM_CTRL2_REG(mspi_id), SPI_MEM_CS_HOLD_TIME);
}
/**
* Get clock reg val
*
* @param mspi_id SPI0 / SPI1
*
* @return
* clock reg val
*/
__attribute__((always_inline))
static inline uint32_t mspi_timing_ll_get_clock_reg(uint8_t mspi_id)
{
return READ_PERI_REG(SPI_MEM_CLOCK_REG(mspi_id));
}
/*---------------------------------------------------------------
PSRAM
---------------------------------------------------------------*/
/**
* @brief Set PSRAM clock
*
* @param mspi_id mspi_id
* @param clock_conf Configuration value for psram clock
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_psram_clock(uint32_t mspi_id, uint32_t clock_conf)
{
SPIMEM0.mem_sram_clk.val = clock_conf;
}
/**
* @brief Set SPI1 bus clock to initialise PSRAM
*
* @param mspi_id mspi_id
* @param clock_conf Configuration value for psram clock
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_spi1_bus_clock(uint32_t mspi_id, uint32_t clock_conf)
{
HAL_ASSERT(mspi_id == MSPI_TIMING_LL_MSPI_ID_1);
SPIMEM1.clock.val = clock_conf;
}
/**
* Enable PSRAM timing adjust clock
*
* @param mspi_id SPI0 / SPI1
*/
__attribute__((always_inline))
static inline void mspi_timinng_ll_enable_psram_timing_adjust_clk(uint8_t mspi_id)
{
SPIMEM0.smem_timing_cali.smem_timing_clk_ena = true;
}
/**
* Set MSPI PSRAM din mode
*
* @param mspi_id SPI0 / SPI1
* @param din_mode Din mode value
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_psram_din_mode(uint8_t mspi_id, uint8_t din_mode)
{
uint32_t reg_val = (REG_READ(SPI_SMEM_DIN_MODE_REG(mspi_id)) & (~(SPI_SMEM_DIN0_MODE_M | SPI_SMEM_DIN1_MODE_M | SPI_SMEM_DIN2_MODE_M | SPI_SMEM_DIN3_MODE_M | SPI_SMEM_DIN4_MODE_M | SPI_SMEM_DIN5_MODE_M | SPI_SMEM_DIN6_MODE_M | SPI_SMEM_DIN7_MODE_M | SPI_SMEM_DINS_MODE_M)))
| (din_mode << SPI_SMEM_DIN0_MODE_S) | (din_mode << SPI_SMEM_DIN1_MODE_S) | (din_mode << SPI_SMEM_DIN2_MODE_S) | (din_mode << SPI_SMEM_DIN3_MODE_S)
| (din_mode << SPI_SMEM_DIN4_MODE_S) | (din_mode << SPI_SMEM_DIN5_MODE_S) | (din_mode << SPI_SMEM_DIN6_MODE_S) | (din_mode << SPI_SMEM_DIN7_MODE_S) | (din_mode << SPI_SMEM_DINS_MODE_S);
REG_WRITE(SPI_SMEM_DIN_MODE_REG(mspi_id), reg_val);
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Set MSPI PSRAM din num
*
* @param mspi_id SPI0 / SPI1
* @param din_num Din num value
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_psram_din_num(uint8_t mspi_id, uint8_t din_num)
{
uint32_t reg_val = (REG_READ(SPI_SMEM_DIN_NUM_REG(mspi_id)) & (~(SPI_SMEM_DIN0_NUM_M | SPI_SMEM_DIN1_NUM_M | SPI_SMEM_DIN2_NUM_M | SPI_SMEM_DIN3_NUM_M | SPI_SMEM_DIN4_NUM_M | SPI_SMEM_DIN5_NUM_M | SPI_SMEM_DIN6_NUM_M | SPI_SMEM_DIN7_NUM_M | SPI_SMEM_DINS_NUM_M)))
| (din_num << SPI_SMEM_DIN0_NUM_S) | (din_num << SPI_SMEM_DIN1_NUM_S) | (din_num << SPI_SMEM_DIN2_NUM_S) | (din_num << SPI_SMEM_DIN3_NUM_S)
| (din_num << SPI_SMEM_DIN4_NUM_S) | (din_num << SPI_SMEM_DIN5_NUM_S) | (din_num << SPI_SMEM_DIN6_NUM_S) | (din_num << SPI_SMEM_DIN7_NUM_S) | (din_num << SPI_SMEM_DINS_NUM_S);
REG_WRITE(SPI_SMEM_DIN_NUM_REG(mspi_id), reg_val);
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Set MSPI Octal PSRAM extra dummy
*
* @param mspi_id SPI0 / SPI1
* @param extra_dummy Extra dummy
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_set_psram_extra_dummy(uint8_t mspi_id, uint8_t extra_dummy)
{
if (extra_dummy > 0) {
SET_PERI_REG_MASK(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_TIMING_CALI_M);
SET_PERI_REG_BITS(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy,
SPI_SMEM_EXTRA_DUMMY_CYCLELEN_S);
} else {
CLEAR_PERI_REG_MASK(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_TIMING_CALI_M);
SET_PERI_REG_BITS(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_EXTRA_DUMMY_CYCLELEN_V, 0,
SPI_SMEM_EXTRA_DUMMY_CYCLELEN_S);
}
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(MSPI_TIMING_LL_MSPI_ID_0), SPI_MEM_TIMING_CALI_UPDATE);
}
/**
* Get MSPI PSRAM dummy info
*
* @param mspi_id SPI0 / SPI1
* @param usr_rdummy User read dummy
* @param extra_dummy Extra dummy
*/
__attribute__((always_inline))
static inline void mspi_timing_ll_get_psram_dummy(uint8_t mspi_id, int *usr_rdummy, int *extra_dummy)
{
*usr_rdummy = REG_GET_FIELD(SPI_MEM_CACHE_SCTRL_REG(mspi_id), SPI_MEM_SRAM_RDUMMY_CYCLELEN);
*extra_dummy = REG_GET_FIELD(SPI_SMEM_TIMING_CALI_REG(mspi_id), SPI_SMEM_EXTRA_DUMMY_CYCLELEN);
}
#ifdef __cplusplus
}
#endif

View File

@@ -624,11 +624,39 @@ static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
// Not supported on esp32c61
}
/**
* Set CS setup time.
*
* @param dev Beginning address of the peripheral registers.
* @param cs_setup_time CS setup time config used by the host.
*/
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
{
// Not supported on esp32c61
}
/**
* Set extra dummy.
*
* @param dev Beginning address of the peripheral registers.
* @param extra_dummy Extra dummy
*/
static inline void spimem_flash_ll_set_extra_dummy(spi_mem_dev_t *dev, uint32_t extra_dummy)
{
//for compatibility
}
/**
* Set FDUMMY_RIN.
*
* @param dev Beginning address of the peripheral registers.
* @param fdummy_rin fdummy_rin value
*/
static inline void spimem_flash_ll_set_fdummy_rin(spi_mem_dev_t *dev, uint32_t fdummy_rin)
{
dev->ctrl.fdummy_rin = fdummy_rin;
}
/**
* Get the spi flash source clock frequency. Used for calculating
* the divider parameters.

View File

@@ -847,10 +847,18 @@ config SOC_SPI_MEM_SUPPORT_WRAP
bool
default y
config SOC_SPI_MEM_SUPPORT_TIMING_TUNING
bool
default y
config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR
bool
default y
config SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY
bool
default y
config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
bool
default y

View File

@@ -353,7 +353,9 @@
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
#define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1)
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
#define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1)
#define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1)
#define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1)
#define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1
#define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1