diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index d183e4748a..672b7b44f1 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -131,10 +131,13 @@ if(NOT BOOTLOADER_BUILD) endif() if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - list(APPEND srcs "mspi_timing_tuning.c" "mspi_timing_config.c") + list(APPEND srcs "mspi_timing_tuning.c") if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY) list(APPEND srcs "mspi_timing_by_mspi_delay.c") endif() + if(CONFIG_SOC_MEMSPI_TIMING_TUNING_BY_DQS) + list(APPEND srcs "mspi_timing_by_dqs.c") + endif() endif() if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED) diff --git a/components/esp_hw_support/mspi_timing_config.h b/components/esp_hw_support/include/esp_private/mspi_timing_config.h similarity index 98% rename from components/esp_hw_support/mspi_timing_config.h rename to components/esp_hw_support/include/esp_private/mspi_timing_config.h index 5d2b411d5e..b3554826aa 100644 --- a/components/esp_hw_support/mspi_timing_config.h +++ b/components/esp_hw_support/include/esp_private/mspi_timing_config.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include "esp_private/mspi_timing_types.h" #ifdef __cplusplus diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 4f366e13f5..66f8618a5e 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -36,9 +36,12 @@ entries: systimer (noflash) if APP_BUILD_TYPE_PURE_RAM_APP = n: mspi_timing_tuning (noflash) - mspi_timing_config (noflash) if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY = y: mspi_timing_by_mspi_delay (noflash) + mspi_timing_config (noflash) + if SOC_MEMSPI_TIMING_TUNING_BY_DQS = y: + mspi_timing_by_dqs (noflash) + mspi_timing_config (noflash) if SOC_ADC_SHARED_POWER = y: if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: sar_periph_ctrl (noflash) diff --git a/components/esp_hw_support/mspi_timing_by_dqs.c b/components/esp_hw_support/mspi_timing_by_dqs.c new file mode 100644 index 0000000000..a8ced1f660 --- /dev/null +++ b/components/esp_hw_support/mspi_timing_by_dqs.c @@ -0,0 +1,239 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief + * + * This file contains configuration APIs doing MSPI timing tuning by MSPI dqs + * This file will only be built, when `SOC_MEMSPI_TIMING_TUNING_BY_DQS == 1` + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_types.h" +#include "esp_log.h" +#include "mspi_timing_by_dqs.h" +#include "mspi_timing_tuning_configs.h" +#include "esp_private/mspi_timing_config.h" +#include "esp_private/rtc_clk.h" +#include "esp_private/periph_ctrl.h" +#include "hal/psram_ctrlr_ll.h" +#include "hal/mspi_timing_tuning_ll.h" + +#define AP_HEX_PSRAM_SYNC_READ 0x0000 +#define AP_HEX_PSRAM_SYNC_WRITE 0x8080 +#define AP_HEX_PSRAM_RD_CMD_BITLEN 16 +#define AP_HEX_PSRAM_WR_CMD_BITLEN 16 +#define AP_HEX_PSRAM_ADDR_BITLEN 32 +#if CONFIG_SPIRAM_SPEED_250M +#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(18-1)) +#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(9-1)) +#elif CONFIG_SPIRAM_SPEED_200M +#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(14-1)) +#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(7-1)) +#else +#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(10-1)) +#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(5-1)) +#endif + +#define WRONG_DELAYLINE 16 + +const static char *TAG = "MSPI DQS"; +static uint32_t s_test_data[MSPI_TIMING_TEST_DATA_LEN] = {0x7f786655, 0xa5ff005a, 0x3f3c33aa, 0xa5ff5a00, 0x1f1e9955, 0xa5005aff, 0x0f0fccaa, 0xa55a00ff, + 0x07876655, 0xffa55a00, 0x03c333aa, 0xff00a55a, 0x01e19955, 0xff005aa5, 0x00f0ccaa, 0xff5a00a5, + 0x80786655, 0x00a5ff5a, 0xc03c33aa, 0x00a55aff, 0xe01e9355, 0x00ff5aa5, 0xf00fccaa, 0x005affa5, + 0xf8876655, 0x5aa5ff00, 0xfcc333aa, 0x5affa500, 0xfee19955, 0x5a00a5ff, 0x11f0ccaa, 0x5a00ffa5}; +static mspi_timing_config_t s_test_delayline_config = { + .delayline_table = {{15, 0}, {14, 0}, {13, 0}, {12, 0}, {11, 0}, {10, 0}, {9, 0}, {8, 0}, {7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}, + {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}}, + .available_config_num = 32, + }; +static mspi_ll_dqs_phase_t s_psram_best_phase = MSPI_LL_DQS_PHASE_MAX; +static delayline_config_t s_psram_best_delayline = {WRONG_DELAYLINE, WRONG_DELAYLINE}; + +void mspi_timing_psram_init(uint32_t psram_freq_mhz) +{ + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_3, false); + mspi_timing_config_set_psram_clock(psram_freq_mhz, MSPI_TIMING_SPEED_MODE_NORMAL_PERF, true); +} + +void mspi_timing_config_psram_prepare_reference_data(uint8_t *buf, uint32_t len) +{ + assert(len == MSPI_TIMING_TEST_DATA_LEN); + + memcpy(buf, &s_test_data, len); +} + +void mspi_timing_config_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint8_t *w_ptr = buf; + + while (len) { + int len_to_send = MIN(len, PSRAM_CTRLR_LL_FIFO_MAX_BYTES); + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_HEX_PSRAM_SYNC_WRITE, AP_HEX_PSRAM_WR_CMD_BITLEN, + addr, AP_HEX_PSRAM_ADDR_BITLEN, + AP_HEX_PSRAM_WR_DUMMY_BITLEN, + w_ptr, len_to_send * 8, + NULL, 0, + false); + w_ptr += len_to_send; + addr += len_to_send; + len -= len_to_send; + } +} + +void mspi_timing_config_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint8_t *r_ptr = buf; + + while (len) { + int len_to_recv = MIN(len, PSRAM_CTRLR_LL_FIFO_MAX_BYTES); + psram_ctrlr_ll_common_transaction(PSRAM_CTRLR_LL_MSPI_ID_3, + AP_HEX_PSRAM_SYNC_READ, AP_HEX_PSRAM_RD_CMD_BITLEN, + addr, AP_HEX_PSRAM_ADDR_BITLEN, + AP_HEX_PSRAM_RD_DUMMY_BITLEN, + NULL, 0, + r_ptr, len_to_recv * 8, + false); + r_ptr += len_to_recv; + addr += len_to_recv; + len -= len_to_recv; + } +} + +void mspi_timing_get_psram_tuning_phases(mspi_timing_config_t *configs) +{ + *configs = (mspi_timing_config_t) { + .phase = {MSPI_LL_DQS_PHASE_67_5, MSPI_LL_DQS_PHASE_78_75, MSPI_LL_DQS_PHASE_90, MSPI_LL_DQS_PHASE_101_25}, + .available_phase_num = 4, + }; +} + +void mspi_timing_config_psram_set_tuning_phase(const void *configs, uint8_t id) +{ + mspi_ll_dqs_phase_t phase = ((mspi_timing_config_t *)configs)->phase[id]; + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, phase); + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, phase); + ESP_EARLY_LOGD(TAG, "set to phase: %d", phase); +} + +uint32_t mspi_timing_psram_select_best_tuning_phase(const void *configs, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_ddr) +{ + assert(consecutive_length < 5); + uint32_t best_phase_id = 0; + + bool success = true; + if (consecutive_length == 0) { + best_phase_id = 0; + success = false; + } else if (consecutive_length == 1) { + best_phase_id = end; + } else if (consecutive_length == 2 || consecutive_length == 3){ + best_phase_id = end - 1; + } else { + best_phase_id = end - 2; + } + + if (success) { + ESP_EARLY_LOGI(TAG, "tuning success, best phase id is %"PRIu32, best_phase_id); + } else { + ESP_EARLY_LOGW(TAG, "tuning fail, best phase id is fallen back to index %"PRIu32"", best_phase_id); + } + + return best_phase_id; +} + +void mspi_timing_psram_set_best_tuning_phase(const void *configs, uint8_t best_id) +{ + s_psram_best_phase = ((mspi_timing_config_t *)configs)->phase[best_id]; +} + +void mspi_timing_get_psram_tuning_delaylines(mspi_timing_config_t *configs) +{ + ESP_EARLY_LOGD(TAG, "sizeof(delayline_config_t): %d, sizeof(test_config): %d", sizeof(delayline_config_t), sizeof(s_test_delayline_config)); + memcpy(configs, &s_test_delayline_config, sizeof(s_test_delayline_config)); +} + +void mspi_timing_config_psram_set_tuning_delayline(const void *configs, uint8_t id) +{ + assert(s_psram_best_phase != MSPI_LL_DQS_PHASE_MAX); + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, s_psram_best_phase); + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, s_psram_best_phase); + ESP_EARLY_LOGD(TAG, "set to best phase: %d", s_psram_best_phase); + + const delayline_config_t *delayline_config = &((mspi_timing_config_t *)configs)->delayline_table[id]; + for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { + if (i == MSPI_LL_PIN_DQS0 || i == MSPI_LL_PIN_DQS1) { + mspi_timing_ll_set_delayline(i, delayline_config->dqs_delayline); + } else { + mspi_timing_ll_set_delayline(i, delayline_config->data_delayline); + } + } + + ESP_EARLY_LOGD(TAG, "set to delayline: {%d, %d}", delayline_config->data_delayline, delayline_config->dqs_delayline); +} + +uint32_t mspi_timing_psram_select_best_tuning_delayline(const void *configs, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_ddr) +{ + assert(consecutive_length <= 32); + uint32_t bset_delayline_id = 0; + + if (consecutive_length <= 1) { + bset_delayline_id = 0; + ESP_EARLY_LOGW(TAG, "tuning fail, best delayline id is fallen back to index %"PRIu32"", bset_delayline_id); + } else { + bset_delayline_id = end - consecutive_length / 2; + ESP_EARLY_LOGI(TAG, "tuning success, best delayline id is %"PRIu32, bset_delayline_id); + } + + return bset_delayline_id; +} + +void mspi_timing_psram_set_best_tuning_delayline(const void *configs, uint8_t best_id) +{ + s_psram_best_delayline = ((mspi_timing_config_t *)configs)->delayline_table[best_id]; +} + +void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi) +{ + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, 0); + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, 0); + + for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { + mspi_timing_ll_set_delayline(i, 0); + } +} + +void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi) +{ + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_0, s_psram_best_phase); + mspi_timing_ll_set_dqs_phase(MSPI_LL_DQS_ID_1, s_psram_best_phase); + + for (int i = 0; i < MSPI_LL_PIN_MAX; i++) { + if (i == MSPI_LL_PIN_DQS0 || i == MSPI_LL_PIN_DQS1) { + mspi_timing_ll_set_delayline(i, s_psram_best_delayline.dqs_delayline); + } else { + mspi_timing_ll_set_delayline(i, s_psram_best_delayline.data_delayline); + } + } +} + +void mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi) +{ + //no need for now, may need set drvs + //keep for compatibility +} + +void mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi) +{ + //no need for now, may need clear drvs + //keep for compatibility +} diff --git a/components/esp_hw_support/mspi_timing_by_dqs.h b/components/esp_hw_support/mspi_timing_by_dqs.h new file mode 100644 index 0000000000..45147c5be8 --- /dev/null +++ b/components/esp_hw_support/mspi_timing_by_dqs.h @@ -0,0 +1,201 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief + * + * This file contains configuration APIs doing MSPI timing tuning by MSPI DQS + */ +#pragma once + +#include +#include "soc/soc_caps.h" +#if SOC_MEMSPI_TIMING_TUNING_BY_DQS +#include "mspi_timing_tuning_configs.h" +#include "hal/mspi_timing_tuning_ll.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_MEMSPI_TIMING_TUNING_BY_DQS + +#define IS_DDR 1 +#define IS_SDR (!IS_DDR) + + +/** + * Delayline + */ +typedef struct { + uint8_t data_delayline; + uint8_t dqs_delayline; +} __attribute__((packed)) delayline_config_t; + +/** + * MSPI timing tuning configurations + */ +typedef struct { + mspi_ll_dqs_phase_t phase[MSPI_LL_DQS_PHASE_MAX]; + delayline_config_t delayline_table[MSPI_TIMING_CONFIG_NUM_MAX]; + union { + uint32_t available_config_num; + uint32_t available_phase_num; + }; +} mspi_timing_config_t; + +/*------------------------------------------------------------------------------------------------- + * Timing Required APIs + *-------------------------------------------------------------------------------------------------*/ +/** + * @brief Init MSPI for PSRAM timing tuning + * + * @param[in] psram_freq_mhz PSRAM frequency in MHz + */ +void mspi_timing_psram_init(uint32_t psram_freq_mhz); + +/** + * @brief Prepare reference data buffer + */ +void mspi_timing_config_psram_prepare_reference_data(uint8_t *buf, uint32_t len); + +/** + * @brief Configure PSRAM to write data via MSPI3 + * + * @param[in] buf buffer + * @param[in] addr address + * @param[in] len length + */ +void mspi_timing_config_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t len); + +/** + * @brief Configure PSRAM to read data via MSPI3 + * + * @param[out] buf buffer + * @param[in] addr address + * @param[in] len length + */ +void mspi_timing_config_psram_read_data(uint8_t *buf, uint32_t addr, uint32_t len); + +/** + * @brief Get PSRAM tuning configurations for phase + * + * @param[out] config Pointer to PSRAM tuning configurations + */ +void mspi_timing_get_psram_tuning_phases(mspi_timing_config_t *configs); + +/** + * @brief Tune PSRAM timing registers for MSPI3 accessing PSRAM + * + * @param[in] configs Timing configs + * @param[in] id Config ID + */ +void mspi_timing_config_psram_set_tuning_phase(const void *configs, uint8_t id); + +/** + * @brief Select PSRAM best tuning configuration + * + * @param[in] configs Timing tuning configuration table + * @param[in] consecutive_length Length of the consecutive successful sample results + * @param[in] end End of the consecutive successful sample results + * @param[in] reference_data Reference data + * @param[in] is_ddr DDR or SDR + * + * @return Best config ID + */ +uint32_t mspi_timing_psram_select_best_tuning_phase(const void *configs, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_ddr); + +/** + * @brief Set best PSRAM tuning configs. + * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly + * + * @param[in] configs Timing tuning configs + * @param[in] best_id Best config ID + */ +void mspi_timing_psram_set_best_tuning_phase(const void *configs, uint8_t best_id); + +/** + * @brief Get PSRAM tuning configurations for delayline + * + * @param[out] config Pointer to PSRAM tuning configurations + */ +void mspi_timing_get_psram_tuning_delaylines(mspi_timing_config_t *configs); + +/** + * @brief Tune PSRAM timing registers for MSPI3 accessing PSRAM + * + * @param[in] configs Timing configs + * @param[in] id Config ID + */ +void mspi_timing_config_psram_set_tuning_delayline(const void *configs, uint8_t id); + +/** + * @brief Select PSRAM best tuning configuration + * + * @param[in] configs Timing tuning configuration table + * @param[in] consecutive_length Length of the consecutive successful sample results + * @param[in] end End of the consecutive successful sample results + * @param[in] reference_data Reference data + * @param[in] is_ddr DDR or SDR + * + * @return Best config ID + */ +uint32_t mspi_timing_psram_select_best_tuning_delayline(const void *configs, uint32_t consecutive_length, uint32_t end, const uint8_t *reference_data, bool is_ddr); + +/** + * @brief Set best PSRAM tuning configs. + * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly + * + * @param[in] configs Timing tuning configs + * @param[in] best_id Best config ID + */ +void mspi_timing_psram_set_best_tuning_delayline(const void *configs, uint8_t best_id); + +/*------------------------------------------------------------------------------------------------- + * General Timing APIs + *-------------------------------------------------------------------------------------------------*/ +/** + * @brief Set PSRAM timing tuning settings + * + * This is used when the system is going to high speed mode / MSPI needs to be run in high speed + * + * @param[in] control_both_mspi Control MSPI3 as well + */ +void mspi_timing_psram_config_set_tuning_regs(bool control_both_mspi); + +/** + * @brief Clear PSRAM timing tuning settings + * + * This is used when the system is going into low speed mode / MSPI doesn't need to be run in high speed + * + * @param[in] control_both_mspi Control MSPI3 as well + */ +void mspi_timing_psram_config_clear_tuning_regs(bool control_both_mspi); + +/** + * @brief Set Flash timing tuning settings + * + * This is used when the system is going to high speed mode / MSPI needs to be run in high speed + * + * @param[in] control_both_mspi Control MSPI1 as well + */ +void mspi_timing_flash_config_set_tuning_regs(bool control_both_mspi); + +/** + * @brief Clear Flash timing tuning settings + * + * This is used when the system is going into low speed mode / MSPI doesn't need to be run in high speed + * + * @param[in] control_both_mspi Control MSPI1 as well + */ +void mspi_timing_flash_config_clear_tuning_regs(bool control_both_mspi); + +#endif //#if SOC_MEMSPI_TIMING_TUNING_BY_DQS + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/mspi_timing_by_mspi_delay.c b/components/esp_hw_support/mspi_timing_by_mspi_delay.c index 9acf8ae47c..9ab56877a0 100644 --- a/components/esp_hw_support/mspi_timing_by_mspi_delay.c +++ b/components/esp_hw_support/mspi_timing_by_mspi_delay.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ #include "hal/mspi_timing_tuning_ll.h" #include "hal/clk_tree_ll.h" #include "hal/regi2c_ctrl_ll.h" -#include "mspi_timing_config.h" +#include "esp_private/mspi_timing_config.h" #include "mspi_timing_by_mspi_delay.h" #include "bootloader_flash.h" #include "esp32s3/rom/spi_flash.h" @@ -169,9 +169,9 @@ static void s_set_flash_extra_dummy(uint8_t spi_num, uint8_t extra_dummy) mspi_timing_ll_set_quad_flash_dummy(spi_num, dummy + g_rom_spiflash_dummy_len_plus[spi_num]); } -void mspi_timing_config_flash_set_tuning_regs(const void *timing_params) +void mspi_timing_config_flash_set_tuning_regs(const void *configs, uint8_t id) { - const mspi_timing_tuning_param_t *params = (const mspi_timing_tuning_param_t *)timing_params; + 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 @@ -239,9 +239,9 @@ static void s_set_psram_extra_dummy(uint8_t spi_num, uint8_t extra_dummy) #endif } -void mspi_timing_config_psram_set_tuning_regs(const void *timing_params) +void mspi_timing_config_psram_set_tuning_regs(const void *configs, uint8_t id) { - const mspi_timing_tuning_param_t *params = (const mspi_timing_tuning_param_t *)timing_params; + const mspi_timing_tuning_param_t *params = &((mspi_timing_config_t *)configs)->tuning_config_table[id]; /** * 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 @@ -322,6 +322,14 @@ static void s_psram_execution(uint8_t *buf, uint32_t addr, uint32_t len, bool is } } +void mspi_timing_config_psram_prepare_reference_data(uint8_t *buf, uint32_t len) +{ + assert((len == MSPI_TIMING_TEST_DATA_LEN) && (len % 4 == 0)); + for (int i=0; i < len/4; i++) { + ((uint32_t *)buf)[i] = 0xa5ff005a; + } +} + void mspi_timing_config_psram_write_data(uint8_t *buf, uint32_t addr, uint32_t len) { s_psram_execution(buf, addr, len, false); @@ -439,9 +447,9 @@ static uint32_t s_select_best_tuning_config_dtr(const mspi_timing_config_t *conf for (; current_point <= end; current_point++) { if (is_flash) { - mspi_timing_config_flash_set_tuning_regs(&(configs->tuning_config_table[current_point])); + mspi_timing_config_flash_set_tuning_regs(configs, current_point); } else { - mspi_timing_config_psram_set_tuning_regs(&(configs->tuning_config_table[current_point])); + mspi_timing_config_psram_set_tuning_regs(configs, current_point); } ret = get_working_pll_freq(reference_data, is_flash, &temp_max_freq, &temp_min_freq); @@ -522,16 +530,16 @@ uint32_t mspi_timing_psram_select_best_tuning_config(const void *configs, uint32 static mspi_timing_tuning_param_t s_flash_best_timing_tuning_config; static mspi_timing_tuning_param_t s_psram_best_timing_tuning_config; -void mspi_timing_flash_set_best_tuning_config(const void *timing_params) +void mspi_timing_flash_set_best_tuning_config(const void *configs, uint8_t best_id) { - const mspi_timing_tuning_param_t *params = (const mspi_timing_tuning_param_t *)timing_params; - s_flash_best_timing_tuning_config = *params; + const mspi_timing_tuning_param_t params = ((const mspi_timing_config_t *)configs)->tuning_config_table[best_id]; + s_flash_best_timing_tuning_config = params; } -void mspi_timing_psram_set_best_tuning_config(const void *timing_params) +void mspi_timing_psram_set_best_tuning_config(const void *configs, uint8_t best_id) { - const mspi_timing_tuning_param_t *params = (const mspi_timing_tuning_param_t *)timing_params; - s_psram_best_timing_tuning_config = *params; + const mspi_timing_tuning_param_t params = ((const mspi_timing_config_t *)configs)->tuning_config_table[best_id]; + s_psram_best_timing_tuning_config = params; } diff --git a/components/esp_hw_support/mspi_timing_by_mspi_delay.h b/components/esp_hw_support/mspi_timing_by_mspi_delay.h index b62ff74f1f..178d793260 100644 --- a/components/esp_hw_support/mspi_timing_by_mspi_delay.h +++ b/components/esp_hw_support/mspi_timing_by_mspi_delay.h @@ -40,7 +40,7 @@ typedef struct { * MSPI timing tuning configurations */ typedef struct { - mspi_timing_tuning_param_t tuning_config_table[MSPI_TIMING_CONFIG_NUM_DEFAULT]; // Available timing tuning configs + mspi_timing_tuning_param_t tuning_config_table[MSPI_TIMING_CONFIG_NUM_MAX]; // Available timing tuning configs uint32_t available_config_num; // Available timing tuning config numbers uint32_t default_config_id; // If tuning fails, we use this one as default } mspi_timing_config_t; @@ -67,9 +67,10 @@ void mspi_timing_flash_init(uint32_t flash_freq_mhz); /** * @brief Tune Flash timing registers for SPI1 accessing Flash * - * @param[in] params Timing parameters + * @param[in] configs Timing configs + * @param[in] id Config ID */ -void mspi_timing_config_flash_set_tuning_regs(const void *timing_params); +void mspi_timing_config_flash_set_tuning_regs(const void *configs, uint8_t id); /** * @brief Configure Flash to read data via SPI1 @@ -97,9 +98,15 @@ void mspi_timing_psram_init(uint32_t psram_freq_mhz); /** * @brief Tune PSRAM timing registers for SPI1 accessing PSRAM * - * @param[in] params Timing parameters + * @param[in] configs Timing configs + * @param[in] id Config ID */ -void mspi_timing_config_psram_set_tuning_regs(const void *timing_params); +void mspi_timing_config_psram_set_tuning_regs(const void *configs, uint8_t id); + +/** + * @brief Prepare reference data buffer + */ +void mspi_timing_config_psram_prepare_reference_data(uint8_t *buf, uint32_t len); /** * @brief Configure PSRAM to write data via SPI1 @@ -140,9 +147,10 @@ uint32_t mspi_timing_flash_select_best_tuning_config(const void *configs, uint32 * @brief Set best Flash tuning configs. * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly * - * @param[in] timing_params Timing tuning parameters + * @param[in] configs Timing tuning configs + * @param[in] best_id Best config ID */ -void mspi_timing_flash_set_best_tuning_config(const void *timing_params); +void mspi_timing_flash_set_best_tuning_config(const void *configs, uint8_t best_id); /** * @brief Select PSRAM best tuning configuration @@ -161,9 +169,10 @@ uint32_t mspi_timing_psram_select_best_tuning_config(const void *configs, uint32 * @brief Set best PSRAM tuning configs. * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly * - * @param[in] timing_params Timing tuning parameters + * @param[in] configs Timing tuning configs + * @param[in] best_id Best config ID */ -void mspi_timing_psram_set_best_tuning_config(const void *timing_params); +void mspi_timing_psram_set_best_tuning_config(const void *configs, uint8_t best_id); /*------------------------------------------------------------------------------------------------- diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index fd05a33000..f21295ef48 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -17,12 +17,16 @@ #include "hal/cache_hal.h" #include "hal/cache_ll.h" #include "esp_private/mspi_timing_tuning.h" -#include "mspi_timing_config.h" +#include "esp_private/mspi_timing_config.h" #include "mspi_timing_by_mspi_delay.h" -#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY +#include "mspi_timing_by_dqs.h" +#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY || SOC_MEMSPI_TIMING_TUNING_BY_DQS #include "mspi_timing_tuning_configs.h" #include "hal/mspi_timing_tuning_ll.h" #endif +#if SOC_MEMSPI_TIMING_TUNING_BY_DQS +#include "hal/psram_ctrlr_ll.h" +#endif #if SOC_MEMSPI_CLK_SRC_IS_INDEPENDENT #include "hal/spimem_flash_ll.h" #endif @@ -60,6 +64,8 @@ */ typedef enum { MSPI_TIMING_TUNING_MSPI_DIN_DUMMY, //tune by mspi din and dummy + MSPI_TIMING_TUNING_MSPI_DQS_PHASE, //tune by mspi dqs phase + MSPI_TIMING_TUNING_MSPI_DELAYLINE, //tune by mspi delayline } mspi_timing_tuning_t; typedef struct mspi_tuning_cfg_drv_s mspi_tuning_cfg_drv_t; @@ -72,6 +78,11 @@ struct mspi_tuning_cfg_drv_s { */ mspi_timing_tuning_t flash_tuning_type; + /** + * @brief How many test times during sweep + */ + uint32_t sweep_test_nums; + /** * @brief Init MSPI for Flash timing tuning * @@ -82,9 +93,10 @@ struct mspi_tuning_cfg_drv_s { /** * @brief Configure MSPI for Flash timing tuning * - * @param[in] params Timing tuning parameters + * @param[in] configs Timing tuning configs + * @param[in] id Config ID */ - void (*flash_tune_mspi)(const void *params); + void (*flash_tune_mspi)(const void *configs, uint8_t id); /** * @brief Flash read @@ -112,9 +124,10 @@ struct mspi_tuning_cfg_drv_s { * @brief Set best Flash tuning configs. * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly * - * @param[in] params Timing tuning parameters + * @param[in] configs Timing tuning configs + * @param[in] best_id Best config ID */ - void (*flash_set_best_tuning_config)(const void *params); + void (*flash_set_best_tuning_config)(const void *configs, uint8_t best_id); /** * @brief PSRAM tuning scheme type @@ -131,9 +144,10 @@ struct mspi_tuning_cfg_drv_s { /** * @brief Configure MSPI for PSRAM timing tuning * - * @param[in] params Timing tuning parameters + * @param[in] configs Timing tuning configs + * @param[in] id Config ID */ - void (*psram_tune_mspi)(const void *params); + void (*psram_tune_mspi)(const void *configs, uint8_t id); /** * @brief PSRAM read @@ -161,9 +175,10 @@ struct mspi_tuning_cfg_drv_s { * @brief Set best PSRAM tuning configs. * After this, calling `mspi_timing_enter_high_speed_mode` will set these configs correctly * - * @param[in] params Timing tuning parameters + * @param[in] configs Timing tuning config + * @param[in] best_id Best config ID */ - void (*psram_set_best_tuning_config)(const void *params); + void (*psram_set_best_tuning_config)(const void *configs, uint8_t best_id); }; static mspi_tuning_cfg_drv_t s_tuning_cfg_drv = {}; @@ -185,6 +200,7 @@ void s_register_config_driver(mspi_tuning_cfg_drv_t *cfg_drv, bool is_flash) s_tuning_cfg_drv.psram_select_best_tuning_config = cfg_drv->psram_select_best_tuning_config; s_tuning_cfg_drv.psram_set_best_tuning_config = cfg_drv->psram_set_best_tuning_config; } + s_tuning_cfg_drv.sweep_test_nums = cfg_drv->sweep_test_nums; } #if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING @@ -192,33 +208,36 @@ void s_register_config_driver(mspi_tuning_cfg_drv_t *cfg_drv, bool is_flash) * We use different MSPI 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 s_sweep_for_success_sample_points(uint8_t *reference_data, void *config, bool is_flash, uint8_t *out_array) +static void s_sweep_for_success_sample_points(uint8_t *reference_data, void *config, bool is_flash, uint32_t *out_array) { const mspi_timing_config_t *timing_config = (const mspi_timing_config_t *)config; uint32_t config_idx = 0; uint8_t read_data[MSPI_TIMING_TEST_DATA_LEN] = {0}; for (config_idx = 0; config_idx < timing_config->available_config_num; config_idx++) { - memset(read_data, 0, MSPI_TIMING_TEST_DATA_LEN); + for (int i = 0; i < s_tuning_cfg_drv.sweep_test_nums; i++) { + memset(read_data, 0, MSPI_TIMING_TEST_DATA_LEN); #if MSPI_TIMING_FLASH_NEEDS_TUNING - if (is_flash) { - s_tuning_cfg_drv.flash_tune_mspi(&(timing_config->tuning_config_table[config_idx])); - s_tuning_cfg_drv.flash_read(read_data, MSPI_TIMING_FLASH_TEST_DATA_ADDR, sizeof(read_data)); - } + if (is_flash) { + s_tuning_cfg_drv.flash_tune_mspi(timing_config, config_idx); + s_tuning_cfg_drv.flash_read(read_data, MSPI_TIMING_FLASH_TEST_DATA_ADDR, sizeof(read_data)); + } #endif #if MSPI_TIMING_PSRAM_NEEDS_TUNING - if (!is_flash) { - s_tuning_cfg_drv.psram_tune_mspi(&(timing_config->tuning_config_table[config_idx])); - s_tuning_cfg_drv.psram_read(read_data, MSPI_TIMING_PSRAM_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); - } + if (!is_flash) { + s_tuning_cfg_drv.psram_tune_mspi(timing_config, config_idx); + s_tuning_cfg_drv.psram_read(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, "%"PRIu32", good", config_idx); - } else { - ESP_EARLY_LOGD(TAG, "%"PRIu32", bad", config_idx); + if (memcmp(reference_data, read_data, sizeof(read_data)) == 0) { + out_array[config_idx] += 1; + } } + } + ESP_EARLY_LOGD(TAG, "test nums: %d, test result: [id][good/bad][good_times]:", s_tuning_cfg_drv.sweep_test_nums); + for (config_idx = 0; config_idx < timing_config->available_config_num; config_idx++) { + ESP_EARLY_LOGD(TAG, "[%"PRIu32"][%s][%d] ", config_idx, out_array[config_idx] == s_tuning_cfg_drv.sweep_test_nums ? "good" : "bad", out_array[config_idx]); } } @@ -228,7 +247,7 @@ static void s_sweep_for_success_sample_points(uint8_t *reference_data, void *con * out_length: 3 * outout_end_index: 6 */ -static void s_find_max_consecutive_success_points(uint8_t *array, uint32_t size, uint32_t *out_length, uint32_t *out_end_index) +static void s_find_max_consecutive_success_points(uint32_t *array, uint32_t size, uint32_t *out_length, uint32_t *out_end_index) { uint32_t max = 0; uint32_t match_num = 0; @@ -236,7 +255,7 @@ static void s_find_max_consecutive_success_points(uint8_t *array, uint32_t size, uint32_t end = 0; while (i < size) { - if (array[i]) { + if (array[i] == s_tuning_cfg_drv.sweep_test_nums) { match_num++; } else { if (match_num > max) { @@ -262,18 +281,18 @@ static void s_select_best_tuning_config(mspi_timing_config_t *config, uint32_t c #elif MSPI_TIMING_FLASH_STR_MODE best_point = s_tuning_cfg_drv.flash_select_best_tuning_config(timing_config, consecutive_length, end, NULL, IS_SDR); #endif - s_tuning_cfg_drv.flash_set_best_tuning_config(&(timing_config->tuning_config_table[best_point])); + s_tuning_cfg_drv.flash_set_best_tuning_config(timing_config, best_point); } else { #if MSPI_TIMING_PSRAM_DTR_MODE best_point = s_tuning_cfg_drv.psram_select_best_tuning_config(timing_config, consecutive_length, end, reference_data, IS_DDR); #elif MSPI_TIMING_PSRAM_STR_MODE best_point = s_tuning_cfg_drv.psram_select_best_tuning_config(timing_config, consecutive_length, end, NULL, IS_SDR); #endif - s_tuning_cfg_drv.psram_set_best_tuning_config(&(timing_config->tuning_config_table[best_point])); + s_tuning_cfg_drv.psram_set_best_tuning_config(timing_config, best_point); } } -static void s_do_tuning(uint8_t *reference_data, void *timing_config, bool is_flash) +static void s_do_tuning(uint8_t *reference_data, mspi_timing_config_t *config, bool is_flash) { /** * We use MSPI to tune the timing: @@ -283,7 +302,7 @@ static void s_do_tuning(uint8_t *reference_data, void *timing_config, bool is_fl */ uint32_t consecutive_length = 0; uint32_t last_success_point = 0; - uint8_t sample_result[MSPI_TIMING_CONFIG_NUM_DEFAULT] = {0}; + uint32_t sample_result[MSPI_TIMING_CONFIG_NUM_MAX] = {0}; #if MSPI_TIMING_FLASH_NEEDS_TUNING if (is_flash) { @@ -296,9 +315,9 @@ static void s_do_tuning(uint8_t *reference_data, void *timing_config, bool is_fl } #endif - s_sweep_for_success_sample_points(reference_data, timing_config, is_flash, sample_result); - s_find_max_consecutive_success_points(sample_result, MSPI_TIMING_CONFIG_NUM_DEFAULT, &consecutive_length, &last_success_point); - s_select_best_tuning_config(timing_config, consecutive_length, last_success_point, reference_data, is_flash); + s_sweep_for_success_sample_points(reference_data, config, is_flash, sample_result); + s_find_max_consecutive_success_points(sample_result, config->available_config_num, &consecutive_length, &last_success_point); + s_select_best_tuning_config(config, consecutive_length, last_success_point, reference_data, is_flash); } #endif //#if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING @@ -318,6 +337,7 @@ void mspi_timing_flash_tuning(void) #if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY mspi_tuning_cfg_drv_t drv = { .flash_tuning_type = MSPI_TIMING_TUNING_MSPI_DIN_DUMMY, + .sweep_test_nums = 1, .flash_init_mspi = mspi_timing_flash_init, .flash_tune_mspi = mspi_timing_config_flash_set_tuning_regs, .flash_read = mspi_timing_config_flash_read_data, @@ -362,16 +382,15 @@ void mspi_timing_psram_tuning(void) */ mspi_timing_enter_low_speed_mode(true); -#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY // write data into psram, used to do timing tuning test. uint8_t reference_data[MSPI_TIMING_TEST_DATA_LEN]; - for (int i=0; i < MSPI_TIMING_TEST_DATA_LEN/4; i++) { - ((uint32_t *)reference_data)[i] = 0xa5ff005a; - } + mspi_timing_config_psram_prepare_reference_data(reference_data, MSPI_TIMING_TEST_DATA_LEN); mspi_timing_config_psram_write_data(reference_data, MSPI_TIMING_PSRAM_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); +#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY mspi_tuning_cfg_drv_t drv = { .psram_tuning_type = MSPI_TIMING_TUNING_MSPI_DIN_DUMMY, + .sweep_test_nums = 1, .psram_init_mspi = mspi_timing_psram_init, .psram_tune_mspi = mspi_timing_config_psram_set_tuning_regs, .psram_read = mspi_timing_config_psram_read_data, @@ -381,14 +400,48 @@ void mspi_timing_psram_tuning(void) bool is_flash = false; s_register_config_driver(&drv, is_flash); - mspi_timing_config_t timing_configs = {0}; + mspi_timing_config_t timing_configs = {}; mspi_timing_get_psram_tuning_configs(&timing_configs); -#endif //#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY //Disable the variable dummy mode when doing timing tuning mspi_timing_ll_enable_flash_variable_dummy(1, false); + //Get required config, and set them to PSRAM related registers s_do_tuning(reference_data, &timing_configs, false); +#endif //#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY + +#if SOC_MEMSPI_TIMING_TUNING_BY_DQS + bool is_flash = false; + mspi_timing_config_t timing_configs = {}; + + //Phase + mspi_tuning_cfg_drv_t drv = { + .psram_tuning_type = MSPI_TIMING_TUNING_MSPI_DQS_PHASE, + .sweep_test_nums = 1, + .psram_init_mspi = mspi_timing_psram_init, + .psram_tune_mspi = mspi_timing_config_psram_set_tuning_phase, + .psram_read = mspi_timing_config_psram_read_data, + .psram_select_best_tuning_config = mspi_timing_psram_select_best_tuning_phase, + .psram_set_best_tuning_config = mspi_timing_psram_set_best_tuning_phase, + }; + s_register_config_driver(&drv, is_flash); + mspi_timing_get_psram_tuning_phases(&timing_configs); + s_do_tuning(reference_data, &timing_configs, false); + + //Delayline + drv = (mspi_tuning_cfg_drv_t) { + .psram_tuning_type = MSPI_TIMING_TUNING_MSPI_DELAYLINE, + .sweep_test_nums = MSPI_TIMING_DELAYLINE_TEST_NUMS, + .psram_init_mspi = mspi_timing_psram_init, + .psram_tune_mspi = mspi_timing_config_psram_set_tuning_delayline, + .psram_read = mspi_timing_config_psram_read_data, + .psram_select_best_tuning_config = mspi_timing_psram_select_best_tuning_delayline, + .psram_set_best_tuning_config = mspi_timing_psram_set_best_tuning_delayline, + }; + s_register_config_driver(&drv, is_flash); + mspi_timing_get_psram_tuning_delaylines(&timing_configs); + s_do_tuning(reference_data, &timing_configs, false); +#endif mspi_timing_enter_high_speed_mode(true); } @@ -495,14 +548,22 @@ void mspi_timing_change_speed_mode_cache_safe(bool switch_down) *----------------------------------------------------------------------------*/ bool spi_timing_is_tuned(void) { +#if MSPI_TIMING_MSPI1_IS_INVOLVED + //esp flash driver needs to be notified #if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING + //either flash or psram or both is tuned, needs notify flash driver return true; #else + //otherwise no need return false; #endif +#else + //if mspi1 is not involved in timing tuning + return false; +#endif //MSPI_TIMING_MSPI1_IS_INVOLVED } -#if MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING +#if MSPI_TIMING_MSPI1_IS_INVOLVED && (MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING) void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing_config) { // Get clock configuration directly from system. @@ -522,7 +583,7 @@ void spi_timing_get_flash_timing_param(spi_flash_hal_timing_config_t *out_timing // This function shouldn't be called if timing tuning is not used. abort(); } -#endif // MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING +#endif // #if MSPI_TIMING_MSPI1_IS_INVOLVED && (MSPI_TIMING_FLASH_NEEDS_TUNING || MSPI_TIMING_PSRAM_NEEDS_TUNING) /*------------------------------------------------------------------------------ * Common settings diff --git a/components/esp_hw_support/port/esp32p4/CMakeLists.txt b/components/esp_hw_support/port/esp32p4/CMakeLists.txt index e7e47df66b..abfc09d1cb 100644 --- a/components/esp_hw_support/port/esp32p4/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32p4/CMakeLists.txt @@ -1,3 +1,5 @@ +target_include_directories(${COMPONENT_LIB} PUBLIC .) + set(srcs "rtc_clk_init.c" "rtc_clk.c" "pmu_param.c" @@ -10,6 +12,10 @@ set(srcs "rtc_clk_init.c" if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_crypto_lock.c") + if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs "mspi_timing_config.c") + endif() + if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE) list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c") endif() diff --git a/components/esp_hw_support/port/esp32p4/mspi_timing_config.c b/components/esp_hw_support/port/esp32p4/mspi_timing_config.c new file mode 100644 index 0000000000..188ae4957f --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/mspi_timing_config.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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" + +const static char *TAG = "MSPI Timing"; + +//-------------------------------------MSPI Clock Setting-------------------------------------// +void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi) +{ + uint32_t freqdiv = MSPI_TIMING_MPLL_FREQ_MHZ / MSPI_TIMING_CORE_CLOCK_DIV / psram_freq_mhz; + assert(freqdiv > 0); + ESP_EARLY_LOGD(TAG, "psram_freq_mhz: %d mhz, bus clock div: %d", psram_freq_mhz, freqdiv); + PERIPH_RCC_ATOMIC() { + //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + psram_ctrlr_ll_set_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, freqdiv); + } +} + +void mspi_timing_config_set_flash_clock(uint32_t flash_freq_mhz, mspi_timing_speed_mode_t speed_mode, bool control_both_mspi) +{ + //For compatibility +} diff --git a/components/esp_hw_support/port/esp32p4/mspi_timing_tuning_configs.h b/components/esp_hw_support/port/esp32p4/mspi_timing_tuning_configs.h new file mode 100644 index 0000000000..d8ffa101ea --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/mspi_timing_tuning_configs.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" + +#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 0x80 +#define MSPI_TIMING_DELAYLINE_TEST_NUMS 100 + +#define MSPI_TIMING_CORE_CLOCK_DIV 1 +#if CONFIG_SPIRAM_SPEED_250M +#define MSPI_TIMING_PSRAM_NEEDS_TUNING 1 +#define MSPI_TIMING_MPLL_FREQ_MHZ 500 +#elif CONFIG_SPIRAM_SPEED_200M +#define MSPI_TIMING_PSRAM_NEEDS_TUNING 1 +#define MSPI_TIMING_MPLL_FREQ_MHZ 400 +#else +#define MSPI_TIMING_MPLL_FREQ_MHZ 400 +#endif + +#define MSPI_TIMING_PSRAM_DTR_MODE CONFIG_SPIRAM_MODE_HEX diff --git a/components/esp_hw_support/port/esp32s3/CMakeLists.txt b/components/esp_hw_support/port/esp32s3/CMakeLists.txt index 4829b57f34..6e8f253572 100644 --- a/components/esp_hw_support/port/esp32s3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s3/CMakeLists.txt @@ -13,6 +13,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_crypto_lock.c" "sar_periph_ctrl.c") + if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) + list(APPEND srcs "mspi_timing_config.c") + endif() + if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE) list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c") endif() diff --git a/components/esp_hw_support/mspi_timing_config.c b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c similarity index 90% rename from components/esp_hw_support/mspi_timing_config.c rename to components/esp_hw_support/port/esp32s3/mspi_timing_config.c index 9b55166eb4..a504bcdd92 100644 --- a/components/esp_hw_support/mspi_timing_config.c +++ b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c @@ -11,22 +11,15 @@ #include "esp_types.h" #include "esp_log.h" #include "soc/soc_caps.h" -#include "mspi_timing_config.h" -#if SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY +#include "esp_private/mspi_timing_config.h" #include "mspi_timing_tuning_configs.h" #include "hal/mspi_timing_tuning_ll.h" -#endif - -#if SOC_MEMSPI_CORE_CLK_SHARED_WITH_PSRAM #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 -#endif //SOC_MEMSPI_CORE_CLK_SHARED_WITH_PSRAM - -#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING /** * Currently we only need these on chips with timing tuning */ @@ -76,4 +69,3 @@ void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_spe assert(freqdiv > 0); mspi_timing_ll_set_psram_clock(0, freqdiv); } -#endif //#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING diff --git a/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h b/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h index 98afa87078..b20cf0a69a 100644 --- a/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h +++ b/components/esp_hw_support/port/esp32s3/mspi_timing_tuning_configs.h @@ -9,7 +9,8 @@ #include "esp_assert.h" #include "esp_flash_partitions.h" -#define MSPI_TIMING_CONFIG_NUM_DEFAULT 20 //This should be larger than the max available timing config num +#define MSPI_TIMING_MSPI1_IS_INVOLVED 1 //This means esp flash driver needs to be notified +#define MSPI_TIMING_CONFIG_NUM_MAX 20 //This should be larger than the max available timing config num #define MSPI_TIMING_TEST_DATA_LEN 64 #define MSPI_TIMING_PSRAM_TEST_DATA_ADDR 0 #define MSPI_TIMING_FLASH_TEST_DATA_ADDR ESP_BOOTLOADER_OFFSET diff --git a/components/esp_psram/device/esp_psram_impl_ap_hex.c b/components/esp_psram/device/esp_psram_impl_ap_hex.c index 59fa7d6500..168235c1ca 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_hex.c +++ b/components/esp_psram/device/esp_psram_impl_ap_hex.c @@ -12,10 +12,10 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/rtc_clk.h" #include "esp_private/esp_ldo_psram.h" +#include "esp_private/mspi_timing_tuning.h" #include "../esp_psram_impl.h" -#include "rom/opi_flash.h" #include "hal/psram_ctrlr_ll.h" -#include "hal/ldo_ll.h" +#include "hal/mspi_timing_tuning_ll.h" // Reset and Clock Control registers are mixing with other peripherals, so we need to use a critical section #define PSRAM_RCC_ATOMIC() PERIPH_RCC_ATOMIC() @@ -29,10 +29,25 @@ #define AP_HEX_PSRAM_RD_CMD_BITLEN 16 #define AP_HEX_PSRAM_WR_CMD_BITLEN 16 #define AP_HEX_PSRAM_ADDR_BITLEN 32 + +#if CONFIG_SPIRAM_SPEED_250M +#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(18-1)) +#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(9-1)) +#define AP_HEX_PSRAM_RD_LATENCY 6 +#define AP_HEX_PSRAM_WR_LATENCY 3 +#elif CONFIG_SPIRAM_SPEED_200M +#define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(14-1)) +#define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(7-1)) +#define AP_HEX_PSRAM_RD_LATENCY 4 +#define AP_HEX_PSRAM_WR_LATENCY 1 +#else #define AP_HEX_PSRAM_RD_DUMMY_BITLEN (2*(10-1)) #define AP_HEX_PSRAM_WR_DUMMY_BITLEN (2*(5-1)) -#define AP_HEX_PSRAM_VENDOR_ID 0xD +#define AP_HEX_PSRAM_RD_LATENCY 2 +#define AP_HEX_PSRAM_WR_LATENCY 2 +#endif +#define AP_HEX_PSRAM_VENDOR_ID 0xD #define AP_HEX_PSRAM_CS_SETUP_TIME 4 #define AP_HEX_PSRAM_CS_HOLD_TIME 4 #define AP_HEX_PSRAM_CS_ECC_HOLD_TIME 4 @@ -164,7 +179,6 @@ static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_co false); addr = 0x4; - //write s_psram_common_transaction(spi_num, AP_HEX_PSRAM_REG_WRITE, cmd_len, addr, addr_bit_len, @@ -173,9 +187,9 @@ static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_co NULL, 0, false); + //read addr = 0x8; data_bit_len = 8; - //read s_psram_common_transaction(spi_num, AP_HEX_PSRAM_REG_READ, cmd_len, addr, addr_bit_len, @@ -269,11 +283,9 @@ static void s_print_psram_info(hex_psram_mode_reg_t *reg_val) static void s_config_mspi_for_psram(void) { - //TODO: IDF-6495, to change back to burst cmd //Config Write CMD phase for SPI0 to access PSRAM psram_ctrlr_ll_set_wr_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_WR_CMD_BITLEN, AP_HEX_PSRAM_SYNC_WRITE); - //TODO: IDF-6495, to change back to burst cmd //Config Read CMD phase for SPI0 to access PSRAM psram_ctrlr_ll_set_rd_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_RD_CMD_BITLEN, AP_HEX_PSRAM_SYNC_READ); @@ -363,26 +375,28 @@ esp_err_t esp_psram_impl_enable(void) PSRAM_RCC_ATOMIC() { psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); psram_ctrlr_ll_reset_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2); - psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL); - psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_XTAL); + psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL); + psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL); } + mspi_timing_ll_pin_drv_set(2); + mspi_timing_ll_enable_dqs(true); + s_set_psram_cs_timing(); #if CONFIG_SPIRAM_ECC_ENABLE s_configure_psram_ecc(); #endif //enter MSPI slow mode to init PSRAM device registers - psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, 2); - psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, 2); - //TODO: IDF-6495, to add back - // psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true); - // psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, 40); + psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, 40); + psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_dll(PSRAM_CTRLR_LL_MSPI_ID_3, true); static hex_psram_mode_reg_t mode_reg = {}; mode_reg.mr0.lt = 1; - mode_reg.mr0.read_latency = 2; + mode_reg.mr0.read_latency = AP_HEX_PSRAM_RD_LATENCY; mode_reg.mr0.drive_str = 0; - mode_reg.mr4.wr_latency = 2; + mode_reg.mr4.wr_latency = AP_HEX_PSRAM_WR_LATENCY; mode_reg.mr8.bl = 3; mode_reg.mr8.bt = 0; mode_reg.mr8.rbx = 1; @@ -404,7 +418,18 @@ esp_err_t esp_psram_impl_enable(void) mode_reg.mr2.density == 0x7 ? PSRAM_SIZE_32MB : mode_reg.mr2.density == 0x6 ? PSRAM_SIZE_64MB : 0; +#if CONFIG_SPIRAM_SPEED_250M + if (mode_reg.mr2.density == 0x7) { + ESP_EARLY_LOGE(TAG, "PSRAM Not support 250MHz speed"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif + s_config_mspi_for_psram(); + mspi_timing_psram_tuning(); + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_enable_variable_dummy(PSRAM_CTRLR_LL_MSPI_ID_3, true); + return ESP_OK; } diff --git a/components/esp_psram/esp32p4/Kconfig.spiram b/components/esp_psram/esp32p4/Kconfig.spiram index dd25eee869..ea37e7f54b 100644 --- a/components/esp_psram/esp32p4/Kconfig.spiram +++ b/components/esp_psram/esp32p4/Kconfig.spiram @@ -30,6 +30,10 @@ menu "PSRAM config" help Select the speed for the PSRAM chip. + config SPIRAM_SPEED_200M + depends on IDF_EXPERIMENTAL_FEATURES + bool "200MHz clock speed" + config SPIRAM_SPEED_20M bool "20MHz clock speed" endchoice @@ -37,6 +41,8 @@ menu "PSRAM config" config SPIRAM_SPEED int default 20 if SPIRAM_SPEED_20M + default 100 if SPIRAM_SPEED_100M + default 200 if SPIRAM_SPEED_200M config SPIRAM_ECC_ENABLE bool "Enable PSRAM ECC" diff --git a/components/esp_psram/test_apps/psram/main/test_psram.c b/components/esp_psram/test_apps/psram/main/test_psram.c index 886afe7c1c..d93e3cf83c 100644 --- a/components/esp_psram/test_apps/psram/main/test_psram.c +++ b/components/esp_psram/test_apps/psram/main/test_psram.c @@ -22,7 +22,7 @@ __attribute__((unused)) const static char *TAG = "PSRAM"; -TEST_CASE("test psram heap allocable", "[psram]") +static void s_test_psram_heap_allocable(void) { size_t largest_size = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM); ESP_LOGI(TAG, "largest size is %zu", largest_size); @@ -46,6 +46,18 @@ TEST_CASE("test psram heap allocable", "[psram]") free(ext_buffer); } +TEST_CASE("test psram heap allocable", "[psram]") +{ + s_test_psram_heap_allocable(); +} + +TEST_CASE("stress test psram heap allocable", "[psram][manual][ignore]") +{ + for (int times = 0; times < 50; times++) { + s_test_psram_heap_allocable(); + } +} + #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA #include "esp_partition.h" #include "driver/gptimer.h" diff --git a/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h new file mode 100644 index 0000000000..9f2e152698 --- /dev/null +++ b/components/hal/esp32p4/include/hal/mspi_timing_tuning_ll.h @@ -0,0 +1,190 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/soc.h" +#include "soc/iomux_mspi_pin_reg.h" +#include "soc/iomux_mspi_pin_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * MSPI DQS ID + */ +typedef enum { + MSPI_LL_DQS_ID_0, + MSPI_LL_DQS_ID_1, +} mspi_ll_dqs_id_t; + +/** + * MSPI DQS Phase + */ +typedef enum { + MSPI_LL_DQS_PHASE_67_5, + MSPI_LL_DQS_PHASE_78_75, + MSPI_LL_DQS_PHASE_90, + MSPI_LL_DQS_PHASE_101_25, + MSPI_LL_DQS_PHASE_MAX, +} mspi_ll_dqs_phase_t; + +/** + * MSPI Delayline + * + * @note The Sequence of these enums should not be changed + */ +typedef enum { + MSPI_LL_PIN_D = 0, + MSPI_LL_PIN_Q, + MSPI_LL_PIN_WP, + MSPI_LL_PIN_HD, + MSPI_LL_PIN_D4, + MSPI_LL_PIN_D5, + MSPI_LL_PIN_D6, + MSPI_LL_PIN_D7, + MSPI_LL_PIN_DQS0, + MSPI_LL_PIN_CLK, + MSPI_LL_PIN_CS, + MSPI_LL_PIN_D8, + MSPI_LL_PIN_D9, + MSPI_LL_PIN_D10, + MSPI_LL_PIN_D11, + MSPI_LL_PIN_D12, + MSPI_LL_PIN_D13, + MSPI_LL_PIN_D14, + MSPI_LL_PIN_D15, + MSPI_LL_PIN_DQS1, + MSPI_LL_PIN_MAX, +} mspi_ll_pin_t; + +/** + * Set all MSPI DQS phase + * + * @param dqs_id DQS ID + * @param phase Phase + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_set_dqs_phase(mspi_ll_dqs_id_t dqs_id, mspi_ll_dqs_phase_t phase) +{ + HAL_ASSERT(dqs_id < 2); + if (dqs_id == MSPI_LL_DQS_ID_0) { + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_PHASE, phase); + } else { + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_1_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_PHASE, phase); + } +} + +/** + * Set all MSPI delayline + * + * @param pin Pin + * @param delayline Delayline + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_set_delayline(mspi_ll_pin_t pin, uint8_t delayline) +{ + HAL_ASSERT(pin < MSPI_LL_PIN_MAX); + + switch (pin) { + case MSPI_LL_PIN_DQS0: + MSPI_IOMUX.psram_pin_group.dqs0.reg_psram_dqs_delay_90 = delayline; + MSPI_IOMUX.psram_pin_group.dqs0.reg_psram_dqs_delay_270 = delayline; + break; + case MSPI_LL_PIN_DQS1: + MSPI_IOMUX.psram_pin_group.dqs1.reg_psram_dqs_delay_90 = delayline; + MSPI_IOMUX.psram_pin_group.dqs1.reg_psram_dqs_delay_270 = delayline; + break; + case MSPI_LL_PIN_D: + case MSPI_LL_PIN_Q: + case MSPI_LL_PIN_WP: + case MSPI_LL_PIN_HD: + case MSPI_LL_PIN_D4: + case MSPI_LL_PIN_D5: + case MSPI_LL_PIN_D6: + case MSPI_LL_PIN_D7: + MSPI_IOMUX.psram_pin_group.pin_group0[pin].reg_psram_pin_dlc = delayline; + break; + case MSPI_LL_PIN_CLK: + case MSPI_LL_PIN_CS: + case MSPI_LL_PIN_D8: + case MSPI_LL_PIN_D9: + case MSPI_LL_PIN_D10: + case MSPI_LL_PIN_D11: + case MSPI_LL_PIN_D12: + case MSPI_LL_PIN_D13: + case MSPI_LL_PIN_D14: + case MSPI_LL_PIN_D15: + pin = (mspi_ll_pin_t)(pin - MSPI_LL_PIN_CLK); + MSPI_IOMUX.psram_pin_group.pin_group1[pin].reg_psram_pin_dlc = delayline; + break; + default: + HAL_ASSERT(false); + break; + } +} + +/** + * Enable DQS + * + * @param en Enable/disable + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_enable_dqs(bool en) +{ + if (en) { + REG_SET_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_XPD); + REG_SET_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_1_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_XPD); + } else { + REG_CLR_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_XPD); + REG_CLR_BIT(IOMUX_MSPI_PIN_PSRAM_DQS_1_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_XPD); + } +} + + +/** + * Set all MSPI pin drive + * + * @param drv Pin drive + */ +__attribute__((always_inline)) +static inline void mspi_timing_ll_pin_drv_set(uint8_t drv) +{ + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_D_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_Q_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_Q_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_WP_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_WP_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_HOLD_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_HOLD_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ4_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ4_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ5_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ5_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ6_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ6_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ7_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ7_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ8_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ8_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ9_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ9_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ10_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ10_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ11_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ11_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ12_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ12_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ13_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ13_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ14_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ14_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQ15_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQ15_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_0_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_0_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_DQS_1_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_CK_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_CK_DRV, drv); + REG_SET_FIELD(IOMUX_MSPI_PIN_PSRAM_CS_PIN0_REG, IOMUX_MSPI_PIN_REG_PSRAM_CS_DRV, drv); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h index 3303ce81e2..438f474d52 100644 --- a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h @@ -16,8 +16,11 @@ #include #include #include "hal/assert.h" +#include "hal/misc.h" #include "soc/spi_mem_s_struct.h" #include "soc/spi_mem_s_reg.h" +#include "soc/spi1_mem_s_reg.h" +#include "soc/spi1_mem_s_struct.h" #include "soc/hp_sys_clkrst_struct.h" #include "soc/clk_tree_defs.h" #include "rom/opi_flash.h" @@ -26,13 +29,15 @@ extern "C" { #endif -#define PSRAM_CTRLR_LL_MSPI_ID_2 2 -#define PSRAM_CTRLR_LL_MSPI_ID_3 3 +#define PSRAM_CTRLR_LL_MSPI_ID_2 2 +#define PSRAM_CTRLR_LL_MSPI_ID_3 3 #define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 #define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) #define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) +#define PSRAM_CTRLR_LL_FIFO_MAX_BYTES 64 + /** * @brief Set PSRAM write cmd @@ -134,8 +139,11 @@ static inline void psram_ctrlr_ll_set_rd_dummy(uint32_t mspi_id, uint32_t dummy_ __attribute__((always_inline)) static inline void psram_ctrlr_ll_enable_variable_dummy(uint32_t mspi_id, bool en) { - (void)mspi_id; - SPIMEM2.smem_ddr.smem_var_dummy = en; + if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) { + SPIMEM2.smem_ddr.smem_var_dummy = en; + } else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) { + SPIMEM3.ddr.fmem_var_dummy = en; + } } /** @@ -350,15 +358,20 @@ static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph /** * @brief Set PSRAM core clock * - * @param mspi_id mspi_id - * @param core_clk_mhz core clock mhz + * @param mspi_id mspi_id + * @param freqdiv Divider value */ __attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_core_clock(uint8_t spi_num, uint32_t core_clk_mhz) +static inline void psram_ctrlr_ll_set_core_clock(uint8_t spi_num, uint32_t freqdiv) { - //TODO: IDF-7517 + HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_core_clk_en = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl00, reg_psram_core_clk_div_num, freqdiv - 1); } +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_set_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_set_core_clock(__VA_ARGS__) + /** * @brief Set PSRAM bus clock * @@ -368,12 +381,20 @@ static inline void psram_ctrlr_ll_set_core_clock(uint8_t spi_num, uint32_t core_ __attribute__((always_inline)) static inline void psram_ctrlr_ll_set_bus_clock(uint32_t mspi_id, uint32_t freqdiv) { - (void)mspi_id; - if (freqdiv == 1) { - WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, SPI_MEM_S_SCLK_EQU_SYSCLK); - } else { - uint32_t freqbits = (((freqdiv - 1) << SPI_MEM_S_SCLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_S_SCLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_S_SCLKCNT_L_S); - WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, freqbits); + if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_2) { + if (freqdiv == 1) { + WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, SPI_MEM_S_SCLK_EQU_SYSCLK); + } else { + uint32_t freqbits = (((freqdiv - 1) << SPI_MEM_S_SCLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_S_SCLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_S_SCLKCNT_L_S); + WRITE_PERI_REG(SPI_MEM_S_SRAM_CLK_REG, freqbits); + } + } else if (mspi_id == PSRAM_CTRLR_LL_MSPI_ID_3) { + if (freqdiv == 1) { + WRITE_PERI_REG(SPI1_MEM_S_CLOCK_REG, SPI1_MEM_S_CLK_EQU_SYSCLK); + } else { + uint32_t freqbits = (((freqdiv - 1) << SPI1_MEM_S_CLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI1_MEM_S_CLKCNT_H_S)) | ((freqdiv - 1) << SPI1_MEM_S_CLKCNT_L_S); + WRITE_PERI_REG(SPI1_MEM_S_CLOCK_REG, freqbits); + } } } diff --git a/components/hal/esp32p4/include/hal/spimem_flash_ll.h b/components/hal/esp32p4/include/hal/spimem_flash_ll.h index 74bd456726..d91af4839e 100644 --- a/components/hal/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32p4/include/hal/spimem_flash_ll.h @@ -627,6 +627,11 @@ static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_ // Not supported on esp32p4 } +static inline void spimem_flash_ll_set_extra_dummy(spi_mem_dev_t *dev, uint32_t extra_dummy) +{ + //for compatibility +} + /** * Get the spi flash source clock frequency. Used for calculating * the divider parameters. diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 29bbcfbf3e..096a99b443 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1011,6 +1011,14 @@ config SOC_SPI_MEM_SUPPORT_WRAP bool default y +config SOC_SPI_MEM_SUPPORT_TIMING_TUNING + bool + default y + +config SOC_MEMSPI_TIMING_TUNING_BY_DQS + bool + default y + config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/io_mux_reg.h b/components/soc/esp32p4/include/soc/io_mux_reg.h index e994c28bcd..b4bbe739c2 100644 --- a/components/soc/esp32p4/include/soc/io_mux_reg.h +++ b/components/soc/esp32p4/include/soc/io_mux_reg.h @@ -169,35 +169,6 @@ #define SPI_D7_GPIO_NUM 36 #define SPI_DQS_GPIO_NUM 37 -#define PIN_FUNC_SPI_DEBUG 4 -#define FLASH_CS_DEBUG_GPIO_NUM 49 -#define FLASH_Q_DEBUG_GPIO_NUM 50 -#define FLASH_WP_DEBUG_GPIO_NUM 51 -#define FLASH_HD_DEBUG_GPIO_NUM 52 -#define FLASH_CLK_DEBUG_GPIO_NUM 53 -#define FLASH_D_DEBUG_GPIO_NUM 54 - -#define PSRAM_D_DEBUG_GPIO_NUM 28 -#define PSRAM_Q_DEBUG_GPIO_NUM 29 -#define PSRAM_WP_DEBUG_GPIO_NUM 30 -#define PSRAM_HOLD_DEBUG_GPIO_NUM 31 -#define PSRAM_DP4_DEBUG_GPIO_NUM 32 -#define PSRAM_DP5_DEBUG_GPIO_NUM 33 -#define PSRAM_DP6_DEBUG_GPIO_NUM 34 -#define PSRAM_DP7_DEBUG_GPIO_NUM 35 -#define PSRAM_DQS0_DEBUG_GPIO_NUM 36 -#define PSRAM_CLK_DEBUG_GPIO_NUM 22 -#define PSRAM_CS_DEBUG_GPIO_NUM 23 -#define PSRAM_DP8_DEBUG_GPIO_NUM 39 -#define PSRAM_DP9_DEBUG_GPIO_NUM 40 -#define PSRAM_DP10_DEBUG_GPIO_NUM 41 -#define PSRAM_DP11_DEBUG_GPIO_NUM 42 -#define PSRAM_DP12_DEBUG_GPIO_NUM 43 -#define PSRAM_DP13_DEBUG_GPIO_NUM 44 -#define PSRAM_DP14_DEBUG_GPIO_NUM 45 -#define PSRAM_DP15_DEBUG_GPIO_NUM 46 -#define PSRAM_DQS1_DEBUG_GPIO_NUM 47 - #define SD_CLK_GPIO_NUM 43 #define SD_CMD_GPIO_NUM 44 #define SD_DATA0_GPIO_NUM 39 diff --git a/components/soc/esp32p4/include/soc/iomux_mspi_pin_reg.h b/components/soc/esp32p4/include/soc/iomux_mspi_pin_reg.h index 3f961aa6a8..9c56cc346a 100644 --- a/components/soc/esp32p4/include/soc/iomux_mspi_pin_reg.h +++ b/components/soc/esp32p4/include/soc/iomux_mspi_pin_reg.h @@ -1386,6 +1386,39 @@ extern "C" { #define IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_DELAY_270_V 0x0000000FU #define IOMUX_MSPI_PIN_REG_PSRAM_DQS_1_DELAY_270_S 17 +/** + * Usage: + * PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_CS_DEBUG_GPIO_NUM], PIN_FUNC_SPI_DEBUG); + */ +#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC) +#define PIN_FUNC_SPI_DEBUG 4 +#define FLASH_CS_DEBUG_GPIO_NUM 49 +#define FLASH_Q_DEBUG_GPIO_NUM 50 +#define FLASH_WP_DEBUG_GPIO_NUM 51 +#define FLASH_HD_DEBUG_GPIO_NUM 52 +#define FLASH_CLK_DEBUG_GPIO_NUM 53 +#define FLASH_D_DEBUG_GPIO_NUM 54 +#define PSRAM_D_DEBUG_GPIO_NUM 28 +#define PSRAM_Q_DEBUG_GPIO_NUM 29 +#define PSRAM_WP_DEBUG_GPIO_NUM 30 +#define PSRAM_HOLD_DEBUG_GPIO_NUM 31 +#define PSRAM_DP4_DEBUG_GPIO_NUM 32 +#define PSRAM_DP5_DEBUG_GPIO_NUM 33 +#define PSRAM_DP6_DEBUG_GPIO_NUM 34 +#define PSRAM_DP7_DEBUG_GPIO_NUM 35 +#define PSRAM_DQS0_DEBUG_GPIO_NUM 36 +#define PSRAM_CLK_DEBUG_GPIO_NUM 22 +#define PSRAM_CS_DEBUG_GPIO_NUM 23 +#define PSRAM_DP8_DEBUG_GPIO_NUM 39 +#define PSRAM_DP9_DEBUG_GPIO_NUM 40 +#define PSRAM_DP10_DEBUG_GPIO_NUM 41 +#define PSRAM_DP11_DEBUG_GPIO_NUM 42 +#define PSRAM_DP12_DEBUG_GPIO_NUM 43 +#define PSRAM_DP13_DEBUG_GPIO_NUM 44 +#define PSRAM_DP14_DEBUG_GPIO_NUM 45 +#define PSRAM_DP15_DEBUG_GPIO_NUM 46 +#define PSRAM_DQS1_DEBUG_GPIO_NUM 47 + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32p4/include/soc/iomux_mspi_pin_struct.h b/components/soc/esp32p4/include/soc/iomux_mspi_pin_struct.h index eb86f13252..6af9fdf782 100644 --- a/components/soc/esp32p4/include/soc/iomux_mspi_pin_struct.h +++ b/components/soc/esp32p4/include/soc/iomux_mspi_pin_struct.h @@ -219,829 +219,97 @@ typedef union { } iomux_mspi_pin_flash_d_pin0_reg_t; -/** Group: psram_d_pin */ -/** Type of psram_d_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ +/** psram_pin */ typedef union { struct { - /** reg_psram_d_dli : R/W; bitpos: [3:0]; default: 0; - * psram d dli + /** reg_psram_pin_dli : R/W; bitpos: [3:0]; default: 0; + * psram pin dli */ - uint32_t reg_psram_d_dli:4; - /** reg_psram_d_dlc : R/W; bitpos: [7:4]; default: 0; - * psram d dlc + uint32_t reg_psram_pin_dli:4; + /** reg_psram_pin_dlc : R/W; bitpos: [7:4]; default: 0; + * psram pin dlc */ - uint32_t reg_psram_d_dlc:4; - /** reg_psram_d_hys : R/W; bitpos: [8]; default: 0; - * psram d hys + uint32_t reg_psram_pin_dlc:4; + /** reg_psram_pin_hys : R/W; bitpos: [8]; default: 0; + * psram pin hys */ - uint32_t reg_psram_d_hys:1; - /** reg_psram_d_ie : R/W; bitpos: [9]; default: 0; + uint32_t reg_psram_pin_hys:1; + /** reg_psram_pin_ie : R/W; bitpos: [9]; default: 0; * Reserved */ - uint32_t reg_psram_d_ie:1; - /** reg_psram_d_wpu : R/W; bitpos: [10]; default: 0; - * psram d wpu + uint32_t reg_psram_pin_ie:1; + /** reg_psram_pin_wpu : R/W; bitpos: [10]; default: 0; + * psram pin wpu */ - uint32_t reg_psram_d_wpu:1; - /** reg_psram_d_wpd : R/W; bitpos: [11]; default: 0; - * psram d wpd + uint32_t reg_psram_pin_wpu:1; + /** reg_psram_pin_wpd : R/W; bitpos: [11]; default: 0; + * psram pin wpd */ - uint32_t reg_psram_d_wpd:1; + uint32_t reg_psram_pin_wpd:1; /** reg_psram_d_drv : R/W; bitpos: [13:12]; default: 0; - * psram d drv + * psram pin drv */ uint32_t reg_psram_d_drv:2; uint32_t reserved_14:18; }; uint32_t val; -} iomux_mspi_pin_psram_d_pin0_reg_t; +} iomux_mspi_pin_psram_pin_reg_t; - -/** Group: psram_q_pin */ -/** Type of psram_q_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ +/** psram_dqs_pin */ typedef union { struct { - /** reg_psram_q_dli : R/W; bitpos: [3:0]; default: 0; - * psram q dli + /** reg_psram_dqs_xpd : R/W; bitpos: [0]; default: 0; + * psram xpd dqs */ - uint32_t reg_psram_q_dli:4; - /** reg_psram_q_dlc : R/W; bitpos: [7:4]; default: 0; - * psram q dlc + uint32_t reg_psram_dqs_xpd:1; + /** reg_psram_dqs_phase : R/W; bitpos: [2:1]; default: 0; + * psram dqs phase */ - uint32_t reg_psram_q_dlc:4; - /** reg_psram_q_hys : R/W; bitpos: [8]; default: 0; - * psram q hys + uint32_t reg_psram_dqs_phase:2; + /** reg_psram_dqs_dli : R/W; bitpos: [6:3]; default: 0; + * psram dqs dli */ - uint32_t reg_psram_q_hys:1; - /** reg_psram_q_ie : R/W; bitpos: [9]; default: 0; + uint32_t reg_psram_dqs_dli:4; + /** reg_psram_dqs_delay_90 : R/W; bitpos: [10:7]; default: 0; + * psram dqs delay 90 + */ + uint32_t reg_psram_dqs_delay_90:4; + /** reg_psram_dqs_hys : R/W; bitpos: [11]; default: 0; + * psram dqs hys + */ + uint32_t reg_psram_dqs_hys:1; + /** reg_psram_dqs_ie : R/W; bitpos: [12]; default: 0; * Reserved */ - uint32_t reg_psram_q_ie:1; - /** reg_psram_q_wpu : R/W; bitpos: [10]; default: 0; - * psram q wpu + uint32_t reg_psram_dqs_ie:1; + /** reg_psram_dqs_wpu : R/W; bitpos: [13]; default: 0; + * psram dqs wpu */ - uint32_t reg_psram_q_wpu:1; - /** reg_psram_q_wpd : R/W; bitpos: [11]; default: 0; - * psram q wpd + uint32_t reg_psram_dqs_wpu:1; + /** reg_psram_dqs_wpd : R/W; bitpos: [14]; default: 0; + * psram dqs wpd */ - uint32_t reg_psram_q_wpd:1; - /** reg_psram_q_drv : R/W; bitpos: [13:12]; default: 0; - * psram q drv + uint32_t reg_psram_dqs_wpd:1; + /** reg_psram_dqs_drv : R/W; bitpos: [16:15]; default: 0; + * psram dqs drv */ - uint32_t reg_psram_q_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_q_pin0_reg_t; - - -/** Group: psram_wp_pin */ -/** Type of psram_wp_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_wp_dli : R/W; bitpos: [3:0]; default: 0; - * psram wp dli + uint32_t reg_psram_dqs_drv:2; + /** reg_psram_dqs_delay_270 : R/W; bitpos: [20:17]; default: 0; + * psram dqs delay 270 */ - uint32_t reg_psram_wp_dli:4; - /** reg_psram_wp_dlc : R/W; bitpos: [7:4]; default: 0; - * psram wp dlc - */ - uint32_t reg_psram_wp_dlc:4; - /** reg_psram_wp_hys : R/W; bitpos: [8]; default: 0; - * psram wp hys - */ - uint32_t reg_psram_wp_hys:1; - /** reg_psram_wp_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_wp_ie:1; - /** reg_psram_wp_wpu : R/W; bitpos: [10]; default: 0; - * psram wp wpu - */ - uint32_t reg_psram_wp_wpu:1; - /** reg_psram_wp_wpd : R/W; bitpos: [11]; default: 0; - * psram wp wpd - */ - uint32_t reg_psram_wp_wpd:1; - /** reg_psram_wp_drv : R/W; bitpos: [13:12]; default: 0; - * psram wp drv - */ - uint32_t reg_psram_wp_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_wp_pin0_reg_t; - - -/** Group: psram_hold_pin */ -/** Type of psram_hold_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_hold_dli : R/W; bitpos: [3:0]; default: 0; - * psram hold dli - */ - uint32_t reg_psram_hold_dli:4; - /** reg_psram_hold_dlc : R/W; bitpos: [7:4]; default: 0; - * psram hold dlc - */ - uint32_t reg_psram_hold_dlc:4; - /** reg_psram_hold_hys : R/W; bitpos: [8]; default: 0; - * psram hold hys - */ - uint32_t reg_psram_hold_hys:1; - /** reg_psram_hold_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_hold_ie:1; - /** reg_psram_hold_wpu : R/W; bitpos: [10]; default: 0; - * psram hold wpu - */ - uint32_t reg_psram_hold_wpu:1; - /** reg_psram_hold_wpd : R/W; bitpos: [11]; default: 0; - * psram hold wpd - */ - uint32_t reg_psram_hold_wpd:1; - /** reg_psram_hold_drv : R/W; bitpos: [13:12]; default: 0; - * psram hold drv - */ - uint32_t reg_psram_hold_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_hold_pin0_reg_t; - - -/** Group: psram_dq4_pin */ -/** Type of psram_dq4_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq4_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq4 dli - */ - uint32_t reg_psram_dq4_dli:4; - /** reg_psram_dq4_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq4 dlc - */ - uint32_t reg_psram_dq4_dlc:4; - /** reg_psram_dq4_hys : R/W; bitpos: [8]; default: 0; - * psram dq4 hys - */ - uint32_t reg_psram_dq4_hys:1; - /** reg_psram_dq4_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq4_ie:1; - /** reg_psram_dq4_wpu : R/W; bitpos: [10]; default: 0; - * psram dq4 wpu - */ - uint32_t reg_psram_dq4_wpu:1; - /** reg_psram_dq4_wpd : R/W; bitpos: [11]; default: 0; - * psram dq4 wpd - */ - uint32_t reg_psram_dq4_wpd:1; - /** reg_psram_dq4_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq4 drv - */ - uint32_t reg_psram_dq4_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq4_pin0_reg_t; - - -/** Group: psram_dq5_pin */ -/** Type of psram_dq5_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq5_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq5 dli - */ - uint32_t reg_psram_dq5_dli:4; - /** reg_psram_dq5_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq5 dlc - */ - uint32_t reg_psram_dq5_dlc:4; - /** reg_psram_dq5_hys : R/W; bitpos: [8]; default: 0; - * psram dq5 hys - */ - uint32_t reg_psram_dq5_hys:1; - /** reg_psram_dq5_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq5_ie:1; - /** reg_psram_dq5_wpu : R/W; bitpos: [10]; default: 0; - * psram dq5 wpu - */ - uint32_t reg_psram_dq5_wpu:1; - /** reg_psram_dq5_wpd : R/W; bitpos: [11]; default: 0; - * psram dq5 wpd - */ - uint32_t reg_psram_dq5_wpd:1; - /** reg_psram_dq5_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq5 drv - */ - uint32_t reg_psram_dq5_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq5_pin0_reg_t; - - -/** Group: psram_dq6_pin */ -/** Type of psram_dq6_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq6_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq6 dli - */ - uint32_t reg_psram_dq6_dli:4; - /** reg_psram_dq6_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq6 dlc - */ - uint32_t reg_psram_dq6_dlc:4; - /** reg_psram_dq6_hys : R/W; bitpos: [8]; default: 0; - * psram dq6 hys - */ - uint32_t reg_psram_dq6_hys:1; - /** reg_psram_dq6_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq6_ie:1; - /** reg_psram_dq6_wpu : R/W; bitpos: [10]; default: 0; - * psram dq6 wpu - */ - uint32_t reg_psram_dq6_wpu:1; - /** reg_psram_dq6_wpd : R/W; bitpos: [11]; default: 0; - * psram dq6 wpd - */ - uint32_t reg_psram_dq6_wpd:1; - /** reg_psram_dq6_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq6 drv - */ - uint32_t reg_psram_dq6_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq6_pin0_reg_t; - - -/** Group: psram_dq7_pin */ -/** Type of psram_dq7_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq7_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq7 dli - */ - uint32_t reg_psram_dq7_dli:4; - /** reg_psram_dq7_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq7 dlc - */ - uint32_t reg_psram_dq7_dlc:4; - /** reg_psram_dq7_hys : R/W; bitpos: [8]; default: 0; - * psram dq7 hys - */ - uint32_t reg_psram_dq7_hys:1; - /** reg_psram_dq7_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq7_ie:1; - /** reg_psram_dq7_wpu : R/W; bitpos: [10]; default: 0; - * psram dq7 wpu - */ - uint32_t reg_psram_dq7_wpu:1; - /** reg_psram_dq7_wpd : R/W; bitpos: [11]; default: 0; - * psram dq7 wpd - */ - uint32_t reg_psram_dq7_wpd:1; - /** reg_psram_dq7_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq7 drv - */ - uint32_t reg_psram_dq7_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq7_pin0_reg_t; - - -/** Group: psram_dqs_0_pin */ -/** Type of psram_dqs_0_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dqs_0_xpd : R/W; bitpos: [0]; default: 0; - * psram xpd dqs0 - */ - uint32_t reg_psram_dqs_0_xpd:1; - /** reg_psram_dqs_0_phase : R/W; bitpos: [2:1]; default: 0; - * psram dqs0 phase - */ - uint32_t reg_psram_dqs_0_phase:2; - /** reg_psram_dqs_0_dli : R/W; bitpos: [6:3]; default: 0; - * psram dqs0 dli - */ - uint32_t reg_psram_dqs_0_dli:4; - /** reg_psram_dqs_0_delay_90 : R/W; bitpos: [10:7]; default: 0; - * psram dqs0 delay 90 - */ - uint32_t reg_psram_dqs_0_delay_90:4; - /** reg_psram_dqs_0_hys : R/W; bitpos: [11]; default: 0; - * psram dqs0 hys - */ - uint32_t reg_psram_dqs_0_hys:1; - /** reg_psram_dqs_0_ie : R/W; bitpos: [12]; default: 0; - * Reserved - */ - uint32_t reg_psram_dqs_0_ie:1; - /** reg_psram_dqs_0_wpu : R/W; bitpos: [13]; default: 0; - * psram dqs0 wpu - */ - uint32_t reg_psram_dqs_0_wpu:1; - /** reg_psram_dqs_0_wpd : R/W; bitpos: [14]; default: 0; - * psram dqs0 wpd - */ - uint32_t reg_psram_dqs_0_wpd:1; - /** reg_psram_dqs_0_drv : R/W; bitpos: [16:15]; default: 0; - * psram dqs0 drv - */ - uint32_t reg_psram_dqs_0_drv:2; - /** reg_psram_dqs_0_delay_270 : R/W; bitpos: [20:17]; default: 0; - * psram dqs0 delay 270 - */ - uint32_t reg_psram_dqs_0_delay_270:4; + uint32_t reg_psram_dqs_delay_270:4; uint32_t reserved_21:11; }; uint32_t val; -} iomux_mspi_pin_psram_dqs_0_pin0_reg_t; - - -/** Group: psram_ck_pin */ -/** Type of psram_ck_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_ck_dli : R/W; bitpos: [3:0]; default: 0; - * psram ck dli - */ - uint32_t reg_psram_ck_dli:4; - /** reg_psram_ck_dlc : R/W; bitpos: [7:4]; default: 0; - * psram ck dlc - */ - uint32_t reg_psram_ck_dlc:4; - /** reg_psram_ck_hys : R/W; bitpos: [8]; default: 0; - * psram ck hys - */ - uint32_t reg_psram_ck_hys:1; - /** reg_psram_ck_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_ck_ie:1; - /** reg_psram_ck_wpu : R/W; bitpos: [10]; default: 0; - * psram ck wpu - */ - uint32_t reg_psram_ck_wpu:1; - /** reg_psram_ck_wpd : R/W; bitpos: [11]; default: 0; - * psram ck wpd - */ - uint32_t reg_psram_ck_wpd:1; - /** reg_psram_ck_drv : R/W; bitpos: [13:12]; default: 0; - * psram ck drv - */ - uint32_t reg_psram_ck_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_ck_pin0_reg_t; - - -/** Group: psram_cs_pin */ -/** Type of psram_cs_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_cs_dli : R/W; bitpos: [3:0]; default: 0; - * psram cs dli - */ - uint32_t reg_psram_cs_dli:4; - /** reg_psram_cs_dlc : R/W; bitpos: [7:4]; default: 0; - * psram cs dlc - */ - uint32_t reg_psram_cs_dlc:4; - /** reg_psram_cs_hys : R/W; bitpos: [8]; default: 0; - * psram cs hys - */ - uint32_t reg_psram_cs_hys:1; - /** reg_psram_cs_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_cs_ie:1; - /** reg_psram_cs_wpu : R/W; bitpos: [10]; default: 0; - * psram cs wpu - */ - uint32_t reg_psram_cs_wpu:1; - /** reg_psram_cs_wpd : R/W; bitpos: [11]; default: 0; - * psram cs wpd - */ - uint32_t reg_psram_cs_wpd:1; - /** reg_psram_cs_drv : R/W; bitpos: [13:12]; default: 0; - * psram cs drv - */ - uint32_t reg_psram_cs_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_cs_pin0_reg_t; - - -/** Group: psram_dq8_pin */ -/** Type of psram_dq8_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq8_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq8 dli - */ - uint32_t reg_psram_dq8_dli:4; - /** reg_psram_dq8_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq8 dlc - */ - uint32_t reg_psram_dq8_dlc:4; - /** reg_psram_dq8_hys : R/W; bitpos: [8]; default: 0; - * psram dq8 hys - */ - uint32_t reg_psram_dq8_hys:1; - /** reg_psram_dq8_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq8_ie:1; - /** reg_psram_dq8_wpu : R/W; bitpos: [10]; default: 0; - * psram dq8 wpu - */ - uint32_t reg_psram_dq8_wpu:1; - /** reg_psram_dq8_wpd : R/W; bitpos: [11]; default: 0; - * psram dq8 wpd - */ - uint32_t reg_psram_dq8_wpd:1; - /** reg_psram_dq8_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq8 drv - */ - uint32_t reg_psram_dq8_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq8_pin0_reg_t; - - -/** Group: psram_dq9_pin */ -/** Type of psram_dq9_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq9_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq9 dli - */ - uint32_t reg_psram_dq9_dli:4; - /** reg_psram_dq9_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq9 dlc - */ - uint32_t reg_psram_dq9_dlc:4; - /** reg_psram_dq9_hys : R/W; bitpos: [8]; default: 0; - * psram dq9 hys - */ - uint32_t reg_psram_dq9_hys:1; - /** reg_psram_dq9_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq9_ie:1; - /** reg_psram_dq9_wpu : R/W; bitpos: [10]; default: 0; - * psram dq9 wpu - */ - uint32_t reg_psram_dq9_wpu:1; - /** reg_psram_dq9_wpd : R/W; bitpos: [11]; default: 0; - * psram dq9 wpd - */ - uint32_t reg_psram_dq9_wpd:1; - /** reg_psram_dq9_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq9 drv - */ - uint32_t reg_psram_dq9_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq9_pin0_reg_t; - - -/** Group: psram_dq10_pin */ -/** Type of psram_dq10_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq10_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq10 dli - */ - uint32_t reg_psram_dq10_dli:4; - /** reg_psram_dq10_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq10 dlc - */ - uint32_t reg_psram_dq10_dlc:4; - /** reg_psram_dq10_hys : R/W; bitpos: [8]; default: 0; - * psram dq10 hys - */ - uint32_t reg_psram_dq10_hys:1; - /** reg_psram_dq10_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq10_ie:1; - /** reg_psram_dq10_wpu : R/W; bitpos: [10]; default: 0; - * psram dq10 wpu - */ - uint32_t reg_psram_dq10_wpu:1; - /** reg_psram_dq10_wpd : R/W; bitpos: [11]; default: 0; - * psram dq10 wpd - */ - uint32_t reg_psram_dq10_wpd:1; - /** reg_psram_dq10_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq10 drv - */ - uint32_t reg_psram_dq10_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq10_pin0_reg_t; - - -/** Group: psram_dq11_pin */ -/** Type of psram_dq11_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq11_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq11 dli - */ - uint32_t reg_psram_dq11_dli:4; - /** reg_psram_dq11_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq11 dlc - */ - uint32_t reg_psram_dq11_dlc:4; - /** reg_psram_dq11_hys : R/W; bitpos: [8]; default: 0; - * psram dq11 hys - */ - uint32_t reg_psram_dq11_hys:1; - /** reg_psram_dq11_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq11_ie:1; - /** reg_psram_dq11_wpu : R/W; bitpos: [10]; default: 0; - * psram dq11 wpu - */ - uint32_t reg_psram_dq11_wpu:1; - /** reg_psram_dq11_wpd : R/W; bitpos: [11]; default: 0; - * psram dq11 wpd - */ - uint32_t reg_psram_dq11_wpd:1; - /** reg_psram_dq11_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq11 drv - */ - uint32_t reg_psram_dq11_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq11_pin0_reg_t; - - -/** Group: psram_dq12_pin */ -/** Type of psram_dq12_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq12_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq12 dli - */ - uint32_t reg_psram_dq12_dli:4; - /** reg_psram_dq12_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq12 dlc - */ - uint32_t reg_psram_dq12_dlc:4; - /** reg_psram_dq12_hys : R/W; bitpos: [8]; default: 0; - * psram dq12 hys - */ - uint32_t reg_psram_dq12_hys:1; - /** reg_psram_dq12_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq12_ie:1; - /** reg_psram_dq12_wpu : R/W; bitpos: [10]; default: 0; - * psram dq12 wpu - */ - uint32_t reg_psram_dq12_wpu:1; - /** reg_psram_dq12_wpd : R/W; bitpos: [11]; default: 0; - * psram dq12 wpd - */ - uint32_t reg_psram_dq12_wpd:1; - /** reg_psram_dq12_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq12 drv - */ - uint32_t reg_psram_dq12_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq12_pin0_reg_t; - - -/** Group: psram_dq13_pin */ -/** Type of psram_dq13_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq13_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq13 dli - */ - uint32_t reg_psram_dq13_dli:4; - /** reg_psram_dq13_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq13 dlc - */ - uint32_t reg_psram_dq13_dlc:4; - /** reg_psram_dq13_hys : R/W; bitpos: [8]; default: 0; - * psram dq13 hys - */ - uint32_t reg_psram_dq13_hys:1; - /** reg_psram_dq13_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq13_ie:1; - /** reg_psram_dq13_wpu : R/W; bitpos: [10]; default: 0; - * psram dq13 wpu - */ - uint32_t reg_psram_dq13_wpu:1; - /** reg_psram_dq13_wpd : R/W; bitpos: [11]; default: 0; - * psram dq13 wpd - */ - uint32_t reg_psram_dq13_wpd:1; - /** reg_psram_dq13_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq13 drv - */ - uint32_t reg_psram_dq13_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq13_pin0_reg_t; - - -/** Group: psram_dq14_pin */ -/** Type of psram_dq14_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq14_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq14 dli - */ - uint32_t reg_psram_dq14_dli:4; - /** reg_psram_dq14_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq14 dlc - */ - uint32_t reg_psram_dq14_dlc:4; - /** reg_psram_dq14_hys : R/W; bitpos: [8]; default: 0; - * psram dq14 hys - */ - uint32_t reg_psram_dq14_hys:1; - /** reg_psram_dq14_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq14_ie:1; - /** reg_psram_dq14_wpu : R/W; bitpos: [10]; default: 0; - * psram dq14 wpu - */ - uint32_t reg_psram_dq14_wpu:1; - /** reg_psram_dq14_wpd : R/W; bitpos: [11]; default: 0; - * psram dq14 wpd - */ - uint32_t reg_psram_dq14_wpd:1; - /** reg_psram_dq14_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq14 drv - */ - uint32_t reg_psram_dq14_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq14_pin0_reg_t; - - -/** Group: psram_dq15_pin */ -/** Type of psram_dq15_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dq15_dli : R/W; bitpos: [3:0]; default: 0; - * psram dq15 dli - */ - uint32_t reg_psram_dq15_dli:4; - /** reg_psram_dq15_dlc : R/W; bitpos: [7:4]; default: 0; - * psram dq15 dlc - */ - uint32_t reg_psram_dq15_dlc:4; - /** reg_psram_dq15_hys : R/W; bitpos: [8]; default: 0; - * psram dq15 hys - */ - uint32_t reg_psram_dq15_hys:1; - /** reg_psram_dq15_ie : R/W; bitpos: [9]; default: 0; - * Reserved - */ - uint32_t reg_psram_dq15_ie:1; - /** reg_psram_dq15_wpu : R/W; bitpos: [10]; default: 0; - * psram dq15 wpu - */ - uint32_t reg_psram_dq15_wpu:1; - /** reg_psram_dq15_wpd : R/W; bitpos: [11]; default: 0; - * psram dq15 wpd - */ - uint32_t reg_psram_dq15_wpd:1; - /** reg_psram_dq15_drv : R/W; bitpos: [13:12]; default: 0; - * psram dq15 drv - */ - uint32_t reg_psram_dq15_drv:2; - uint32_t reserved_14:18; - }; - uint32_t val; -} iomux_mspi_pin_psram_dq15_pin0_reg_t; - - -/** Group: psram_dqs_1_pin */ -/** Type of psram_dqs_1_pin0 register - * IOMUX_MSPI_PIN_PSRAM_D_PIN0_REG - */ -typedef union { - struct { - /** reg_psram_dqs_1_xpd : R/W; bitpos: [0]; default: 0; - * psram xpd dqs1 - */ - uint32_t reg_psram_dqs_1_xpd:1; - /** reg_psram_dqs_1_phase : R/W; bitpos: [2:1]; default: 0; - * psram dqs1 phase - */ - uint32_t reg_psram_dqs_1_phase:2; - /** reg_psram_dqs_1_dli : R/W; bitpos: [6:3]; default: 0; - * psram dqs1 dli - */ - uint32_t reg_psram_dqs_1_dli:4; - /** reg_psram_dqs_1_delay_90 : R/W; bitpos: [10:7]; default: 0; - * psram dqs1 delay 90 - */ - uint32_t reg_psram_dqs_1_delay_90:4; - /** reg_psram_dqs_1_hys : R/W; bitpos: [11]; default: 0; - * psram dqs1 hys - */ - uint32_t reg_psram_dqs_1_hys:1; - /** reg_psram_dqs_1_ie : R/W; bitpos: [12]; default: 0; - * Reserved - */ - uint32_t reg_psram_dqs_1_ie:1; - /** reg_psram_dqs_1_wpu : R/W; bitpos: [13]; default: 0; - * psram dqs1 wpu - */ - uint32_t reg_psram_dqs_1_wpu:1; - /** reg_psram_dqs_1_wpd : R/W; bitpos: [14]; default: 0; - * psram dqs1 wpd - */ - uint32_t reg_psram_dqs_1_wpd:1; - /** reg_psram_dqs_1_drv : R/W; bitpos: [16:15]; default: 0; - * psram dqs1 drv - */ - uint32_t reg_psram_dqs_1_drv:2; - /** reg_psram_dqs_1_delay_270 : R/W; bitpos: [20:17]; default: 0; - * psram dqs1 delay 270 - */ - uint32_t reg_psram_dqs_1_delay_270:4; - uint32_t reserved_21:11; - }; - uint32_t val; -} iomux_mspi_pin_psram_dqs_1_pin0_reg_t; +} iomux_mspi_pin_psram_dqs_pin_reg_t; +/** psram_pin group */ +typedef struct { + volatile iomux_mspi_pin_psram_pin_reg_t pin_group0[8]; //for d, q, wp, hold, dq4, dq5, dq6, dq7 + volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs0; + volatile iomux_mspi_pin_psram_pin_reg_t pin_group1[10]; //for ck, cs, dq8, dq9, dq10, dq11, dq12, dq13, dq14, dq15 + volatile iomux_mspi_pin_psram_dqs_pin_reg_t dqs1; +} iomux_mspi_pin_psram_pin_grp_reg_t; typedef struct { volatile iomux_mspi_pin_clk_en0_reg_t clk_en0; @@ -1051,28 +319,10 @@ typedef struct { volatile iomux_mspi_pin_flash_hold_pin0_reg_t flash_hold_pin0; volatile iomux_mspi_pin_flash_ck_pin0_reg_t flash_ck_pin0; volatile iomux_mspi_pin_flash_d_pin0_reg_t flash_d_pin0; - volatile iomux_mspi_pin_psram_d_pin0_reg_t psram_d_pin0; - volatile iomux_mspi_pin_psram_q_pin0_reg_t psram_q_pin0; - volatile iomux_mspi_pin_psram_wp_pin0_reg_t psram_wp_pin0; - volatile iomux_mspi_pin_psram_hold_pin0_reg_t psram_hold_pin0; - volatile iomux_mspi_pin_psram_dq4_pin0_reg_t psram_dq4_pin0; - volatile iomux_mspi_pin_psram_dq5_pin0_reg_t psram_dq5_pin0; - volatile iomux_mspi_pin_psram_dq6_pin0_reg_t psram_dq6_pin0; - volatile iomux_mspi_pin_psram_dq7_pin0_reg_t psram_dq7_pin0; - volatile iomux_mspi_pin_psram_dqs_0_pin0_reg_t psram_dqs_0_pin0; - volatile iomux_mspi_pin_psram_ck_pin0_reg_t psram_ck_pin0; - volatile iomux_mspi_pin_psram_cs_pin0_reg_t psram_cs_pin0; - volatile iomux_mspi_pin_psram_dq8_pin0_reg_t psram_dq8_pin0; - volatile iomux_mspi_pin_psram_dq9_pin0_reg_t psram_dq9_pin0; - volatile iomux_mspi_pin_psram_dq10_pin0_reg_t psram_dq10_pin0; - volatile iomux_mspi_pin_psram_dq11_pin0_reg_t psram_dq11_pin0; - volatile iomux_mspi_pin_psram_dq12_pin0_reg_t psram_dq12_pin0; - volatile iomux_mspi_pin_psram_dq13_pin0_reg_t psram_dq13_pin0; - volatile iomux_mspi_pin_psram_dq14_pin0_reg_t psram_dq14_pin0; - volatile iomux_mspi_pin_psram_dq15_pin0_reg_t psram_dq15_pin0; - volatile iomux_mspi_pin_psram_dqs_1_pin0_reg_t psram_dqs_1_pin0; + volatile iomux_mspi_pin_psram_pin_grp_reg_t psram_pin_group; } iomux_mspi_pin_dev_t; +extern iomux_mspi_pin_dev_t MSPI_IOMUX; #ifndef __cplusplus _Static_assert(sizeof(iomux_mspi_pin_dev_t) == 0x6c, "Invalid size of iomux_mspi_pin_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/reg_base.h b/components/soc/esp32p4/include/soc/reg_base.h index 350906bcde..d52ef64d53 100644 --- a/components/soc/esp32p4/include/soc/reg_base.h +++ b/components/soc/esp32p4/include/soc/reg_base.h @@ -108,6 +108,7 @@ #define DR_REG_GPIO_BASE (DR_REG_HPPERIPH1_BASE + 0x20000) #define DR_REG_GPIO_EXT_BASE (DR_REG_HPPERIPH1_BASE + 0x20F00) #define DR_REG_IO_MUX_BASE (DR_REG_HPPERIPH1_BASE + 0x21000) +#define DR_REG_IOMUX_MSPI_PIN_BASE (DR_REG_HPPERIPH1_BASE + 0x21200) #define DR_REG_SYSTIMER_BASE (DR_REG_HPPERIPH1_BASE + 0x22000) #define DR_REG_MEM_MON_BASE (DR_REG_HPPERIPH1_BASE + 0x23000) #define DR_REG_AUDIO_ADDC_BASE (DR_REG_HPPERIPH1_BASE + 0x24000) diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 03bdc5d309..c181db4153 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -444,6 +444,8 @@ #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_MEMSPI_TIMING_TUNING_BY_DQS (1) #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 diff --git a/components/soc/esp32p4/include/soc/spi1_mem_s_struct.h b/components/soc/esp32p4/include/soc/spi1_mem_s_struct.h index 80ba6092c4..c2bb46eb9d 100644 --- a/components/soc/esp32p4/include/soc/spi1_mem_s_struct.h +++ b/components/soc/esp32p4/include/soc/spi1_mem_s_struct.h @@ -1259,6 +1259,7 @@ typedef struct spi1_mem_s_dev_s { volatile spi1_mem_s_date_reg_t date; } spi1_mem_s_dev_t; +extern spi1_mem_s_dev_t SPIMEM3; #ifndef __cplusplus _Static_assert(sizeof(spi1_mem_s_dev_t) == 0x400, "Invalid size of spi1_mem_s_dev_t structure"); diff --git a/components/soc/esp32p4/ld/esp32p4.peripherals.ld b/components/soc/esp32p4/ld/esp32p4.peripherals.ld index 7f5ea313c9..6314d78c2d 100644 --- a/components/soc/esp32p4/ld/esp32p4.peripherals.ld +++ b/components/soc/esp32p4/ld/esp32p4.peripherals.ld @@ -59,6 +59,7 @@ PROVIDE ( SDM = 0x500E0F00 ); PROVIDE ( GLITCH_FILTER = 0x500E0F30 ); PROVIDE ( GPIO_ETM = 0x500E0F60 ); PROVIDE ( IOMUX = 0x500E1000 ); +PROVIDE ( MSPI_IOMUX = 0x500E1200 ); PROVIDE ( HP_SYSTEM = 0x500E5000 ); PROVIDE ( HP_SYS_CLKRST = 0x500E6000 );