diff --git a/components/esp_hw_support/mspi_timing_by_flash_delay.c b/components/esp_hw_support/mspi_timing_by_flash_delay.c index 836e078983..2f66ecec6a 100644 --- a/components/esp_hw_support/mspi_timing_by_flash_delay.c +++ b/components/esp_hw_support/mspi_timing_by_flash_delay.c @@ -224,3 +224,8 @@ uint8_t mspi_timing_config_get_flash_extra_dummy(void) //use hw extra dummy return 0; } + +uint32_t mspi_timing_config_get_flash_fdummy_rin(void) +{ + return mspi_timing_ll_get_invalid_dqs_mask(MSPI_TIMING_LL_MSPI_ID_1); +} diff --git a/components/esp_hw_support/mspi_timing_by_flash_delay.h b/components/esp_hw_support/mspi_timing_by_flash_delay.h index 665142a614..2457c7e857 100644 --- a/components/esp_hw_support/mspi_timing_by_flash_delay.h +++ b/components/esp_hw_support/mspi_timing_by_flash_delay.h @@ -137,6 +137,14 @@ uint32_t mspi_timing_config_get_flash_clock_reg(void); * @return Flash extra dummy */ uint8_t mspi_timing_config_get_flash_extra_dummy(void); + +/** + * @brief Get Flash dummy rin_reg + * + * @return Flash dummy rin_reg + */ +uint32_t mspi_timing_config_get_flash_fdummy_rin(void); + #endif //#if SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index d2742ec840..3374e2ab91 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -603,6 +603,10 @@ void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing out_timing_config->extra_dummy = mspi_timing_config_get_flash_extra_dummy(); +#if MSPI_TIMING_LL_FLASH_FDUMMY_RIN_SUPPORTED + out_timing_config->fdummy_rin = mspi_timing_config_get_flash_fdummy_rin(); +#endif + // Get CS setup/hold value here. mspi_timing_config_get_cs_timing(&out_timing_config->cs_setup, &out_timing_config->cs_hold); } diff --git a/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h index adaae6b159..9d83a7ccb2 100644 --- a/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h +++ b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h @@ -28,10 +28,11 @@ extern "C" { #endif -#define MSPI_TIMING_LL_MSPI_ID_0 0 -#define MSPI_TIMING_LL_MSPI_ID_1 1 +#define MSPI_TIMING_LL_MSPI_ID_0 0 +#define MSPI_TIMING_LL_MSPI_ID_1 1 -#define MSPI_TIMING_LL_FLASH_CORE_CLK_DIV 4 +#define MSPI_TIMING_LL_FLASH_CORE_CLK_DIV 4 +#define MSPI_TIMING_LL_FLASH_FDUMMY_RIN_SUPPORTED 1 #define MSPI_TIMING_LL_FLASH_OCT_MASK (SPI_MEM_C_FCMD_OCT | SPI_MEM_C_FADDR_OCT | SPI_MEM_C_FDIN_OCT | SPI_MEM_C_FDOUT_OCT) #define MSPI_TIMING_LL_FLASH_QUAD_MASK (SPI_MEM_C_FASTRD_MODE | SPI_MEM_C_FREAD_DUAL | SPI_MEM_C_FREAD_DIO | SPI_MEM_C_FREAD_QUAD | SPI_MEM_C_FREAD_QIO) @@ -540,6 +541,24 @@ static inline void mspi_timing_ll_get_flash_dummy(uint8_t spi_num, int *usr_dumm } } +/** + * Mask invalid DQS + * + * @param spi_num SPI0 / SPI1 + * @param enable Enable / Disable + */ +__attribute__((always_inline)) +static inline uint32_t mspi_timing_ll_get_invalid_dqs_mask(uint8_t spi_num) +{ + if (spi_num == MSPI_TIMING_LL_MSPI_ID_0) { + return REG_GET_FIELD(SPI_MEM_C_CTRL_REG, SPI_MEM_C_FDUMMY_RIN); + } else if (spi_num == MSPI_TIMING_LL_MSPI_ID_1) { + return REG_GET_FIELD(SPI1_MEM_C_CTRL_REG, SPI1_MEM_C_FDUMMY_RIN); + } else { + HAL_ASSERT(false); + } +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index c2c84cd29c..d76bef60e5 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -643,6 +643,11 @@ static inline void spimem_flash_ll_set_extra_dummy(spi_mem_dev_t *dev, uint32_t //for compatibility } +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. diff --git a/components/hal/esp32s3/include/hal/spimem_flash_ll.h b/components/hal/esp32s3/include/hal/spimem_flash_ll.h index e034092606..8646fde7ab 100644 --- a/components/hal/esp32s3/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32s3/include/hal/spimem_flash_ll.h @@ -640,6 +640,11 @@ static inline void spimem_flash_ll_set_extra_dummy(spi_mem_dev_t *dev, uint32_t dev->timing_cali.extra_dummy_cyclelen = extra_dummy; } +static inline void spimem_flash_ll_set_fdummy_rin(spi_mem_dev_t *dev, uint32_t fdummy_rin) +{ + //for compatibility +} + /** * Get the spi flash source clock frequency. Used for calculating * the divider parameters. diff --git a/components/hal/include/hal/spi_flash_hal.h b/components/hal/include/hal/spi_flash_hal.h index e4e2cd7e2e..eb1a19a6f5 100644 --- a/components/hal/include/hal/spi_flash_hal.h +++ b/components/hal/include/hal/spi_flash_hal.h @@ -42,9 +42,9 @@ typedef struct { int cs_num; ///< Which cs pin is used, 0-2. struct { uint8_t extra_dummy; ///< Pre-calculated extra dummy used for compensation + uint8_t fdummy_rin; ///< Mask invalid dqs or not uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock. uint8_t cs_hold; ///< CS hold time config used by the host - uint8_t reserved2; ///< Reserved, set to 0. }; spi_flash_ll_clock_reg_t clock_conf; ///< Pre-calculated clock configuration value esp_flash_io_mode_t base_io_mode; ///< Default IO mode mask for common commands @@ -63,6 +63,7 @@ ESP_STATIC_ASSERT(sizeof(spi_flash_hal_context_t) == 48, "size of spi_flash_hal_ /// This struct provide MSPI Flash necessary timing related config, should be consistent with that in union in `spi_flash_hal_config_t`. typedef struct { uint32_t extra_dummy; + uint32_t fdummy_rin; uint32_t cs_hold; uint8_t cs_setup; spi_flash_ll_clock_reg_t clock_config; @@ -73,6 +74,7 @@ typedef struct { union { struct { uint32_t extra_dummy; ///< extra dummy for timing compensation. + uint32_t fdummy_rin; ///< Mask invalid dqs or not uint32_t cs_hold; ///< CS hold time config used by the host uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock spi_flash_ll_clock_reg_t clock_config; ///< (optional) Clock configuration for Octal flash. diff --git a/components/hal/spi_flash_hal.c b/components/hal/spi_flash_hal.c index 66c225f770..3403fbe183 100644 --- a/components/hal/spi_flash_hal.c +++ b/components/hal/spi_flash_hal.c @@ -117,6 +117,7 @@ esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_ #if SOC_SPI_MEM_SUPPORT_TIMING_TUNING if (cfg->using_timing_tuning) { data_out->extra_dummy = extra_dummy_under_timing_tuning(cfg); + data_out->fdummy_rin = cfg->fdummy_rin; data_out->clock_conf = cfg->clock_config; } else #endif // SOC_SPI_MEM_SUPPORT_TIMING_TUNING diff --git a/components/hal/spi_flash_hal_common.inc b/components/hal/spi_flash_hal_common.inc index 4281105faa..05074cf618 100644 --- a/components/hal/spi_flash_hal_common.inc +++ b/components/hal/spi_flash_hal_common.inc @@ -161,6 +161,12 @@ esp_err_t spi_flash_hal_configure_host_io_mode( spi_flash_ll_set_miso_bitlen(dev, 0); spi_flash_ll_set_mosi_bitlen(dev, 0); spi_flash_ll_set_read_mode(dev, io_mode); +#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING + spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host; + if (ctx->fdummy_rin) { + spimem_flash_ll_set_fdummy_rin((spi_mem_dev_t*)dev, ctx->fdummy_rin); + } +#endif return ESP_OK; }