feat(esp_psram): Add a new API to just detect and enable the PSRAM

- esp_psram_chip_init() just detects and does basic initialisations of PSRAM
- esp_psram_init() initialises and maps/loads the PSRAM pages
This commit is contained in:
harshal.patil
2025-02-20 16:16:43 +05:30
parent 211074d702
commit 46225a4026
7 changed files with 67 additions and 33 deletions

View File

@@ -2,18 +2,29 @@
#
# sourced into the "SPIRAM config" submenu for a specific chip.
config SPIRAM_BOOT_INIT
bool "Initialize SPI RAM during startup"
default "y"
config SPIRAM_BOOT_HW_INIT
bool "Initialise the PSRAM related hardware"
depends on SPIRAM
default "y" if SPIRAM
help
If this is enabled, the SPI RAM will be enabled during initial boot. Unless you
If this is enabled, the PSRAM hardware will be initialized during startup.
Enabling this config does not ensure make sure the availability of the PSRAM for usage,
but just initialises the PSRAM hardware.
This is necessary to configure PSRAM memory protection during the boot up.
config SPIRAM_BOOT_INIT
bool "Initialize PSRAM during startup, including the hardware and memory related configurations"
default "y"
depends on SPIRAM_BOOT_HW_INIT
help
If this is enabled, the PSRAM will be enabled during initial boot. Unless you
have specific requirements, you'll want to leave this enabled so memory allocated
during boot-up can also be placed in SPI RAM.
during boot-up can also be placed in PSRAM.
config SPIRAM_IGNORE_NOTFOUND
bool "Ignore PSRAM when not found"
default "n"
depends on SPIRAM_BOOT_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && !SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
depends on SPIRAM_BOOT_HW_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && !SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY
help
Normally, if psram initialization is enabled during compile time but not found at runtime, it
is seen as an error making the CPU panic. If this is enabled, booting will complete

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -60,6 +60,17 @@ bool esp_psram_extram_test(void);
*/
void esp_psram_bss_init(void);
/**
* @brief Initialize the PSRAM hardware.
* Just initialize the PSRAM hardware, does not load the XIP segments or map the PSRAM memory
*
* @return
* - ESP_OK: On success
* - ESP_FAIL: PSRAM isn't initialized successfully, potential reason would be: wrong VDDSDIO, invalid chip ID, etc.
* - ESP_ERR_INVALID_STATE: PSRAM is initialized already
*/
esp_err_t esp_psram_chip_init(void);
#if CONFIG_IDF_TARGET_ESP32
/**
* @brief Force a writeback of the data in the PSRAM cache. This is to be called whenever

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,6 +17,7 @@ extern "C" {
/**
* @brief Initialize PSRAM interface/hardware.
* Initializes the PSRAM hardware and load the XIP segments or maps the PSRAM memory
*
* @return
* - ESP_OK: On success

View File

@@ -20,6 +20,7 @@ entries:
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
esp_psram_impl_ap_hex (noflash)
mmu_psram_flash_v2 (noflash)
esp_psram: esp_psram_chip_init (noflash)
esp_psram: esp_psram_init (noflash)
esp_psram: s_psram_chip_init (noflash)
esp_psram: s_xip_psram_placement (noflash)

View File

@@ -78,7 +78,8 @@ typedef struct {
} psram_mem_t;
typedef struct {
bool is_initialised;
bool is_chip_initialised; // if psram hardware is initialised or not
bool is_initialised; // if psram initialised with memory mapping or not and is ready to use
/**
* @note 1
* As we can't use heap allocator during this stage, we need to statically declare these regions.
@@ -138,9 +139,9 @@ static void IRAM_ATTR s_mapping(int v_start, int size)
}
#endif //CONFIG_IDF_TARGET_ESP32
static esp_err_t s_psram_chip_init(uint32_t *out_available_size)
static esp_err_t s_psram_chip_init(void)
{
if (s_psram_ctx.is_initialised) {
if (s_psram_ctx.is_chip_initialised) {
return ESP_ERR_INVALID_STATE;
}
@@ -152,7 +153,7 @@ static esp_err_t s_psram_chip_init(uint32_t *out_available_size)
#endif
return ret;
}
s_psram_ctx.is_initialised = true;
s_psram_ctx.is_chip_initialised = true;
uint32_t psram_physical_size = 0;
ret = esp_psram_impl_get_physical_size(&psram_physical_size);
@@ -167,13 +168,6 @@ static esp_err_t s_psram_chip_init(uint32_t *out_available_size)
ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in low/high (2-core) mode.");
#endif
#endif
uint32_t psram_available_size = 0;
ret = esp_psram_impl_get_available_size(&psram_available_size);
assert(ret == ESP_OK);
*out_available_size = psram_available_size;
return ESP_OK;
}
@@ -349,15 +343,26 @@ static void s_psram_mapping(uint32_t psram_available_size, uint32_t start_page)
#endif
}
esp_err_t esp_psram_chip_init(void)
{
return s_psram_chip_init();
}
esp_err_t esp_psram_init(void)
{
esp_err_t ret = ESP_FAIL;
uint32_t psram_available_size = 0;
ret = s_psram_chip_init(&psram_available_size);
if (ret != ESP_OK) {
return ret;
if (!s_psram_ctx.is_chip_initialised) {
ret = esp_psram_chip_init();
if (ret != ESP_OK) {
return ret;
}
}
uint32_t psram_available_size = 0;
ret = esp_psram_impl_get_available_size(&psram_available_size);
assert(ret == ESP_OK);
/**
* `start_page` is the psram physical address in MMU page size.
* MMU page size on ESP32S2 is 64KB
@@ -382,6 +387,7 @@ esp_err_t esp_psram_init(void)
cache_register_writeback(&drv);
#endif
s_psram_ctx.is_initialised = true;
return ESP_OK;
}

View File

@@ -565,19 +565,23 @@ void IRAM_ATTR call_start_cpu0(void)
#endif
#endif
#if CONFIG_SPIRAM_BOOT_HW_INIT
if (esp_psram_chip_init() != ESP_OK) {
#if CONFIG_SPIRAM_IGNORE_NOTFOUND
ESP_DRAM_LOGE(TAG, "Failed to init external RAM; continuing without it.");
#else
ESP_DRAM_LOGE(TAG, "Failed to init external RAM!");
abort();
#endif
}
#endif
#if CONFIG_SPIRAM_BOOT_INIT
if (esp_psram_init() != ESP_OK) {
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
ESP_DRAM_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
abort();
#endif
#if CONFIG_SPIRAM_IGNORE_NOTFOUND
ESP_EARLY_LOGI(TAG, "Failed to init external RAM; continuing without it.");
#else
ESP_DRAM_LOGE(TAG, "Failed to init external RAM!");
abort();
#endif
}
#endif
@@ -792,13 +796,13 @@ void IRAM_ATTR call_start_cpu0(void)
}
#if CONFIG_IDF_TARGET_ESP32
#if !CONFIG_SPIRAM_BOOT_INIT
#if !CONFIG_SPIRAM_BOOT_HW_INIT
// If psram is uninitialized, we need to improve some flash configuration.
bootloader_flash_clock_config(&fhdr);
bootloader_flash_gpio_config(&fhdr);
bootloader_flash_dummy_config(&fhdr);
bootloader_flash_cs_timing_config();
#endif //!CONFIG_SPIRAM_BOOT_INIT
#endif //!CONFIG_SPIRAM_BOOT_HW_INIT
#endif //CONFIG_IDF_TARGET_ESP32
#if CONFIG_SPI_FLASH_SIZE_OVERRIDE

View File

@@ -414,7 +414,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL2_CLK_EN);
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL1_CLK_EN);
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL0_CLK_EN);
#if !CONFIG_SPIRAM_BOOT_INIT
#if !CONFIG_SPIRAM_BOOT_HW_INIT
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN);
#endif
REG_CLR_BIT(LP_SYSTEM_REG_HP_ROOT_CLK_CTRL_REG, LP_SYSTEM_REG_CPU_CLK_EN);