forked from espressif/esp-idf
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:
@@ -2,18 +2,29 @@
|
|||||||
#
|
#
|
||||||
# sourced into the "SPIRAM config" submenu for a specific chip.
|
# sourced into the "SPIRAM config" submenu for a specific chip.
|
||||||
|
|
||||||
config SPIRAM_BOOT_INIT
|
config SPIRAM_BOOT_HW_INIT
|
||||||
bool "Initialize SPI RAM during startup"
|
bool "Initialise the PSRAM related hardware"
|
||||||
default "y"
|
depends on SPIRAM
|
||||||
|
default "y" if SPIRAM
|
||||||
help
|
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
|
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
|
config SPIRAM_IGNORE_NOTFOUND
|
||||||
bool "Ignore PSRAM when not found"
|
bool "Ignore PSRAM when not found"
|
||||||
default "n"
|
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
|
help
|
||||||
Normally, if psram initialization is enabled during compile time but not found at runtime, it
|
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
|
is seen as an error making the CPU panic. If this is enabled, booting will complete
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -60,6 +60,17 @@ bool esp_psram_extram_test(void);
|
|||||||
*/
|
*/
|
||||||
void esp_psram_bss_init(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
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
/**
|
/**
|
||||||
* @brief Force a writeback of the data in the PSRAM cache. This is to be called whenever
|
* @brief Force a writeback of the data in the PSRAM cache. This is to be called whenever
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -17,6 +17,7 @@ extern "C" {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize PSRAM interface/hardware.
|
* @brief Initialize PSRAM interface/hardware.
|
||||||
|
* Initializes the PSRAM hardware and load the XIP segments or maps the PSRAM memory
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: On success
|
* - ESP_OK: On success
|
||||||
|
@@ -20,6 +20,7 @@ entries:
|
|||||||
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
|
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
|
||||||
esp_psram_impl_ap_hex (noflash)
|
esp_psram_impl_ap_hex (noflash)
|
||||||
mmu_psram_flash_v2 (noflash)
|
mmu_psram_flash_v2 (noflash)
|
||||||
|
esp_psram: esp_psram_chip_init (noflash)
|
||||||
esp_psram: esp_psram_init (noflash)
|
esp_psram: esp_psram_init (noflash)
|
||||||
esp_psram: s_psram_chip_init (noflash)
|
esp_psram: s_psram_chip_init (noflash)
|
||||||
esp_psram: s_xip_psram_placement (noflash)
|
esp_psram: s_xip_psram_placement (noflash)
|
||||||
|
@@ -78,7 +78,8 @@ typedef struct {
|
|||||||
} psram_mem_t;
|
} psram_mem_t;
|
||||||
|
|
||||||
typedef struct {
|
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
|
* @note 1
|
||||||
* As we can't use heap allocator during this stage, we need to statically declare these regions.
|
* 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
|
#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;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ static esp_err_t s_psram_chip_init(uint32_t *out_available_size)
|
|||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
s_psram_ctx.is_initialised = true;
|
s_psram_ctx.is_chip_initialised = true;
|
||||||
|
|
||||||
uint32_t psram_physical_size = 0;
|
uint32_t psram_physical_size = 0;
|
||||||
ret = esp_psram_impl_get_physical_size(&psram_physical_size);
|
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.");
|
ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in low/high (2-core) mode.");
|
||||||
#endif
|
#endif
|
||||||
#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;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,15 +343,26 @@ static void s_psram_mapping(uint32_t psram_available_size, uint32_t start_page)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_psram_chip_init(void)
|
||||||
|
{
|
||||||
|
return s_psram_chip_init();
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_psram_init(void)
|
esp_err_t esp_psram_init(void)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_FAIL;
|
esp_err_t ret = ESP_FAIL;
|
||||||
uint32_t psram_available_size = 0;
|
|
||||||
ret = s_psram_chip_init(&psram_available_size);
|
if (!s_psram_ctx.is_chip_initialised) {
|
||||||
if (ret != ESP_OK) {
|
ret = esp_psram_chip_init();
|
||||||
return ret;
|
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.
|
* `start_page` is the psram physical address in MMU page size.
|
||||||
* MMU page size on ESP32S2 is 64KB
|
* MMU page size on ESP32S2 is 64KB
|
||||||
@@ -382,6 +387,7 @@ esp_err_t esp_psram_init(void)
|
|||||||
cache_register_writeback(&drv);
|
cache_register_writeback(&drv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
s_psram_ctx.is_initialised = true;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -565,19 +565,23 @@ void IRAM_ATTR call_start_cpu0(void)
|
|||||||
#endif
|
#endif
|
||||||
#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 CONFIG_SPIRAM_BOOT_INIT
|
||||||
if (esp_psram_init() != ESP_OK) {
|
if (esp_psram_init() != ESP_OK) {
|
||||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||||
ESP_DRAM_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
|
ESP_DRAM_LOGE(TAG, "Failed to init external RAM, needed for external .bss segment");
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
@@ -792,13 +796,13 @@ void IRAM_ATTR call_start_cpu0(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
#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.
|
// If psram is uninitialized, we need to improve some flash configuration.
|
||||||
bootloader_flash_clock_config(&fhdr);
|
bootloader_flash_clock_config(&fhdr);
|
||||||
bootloader_flash_gpio_config(&fhdr);
|
bootloader_flash_gpio_config(&fhdr);
|
||||||
bootloader_flash_dummy_config(&fhdr);
|
bootloader_flash_dummy_config(&fhdr);
|
||||||
bootloader_flash_cs_timing_config();
|
bootloader_flash_cs_timing_config();
|
||||||
#endif //!CONFIG_SPIRAM_BOOT_INIT
|
#endif //!CONFIG_SPIRAM_BOOT_HW_INIT
|
||||||
#endif //CONFIG_IDF_TARGET_ESP32
|
#endif //CONFIG_IDF_TARGET_ESP32
|
||||||
|
|
||||||
#if CONFIG_SPI_FLASH_SIZE_OVERRIDE
|
#if CONFIG_SPI_FLASH_SIZE_OVERRIDE
|
||||||
|
@@ -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_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_PLL1_CLK_EN);
|
||||||
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_SDIO_PLL0_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);
|
REG_CLR_BIT(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_MPLL_500M_CLK_EN);
|
||||||
#endif
|
#endif
|
||||||
REG_CLR_BIT(LP_SYSTEM_REG_HP_ROOT_CLK_CTRL_REG, LP_SYSTEM_REG_CPU_CLK_EN);
|
REG_CLR_BIT(LP_SYSTEM_REG_HP_ROOT_CLK_CTRL_REG, LP_SYSTEM_REG_CPU_CLK_EN);
|
||||||
|
Reference in New Issue
Block a user