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 cbf79906906..5e586823a3a 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_hex.c +++ b/components/esp_psram/device/esp_psram_impl_ap_hex.c @@ -9,9 +9,11 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_ldo.h" #include "../esp_psram_impl.h" #include "rom/opi_flash.h" #include "hal/psram_ctrlr_ll.h" +#include "hal/ldo_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() @@ -122,7 +124,7 @@ static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_co hex_psram_mode_reg_t mode_reg = {0}; int data_bit_len = 16; - //read + //read MR0 and MR1 s_psram_common_transaction(spi_num, AP_HEX_PSRAM_REG_READ, cmd_len, addr, addr_bit_len, @@ -131,12 +133,24 @@ static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_co &mode_reg.mr0.val, data_bit_len, false); + addr = 0x4; + //read MR4 and MR8 + s_psram_common_transaction(spi_num, + AP_HEX_PSRAM_REG_READ, cmd_len, + addr, addr_bit_len, + dummy, + NULL, 0, + &mode_reg.mr4.val, data_bit_len, + false); + //modify mode_reg.mr0.lt = mode_reg_config->mr0.lt; mode_reg.mr0.read_latency = mode_reg_config->mr0.read_latency; mode_reg.mr0.drive_str = mode_reg_config->mr0.drive_str; + mode_reg.mr4.wr_latency = mode_reg_config->mr4.wr_latency; //write + addr = 0x0; s_psram_common_transaction(spi_num, AP_HEX_PSRAM_REG_WRITE, cmd_len, addr, addr_bit_len, @@ -145,6 +159,16 @@ static void s_init_psram_mode_reg(int spi_num, hex_psram_mode_reg_t *mode_reg_co NULL, 0, false); + addr = 0x4; + //write + s_psram_common_transaction(spi_num, + AP_HEX_PSRAM_REG_WRITE, cmd_len, + addr, addr_bit_len, + 0, + &mode_reg.mr4.val, 16, + NULL, 0, + false); + addr = 0x8; data_bit_len = 8; //read @@ -241,11 +265,13 @@ 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_BURST_WRITE); + 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_BURST_READ); + psram_ctrlr_ll_set_rd_cmd(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_RD_CMD_BITLEN, AP_HEX_PSRAM_SYNC_READ); //Config ADDR phase psram_ctrlr_ll_set_addr_bitlen(PSRAM_CTRLR_LL_MSPI_ID_2, AP_HEX_PSRAM_ADDR_BITLEN); @@ -324,10 +350,25 @@ static void s_configure_psram_ecc(void) esp_err_t esp_psram_impl_enable(void) { +#if CONFIG_SPIRAM_LDO_ID + if (CONFIG_SPIRAM_LDO_ID != -1) { + esp_ldo_unit_init_cfg_t unit_cfg = { + .unit_id = LDO_ID2UNIT(CONFIG_SPIRAM_LDO_ID), + .cfg = { + .voltage_mv = CONFIG_SPIRAM_LDO_VOLTAGE_MV, + }, + .flags.enable_unit = true, + }; + esp_ldo_unit_handle_t early_unit = esp_ldo_init_unit_early(&unit_cfg); + assert(early_unit); + } +#endif + 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); } s_set_psram_cs_timing(); @@ -336,13 +377,16 @@ esp_err_t esp_psram_impl_enable(void) #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_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_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); static hex_psram_mode_reg_t mode_reg = {}; mode_reg.mr0.lt = 1; mode_reg.mr0.read_latency = 2; mode_reg.mr0.drive_str = 0; + mode_reg.mr4.wr_latency = 2; mode_reg.mr8.bl = 3; mode_reg.mr8.bt = 0; mode_reg.mr8.rbx = 1; diff --git a/components/esp_psram/esp32p4/Kconfig.spiram b/components/esp_psram/esp32p4/Kconfig.spiram index dd25eee8692..958d5be9c8a 100644 --- a/components/esp_psram/esp32p4/Kconfig.spiram +++ b/components/esp_psram/esp32p4/Kconfig.spiram @@ -46,6 +46,31 @@ menu "PSRAM config" If enabled, 1/8 of the PSRAM total size will be reserved for error-correcting code. + config SPIRAM_LDO_ID + int "PSRAM connected LDO ID, set -1 for using external power supply" + default 2 + range -1 4 + help + PSRAM VDD needs to be connected to an voltage output. This option selects the on-chip + LDO which is connected to the PSRAM VDD. + Set to -1 for connecting to external voltage output. + + choice SPIRAM_LDO_VOLTAGE_MV + prompt "PSRAM connected LDO voltage" + depends on SPIRAM_LDO_ID != -1 + default SPIRAM_LDO_VOLTAGE_MV_1800 + help + Select the speed for the PSRAM chip. + + config SPIRAM_LDO_VOLTAGE_MV_1800 + bool "1.8V" + endchoice + + config SPIRAM_LDO_VOLTAGE_MV + int + default 1800 if SPIRAM_LDO_VOLTAGE_MV_1800 + + config SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY bool "Allow external memory as an argument to xTaskCreateStatic" default y diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index 7eaac60d51e..80337edcbfd 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -21,10 +21,6 @@ extern "C" { static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) { switch (periph) { - case PERIPH_MSPI_FLASH_MODULE: - return HP_SYS_CLKRST_REG_FLASH_CORE_CLK_EN; - case PERIPH_MSPI_PSRAM_MODULE: - return HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN; case PERIPH_EMAC_MODULE: return LP_CLKRST_HP_PAD_EMAC_TXRX_CLK_EN | LP_CLKRST_HP_PAD_EMAC_RX_CLK_EN | LP_CLKRST_HP_PAD_EMAC_TX_CLK_EN; case PERIPH_MIPI_DSI_MODULE: @@ -67,10 +63,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en switch (periph) { case PERIPH_PVT_MODULE: return HP_SYS_CLKRST_REG_RST_EN_PVT_TOP; - case PERIPH_MSPI_FLASH_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI; - case PERIPH_MSPI_PSRAM_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI; case PERIPH_MIPI_DSI_MODULE: return HP_SYS_CLKRST_REG_RST_EN_DSI_BRG; case PERIPH_MIPI_CSI_MODULE: @@ -132,9 +124,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) { switch (periph) { - case PERIPH_MSPI_FLASH_MODULE: - case PERIPH_MSPI_PSRAM_MODULE: - return HP_SYS_CLKRST_PERI_CLK_CTRL00_REG; case PERIPH_MIPI_DSI_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL03_REG; case PERIPH_I3C_MODULE: @@ -164,8 +153,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) { switch (periph) { case PERIPH_PVT_MODULE: - case PERIPH_MSPI_FLASH_MODULE: - case PERIPH_MSPI_PSRAM_MODULE: case PERIPH_ISP_MODULE: case PERIPH_DMA2D_MODULE: return HP_SYS_CLKRST_HP_RST_EN0_REG; diff --git a/components/hal/esp32p4/include/hal/ldo_ll.h b/components/hal/esp32p4/include/hal/ldo_ll.h index db525a160ce..e3d2ce4bd0c 100644 --- a/components/hal/esp32p4/include/hal/ldo_ll.h +++ b/components/hal/esp32p4/include/hal/ldo_ll.h @@ -35,8 +35,8 @@ extern "C" { #define LDO_LL_EXT_LDO_DREF_VOL_H_STEP 100 #define LDO_LL_EXT_LDO_DREF_VOL_L_BASE 500 #define LDO_LL_EXT_LDO_DREF_VOL_L_STEP 50 -#define LDO_LL_EXT_LDO_MUL_VOL_BASE 1000 -#define LDO_LL_EXT_LDO_MUL_VOL_STEP 250 +#define LDO_LL_EXT_LDO_MUL_VOL_BASE 1000 +#define LDO_LL_EXT_LDO_MUL_VOL_STEP 250 /** * Trick to be adapted to the LDO register structure @@ -47,7 +47,12 @@ extern "C" { * - ext_ldo[1] is LDO3 * - ext_ldo[4] is LDO4 */ -#define LDO_ID2INDEX(id) (uint8_t[]){0,3,1,4}[id] +#define LDO_ID2INDEX(id) (uint8_t[]){0,3,1,4}[id] + +/** + * LDO ID to real unit ID + */ +#define LDO_ID2UNIT(ldo_id) ((ldo_id) - 1) /** * @brief Enable a LDO diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index b851cdb7f7e..1b6c6dcf00a 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -24,7 +24,16 @@ Hardware .. note:: - Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on bootup, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. + .. only:: esp32 or esp32s2 or esp32s3 + + Some PSRAM chips are 1.8 V devices and some are 3.3 V. The working voltage of the PSRAM chip must match the working voltage of the flash component. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. For a 1.8 V PSRAM chip, make sure to either set the MTDI pin to a high signal level on bootup, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip. + + .. only:: esp32p4 + + Some PSRAM chips are 1.8 V devices and some are 3.3 V. Consult the datasheet for your PSRAM chip and {IDF_TARGET_NAME} device to find out the working voltages. + + By default PSRAM is powered up by the on-chip LDO2, you can use :ref:`CONFIG_SPIRAM_LDO_ID` to switch the LDO ID according. Setting this value to -1 for using external power supply. + By default PSRAM connected LDO is set to correct voltage according to the used Espressif module. You can still use :ref:`CONFIG_SPIRAM_LDO_VOLTAGE_MV` to select LDO output voltage if you do not use an Espressif module. When using external power supply, this option does not exist. .. note::