mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/add_system_components_to_esp32c5mp' into 'master'
feat(esp32c5mp): add system related components (Stage 5/7) See merge request espressif/esp-idf!29603
This commit is contained in:
commit
a77a7ab550
@ -11,7 +11,14 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp32c5/rom/spi_flash.h"
|
||||
#include "esp32c5/rom/efuse.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
// TODO: IDF-9197
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#endif
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@ -24,6 +31,7 @@
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
@ -199,6 +207,20 @@ static void bootloader_spi_flash_resume(void)
|
||||
|
||||
esp_err_t bootloader_init_spi_flash(void)
|
||||
{
|
||||
// TODO: IDF-9197
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
// On ESP32C5, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration
|
||||
// Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at
|
||||
// 80MHz after the switch. PLL = 480MHz, so divider is 6.
|
||||
clk_ll_mspi_fast_set_hs_divider(6);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
/* TODO: [ESP32C5] IDF-8649 temporary use xtal clock source,
|
||||
need to change back SPLL(480M) and set divider to 6 to use the 80M MSPI,
|
||||
and we need to check flash freq before restart as well */
|
||||
clk_ll_mspi_fast_set_divider(1);
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_XTAL);
|
||||
#endif
|
||||
|
||||
bootloader_init_flash_configure();
|
||||
bootloader_spi_flash_resume();
|
||||
bootloader_flash_unlock();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -66,7 +66,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C5
|
||||
// TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock has timing issue
|
||||
// Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd stage bootloader
|
||||
clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST;
|
||||
@ -81,14 +81,6 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
rtc_clk_init(clk_cfg);
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
/* TODO: [ESP32C5] IDF-8649 temporary use xtal clock source,
|
||||
need to change back SPLL(480M) and set divider to 6 to use the 80M MSPI,
|
||||
and we need to check flash freq before restart as well */
|
||||
clk_ll_mspi_fast_set_divider(1);
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_XTAL);
|
||||
#endif
|
||||
|
||||
/* As a slight optimization, if 32k XTAL was enabled in sdkconfig, we enable
|
||||
* it here. Usually it needs some time to start up, so we amortize at least
|
||||
* part of the start up time by enabling 32k XTAL early.
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_rom_caps.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
#include "soc/pcr_reg.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_CONSOLE_NONE
|
||||
void bootloader_console_init(void)
|
||||
@ -85,6 +88,13 @@ void bootloader_console_init(void)
|
||||
#if ESP_ROM_UART_CLK_IS_XTAL
|
||||
clock_hz = (uint32_t)rtc_clk_xtal_freq_get() * MHZ; // From esp32-s3 on, UART clk source is selected to XTAL in ROM
|
||||
#endif
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
#if CONFIG_IDF_ENV_FPGA
|
||||
clock_hz = CONFIG_XTAL_FREQ * MHZ;
|
||||
#else
|
||||
clock_hz = REG_GET_FIELD(PCR_SYSCLK_CONF_REG, PCR_CLK_XTAL_FREQ) * MHZ;
|
||||
#endif // CONFIG_IDF_ENV_FPGA
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
esp_rom_uart_set_clock_baudrate(uart_num, clock_hz, CONFIG_ESP_CONSOLE_UART_BAUDRATE);
|
||||
}
|
||||
#endif // CONFIG_ESP_CONSOLE_UART
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "hal/apm_hal.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-8615 Remove the workaround when APM supported on C5!
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION // TODO: IDF-8615 Remove the workaround when APM supported on C5!
|
||||
#include "soc/hp_apm_reg.h"
|
||||
#include "soc/lp_apm_reg.h"
|
||||
#include "soc/lp_apm0_reg.h"
|
||||
@ -36,7 +36,7 @@ void bootloader_init_mem(void)
|
||||
apm_hal_apm_ctrl_filter_enable_all(false);
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5 // TODO: IDF-8615 Remove the workaround when APM supported on C5!
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION // TODO: IDF-8615 Remove the workaround when APM supported on C5!
|
||||
// disable apm filter
|
||||
REG_WRITE(LP_APM_FUNC_CTRL_REG, 0);
|
||||
REG_WRITE(LP_APM0_FUNC_CTRL_REG, 0);
|
||||
@ -45,6 +45,6 @@ void bootloader_init_mem(void)
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE
|
||||
// protect memory region
|
||||
esp_cpu_configure_region_protection();
|
||||
esp_cpu_configure_region_protection(); // TODO: [ESP32C5] IDF-8833 PSRAM support write
|
||||
#endif
|
||||
}
|
||||
|
@ -12,12 +12,12 @@
|
||||
|
||||
void bootloader_random_enable(void)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8626
|
||||
// TODO: [ESP32C5] IDF-8626, IDF-9197
|
||||
ESP_EARLY_LOGW("bootloader_random", "bootloader_random_enable() has not been implemented on C5 yet");
|
||||
}
|
||||
|
||||
void bootloader_random_disable(void)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8626
|
||||
// TODO: [ESP32C5] IDF-8626, IDF-9197
|
||||
ESP_EARLY_LOGW("bootloader_random", "bootloader_random_disable() has not been implemented on C5 yet");
|
||||
}
|
||||
|
@ -645,6 +645,12 @@ static void load_image(const esp_image_metadata_t *image_data)
|
||||
#endif // CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
|
||||
|
||||
if (!flash_encryption_enabled) {
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
// TODO: [ESP32C5] IDF-8622 find a more proper place for these codes
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH);
|
||||
REG_SET_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
REG_CLR_BIT(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
#endif
|
||||
err = esp_flash_encrypt_contents();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Encryption flash contents failed (%d)", err);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_rom_spiflash.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/assist_debug_reg.h"
|
||||
@ -41,7 +42,9 @@
|
||||
#include "soc/lp_wdt_reg.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/lpwdt_ll.h"
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "modem/modem_lpcon_reg.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "boot.esp32c5";
|
||||
|
||||
@ -85,12 +88,15 @@ static void bootloader_super_wdt_auto_feed(void)
|
||||
static inline void bootloader_hardware_init(void)
|
||||
{
|
||||
/* Enable analog i2c master clock */
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
|
||||
SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
{
|
||||
// TODO: IDF-9197
|
||||
// TODO: [ESP32C5] IDF-8650
|
||||
//Enable super WDT reset.
|
||||
// bootloader_ana_super_wdt_reset_config(true);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -6,17 +6,18 @@ set(srcs "rtc_clk_init.c"
|
||||
"chip_info.c"
|
||||
)
|
||||
|
||||
# TODO: [ESP32C5] IDF-8667
|
||||
if(IDF_TARGET STREQUAL "esp32c5")
|
||||
list(REMOVE_ITEM srcs "pmu_init.c"
|
||||
"pmu_param.c")
|
||||
endif()
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "sar_periph_ctrl.c"
|
||||
"esp_crypto_lock.c")
|
||||
endif()
|
||||
|
||||
# TODO: [ESP32C5] IDF-8667
|
||||
if(IDF_TARGET STREQUAL "esp32c5")
|
||||
list(REMOVE_ITEM srcs "pmu_init.c"
|
||||
"pmu_param.c"
|
||||
"sar_periph_ctrl.c")
|
||||
endif()
|
||||
|
||||
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
|
||||
|
||||
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
|
||||
|
@ -1,9 +1,14 @@
|
||||
choice RTC_CLK_SRC
|
||||
prompt "RTC clock source"
|
||||
default RTC_CLK_SRC_INT_RC32K
|
||||
# TODO: IDF-9197
|
||||
default RTC_CLK_SRC_INT_RC if IDF_TARGET_ESP32C5_MP_VERSION
|
||||
default RTC_CLK_SRC_INT_RC32K if IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
help
|
||||
Choose which clock is used as RTC clock source.
|
||||
|
||||
config RTC_CLK_SRC_INT_RC
|
||||
depends on IDF_TARGET_ESP32C5_MP_VERSION
|
||||
bool "Internal 136kHz RC oscillator"
|
||||
config RTC_CLK_SRC_EXT_CRYS
|
||||
bool "External 32kHz crystal"
|
||||
select ESP_SYSTEM_RTC_EXT_XTAL
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_chip_info.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
void esp_chip_info(esp_chip_info_t *out_info)
|
||||
@ -14,5 +15,5 @@ void esp_chip_info(esp_chip_info_t *out_info)
|
||||
out_info->model = CHIP_ESP32C5;
|
||||
out_info->revision = efuse_hal_chip_revision();
|
||||
out_info->cores = 1;
|
||||
out_info->features = CHIP_FEATURE_WIFI_BGN | CHIP_FEATURE_BLE;
|
||||
out_info->features = CHIP_FEATURE_WIFI_BGN | CHIP_FEATURE_BLE | CHIP_FEATURE_IEEE802154;
|
||||
}
|
||||
|
@ -24,7 +24,194 @@
|
||||
#define CONDITIONAL_RWX RWX
|
||||
#endif
|
||||
|
||||
// TODO: IDF-9197
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8833
|
||||
// TODO: [ESP32C5] IDF-8833
|
||||
}
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
static void esp_cpu_configure_invalid_regions(void)
|
||||
{
|
||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||
__attribute__((unused)) const unsigned PMA_RW = PMA_L | PMA_EN | PMA_R | PMA_W;
|
||||
__attribute__((unused)) const unsigned PMA_RX = PMA_L | PMA_EN | PMA_R | PMA_X;
|
||||
__attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X;
|
||||
|
||||
// 1. Gap at bottom of address space
|
||||
PMA_ENTRY_SET_TOR(0, SOC_DEBUG_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 2. Gap between debug region & IROM
|
||||
PMA_ENTRY_SET_TOR(1, SOC_DEBUG_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 3. Gap between ROM & RAM
|
||||
PMA_ENTRY_SET_TOR(3, SOC_DROM_MASK_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(4, SOC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 4. Gap between DRAM and I_Cache
|
||||
PMA_ENTRY_SET_TOR(5, SOC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(6, SOC_IROM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 5. Gap between D_Cache & LP_RAM
|
||||
PMA_ENTRY_SET_TOR(7, SOC_DROM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(8, SOC_RTC_IRAM_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 6. Gap between LP memory & peripheral addresses
|
||||
PMA_ENTRY_SET_TOR(9, SOC_RTC_IRAM_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(10, SOC_PERIPHERAL_LOW, PMA_TOR | PMA_NONE);
|
||||
|
||||
// 7. End of address space
|
||||
PMA_ENTRY_SET_TOR(11, SOC_PERIPHERAL_HIGH, PMA_NONE);
|
||||
PMA_ENTRY_SET_TOR(12, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||
}
|
||||
|
||||
void esp_cpu_configure_region_protection(void)
|
||||
{
|
||||
// ROM has configured the MSPI region with RX permission, we should add W attribute for psram
|
||||
PMA_ENTRY_SET_NAPOT(0, SOC_IROM_LOW, (SOC_IROM_HIGH - SOC_IROM_LOW), PMA_NAPOT | PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X);
|
||||
return;
|
||||
/* Notes on implementation:
|
||||
*
|
||||
* 1) Note: ESP32-C6 CPU doesn't support overlapping PMP regions
|
||||
*
|
||||
* 2) ESP32-C6 supports 16 PMA regions so we use this feature to block all the invalid address ranges
|
||||
*
|
||||
* 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range)
|
||||
* entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries
|
||||
* which can be used to provide more granular access
|
||||
*
|
||||
* 4) Entries are grouped in order with some static asserts to try and verify everything is
|
||||
* correct.
|
||||
*/
|
||||
|
||||
/* There are 4 configuration scenarios for SRAM
|
||||
*
|
||||
* 1. Bootloader build:
|
||||
* - We cannot set the lock bit as we need to reconfigure it again for the application.
|
||||
* We configure PMP to cover entire valid IRAM and DRAM range.
|
||||
*
|
||||
* 2. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT enabled
|
||||
* - We split the SRAM into IRAM and DRAM such that IRAM region cannot be written to
|
||||
* and DRAM region cannot be executed. We use _iram_end and _data_start markers to set the boundaries.
|
||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||
*
|
||||
* 3. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT disabled
|
||||
* - The IRAM-DRAM split is not enabled so we just need to ensure that access to only valid address ranges are successful
|
||||
* so for that we set PMP to cover entire valid IRAM and DRAM region.
|
||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||
*
|
||||
* 4. CPU is in OCD debug mode
|
||||
* - The IRAM-DRAM split is not enabled so that OpenOCD can write and execute from IRAM.
|
||||
* We set PMP to cover entire valid IRAM and DRAM region.
|
||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||
*/
|
||||
const unsigned NONE = PMP_L;
|
||||
const unsigned R = PMP_L | PMP_R;
|
||||
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
||||
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
||||
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
||||
|
||||
//
|
||||
// Configure all the invalid address regions using PMA
|
||||
//
|
||||
esp_cpu_configure_invalid_regions();
|
||||
|
||||
//
|
||||
// Configure all the valid address regions using PMP
|
||||
//
|
||||
|
||||
// 1. Debug region
|
||||
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_DEBUG_LOW, SOC_DEBUG_HIGH);
|
||||
PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX);
|
||||
_Static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region");
|
||||
|
||||
// 2.1 I-ROM
|
||||
PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE);
|
||||
PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX);
|
||||
_Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I-ROM region");
|
||||
|
||||
// 2.2 D-ROM
|
||||
PMP_ENTRY_SET(3, SOC_DROM_MASK_LOW, NONE);
|
||||
PMP_ENTRY_SET(4, SOC_DROM_MASK_HIGH, PMP_TOR | R);
|
||||
_Static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH, "Invalid D-ROM region");
|
||||
|
||||
if (esp_cpu_dbgr_is_attached()) {
|
||||
// Anti-FI check that cpu is really in ocd mode
|
||||
ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached());
|
||||
|
||||
// 5. IRAM and DRAM
|
||||
// const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH);
|
||||
// PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | RWX);
|
||||
// _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||
PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE);
|
||||
PMP_ENTRY_SET(6, SOC_IRAM_HIGH, PMP_TOR | RWX);
|
||||
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||
} else {
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _iram_end;
|
||||
// 5. IRAM and DRAM
|
||||
/* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits
|
||||
* Bootloader might have given extra permissions and those won't be cleared
|
||||
*/
|
||||
PMP_ENTRY_CFG_RESET(5);
|
||||
PMP_ENTRY_CFG_RESET(6);
|
||||
PMP_ENTRY_CFG_RESET(7);
|
||||
PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE);
|
||||
PMP_ENTRY_SET(6, (int)&_iram_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(7, SOC_DRAM_HIGH, PMP_TOR | RW);
|
||||
#else
|
||||
// 5. IRAM and DRAM
|
||||
// const uint32_t pmpaddr5 = PMPADDR_NAPOT(SOC_IRAM_LOW, SOC_IRAM_HIGH);
|
||||
// PMP_ENTRY_SET(5, pmpaddr5, PMP_NAPOT | CONDITIONAL_RWX);
|
||||
// _Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||
PMP_ENTRY_SET(5, SOC_IRAM_LOW, NONE);
|
||||
PMP_ENTRY_SET(6, SOC_IRAM_HIGH, PMP_TOR | RWX);
|
||||
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||
#endif
|
||||
}
|
||||
|
||||
// 4. I_Cache (flash)
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX);
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region");
|
||||
|
||||
// 5. D_Cache (flash)
|
||||
const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH);
|
||||
PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R);
|
||||
_Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region");
|
||||
|
||||
// 6. LP memory
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _rtc_text_end;
|
||||
/* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits
|
||||
* Bootloader might have given extra permissions and those won't be cleared
|
||||
*/
|
||||
PMP_ENTRY_CFG_RESET(10);
|
||||
PMP_ENTRY_CFG_RESET(11);
|
||||
PMP_ENTRY_CFG_RESET(12);
|
||||
PMP_ENTRY_CFG_RESET(13);
|
||||
PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE);
|
||||
#if CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// First part of LP mem is reserved for coprocessor
|
||||
PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW);
|
||||
#else // CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
// Repeat same previous entry, to ensure next entry has correct base address (TOR)
|
||||
PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE);
|
||||
#endif // !CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
PMP_ENTRY_SET(12, (int)&_rtc_text_end, PMP_TOR | RX);
|
||||
PMP_ENTRY_SET(13, SOC_RTC_IRAM_HIGH, PMP_TOR | RW);
|
||||
#else
|
||||
const uint32_t pmpaddr10 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH);
|
||||
PMP_ENTRY_SET(10, pmpaddr10, PMP_NAPOT | CONDITIONAL_RWX);
|
||||
_Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region");
|
||||
#endif
|
||||
|
||||
|
||||
// 7. Peripheral addresses
|
||||
const uint32_t pmpaddr14 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH);
|
||||
PMP_ENTRY_SET(14, pmpaddr14, PMP_NAPOT | RW);
|
||||
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
|
@ -19,7 +19,7 @@ static const char *TAG = "esp_clk_tree";
|
||||
esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision,
|
||||
uint32_t *freq_value)
|
||||
{
|
||||
// TODO: [ESP32C5] IDF-8642
|
||||
// TODO: [ESP32C5] IDF-8642 check again for MP version
|
||||
ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src");
|
||||
ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision");
|
||||
ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer");
|
||||
@ -38,9 +38,11 @@ uint32_t *freq_value)
|
||||
case SOC_MOD_CLK_PLL_F240M:
|
||||
clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ;
|
||||
break;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
case SOC_MOD_CLK_RTC_FAST:
|
||||
clk_src_freq = 20 * MHZ;
|
||||
break;
|
||||
#endif
|
||||
case SOC_MOD_CLK_SPLL:
|
||||
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ;
|
||||
break;
|
||||
|
@ -367,6 +367,12 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
|
||||
# define PMU_SLOW_CLK_USE_EXT_XTAL (0)
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#define PMU_LP_DEFAULT_XPD_RC32K (1)
|
||||
#else
|
||||
#define PMU_LP_DEFAULT_XPD_RC32K (0)
|
||||
#endif
|
||||
|
||||
#define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \
|
||||
.dig_power = { \
|
||||
.mem_dslp = 0, \
|
||||
@ -374,7 +380,7 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
|
||||
}, \
|
||||
.clk_power = { \
|
||||
.xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \
|
||||
.xpd_rc32k = 1, \
|
||||
.xpd_rc32k = PMU_LP_DEFAULT_XPD_RC32K, \
|
||||
.xpd_fosc = 1, \
|
||||
.pd_osc = 0 \
|
||||
} \
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp32c5/rom/rtc.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "esp_hw_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
@ -21,11 +22,13 @@
|
||||
#include "soc/lp_aon_reg.h"
|
||||
#include "esp_private/sleep_event.h"
|
||||
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#else
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const char *TAG = "rtc_clk";
|
||||
|
||||
@ -114,7 +117,9 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||
{
|
||||
switch (rtc_clk_slow_src_get()) {
|
||||
// case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
||||
#endif
|
||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
|
||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
|
||||
@ -146,6 +151,7 @@ static void rtc_clk_bbpll_enable(void)
|
||||
|
||||
static void rtc_clk_enable_i2c_ana_master_clock(bool enable)
|
||||
{
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
modem_lpcon_ll_enable_i2c_master_clock(&MODEM_LPCON, enable);
|
||||
#else
|
||||
@ -155,6 +161,7 @@ static void rtc_clk_enable_i2c_ana_master_clock(bool enable)
|
||||
modem_clock_module_disable(PERIPH_ANA_I2C_MASTER_MODULE);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
|
||||
@ -168,7 +175,9 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
|
||||
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
|
||||
/* WAIT CALIBRATION DONE */
|
||||
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
esp_rom_delay_us(10); // wait for true stop // TODO: check this
|
||||
#endif
|
||||
/* BBPLL CALIBRATION STOP */
|
||||
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||
rtc_clk_enable_i2c_ana_master_clock(false);
|
||||
@ -182,6 +191,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
/* Configure clk mspi fast to XTAL*/
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_XTAL);
|
||||
clk_ll_mspi_fast_set_divider(1);
|
||||
@ -190,11 +200,17 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||
clk_ll_ahb_set_divider(div);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||
clk_ll_bus_update();
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
clk_ll_ahb_set_ls_divider(div);
|
||||
clk_ll_cpu_set_ls_divider(div);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||
#endif
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||
}
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
/* Configure clk mspi fast to XTAL*/
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_XTAL);
|
||||
clk_ll_mspi_fast_set_divider(1);
|
||||
@ -203,6 +219,11 @@ static void rtc_clk_cpu_freq_to_8m(void)
|
||||
clk_ll_ahb_set_divider(1);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
clk_ll_bus_update();
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
clk_ll_ahb_set_ls_divider(1);
|
||||
clk_ll_cpu_set_ls_divider(1);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
#endif
|
||||
esp_rom_set_cpu_ticks_per_us(20);
|
||||
}
|
||||
|
||||
@ -213,6 +234,7 @@ static void rtc_clk_cpu_freq_to_8m(void)
|
||||
*/
|
||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
rtc_cpu_freq_config_t cfg;
|
||||
rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &cfg);
|
||||
// Set AHB always be 40MHz
|
||||
@ -225,6 +247,11 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||
/* Configure clk mspi fast to 80m*/
|
||||
clk_ll_mspi_fast_set_divider(6);
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_SPLL);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
|
||||
@ -235,7 +262,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
||||
uint32_t real_freq_mhz;
|
||||
|
||||
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
#if (CONFIG_XTAL_FREQ == 48)
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION && (CONFIG_XTAL_FREQ == 48)
|
||||
// To maintain APB_MAX (40MHz) while lowering CPU frequency when using a 48MHz XTAL, have to let CPU frequnecy be
|
||||
// 40MHz with PLL_F160M or PLL_F240M clock source. This is a special case, has to handle separately.
|
||||
if (freq_mhz == 40) {
|
||||
@ -255,6 +282,7 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
||||
|
||||
source_freq_mhz = xtal_freq;
|
||||
source = SOC_CPU_CLK_SRC_XTAL;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
} else if (freq_mhz == 240) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL_F240M;
|
||||
@ -265,6 +293,23 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
|
||||
source = SOC_CPU_CLK_SRC_PLL_F160M;
|
||||
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
|
||||
divider = CLK_LL_PLL_160M_FREQ_MHZ / freq_mhz;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
} else if (freq_mhz == 80) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 6;
|
||||
} else if (freq_mhz == 120) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 4;
|
||||
} else if (freq_mhz == 160) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 3;
|
||||
#endif
|
||||
} else {
|
||||
// unsupported frequency
|
||||
return false;
|
||||
@ -285,6 +330,7 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_pll(int event_id)
|
||||
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
/* Configure clk mspi fast to 80m*/
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
@ -308,35 +354,68 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
|
||||
// We don't turn off the bbpll if some consumers depend on bbpll
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
|
||||
rtc_clk_bbpll_enable();
|
||||
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
|
||||
}
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
|
||||
// We don't turn off the bbpll if some consumers depend on bbpll
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
|
||||
{
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
uint32_t source_freq_mhz;
|
||||
uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
uint32_t freq_mhz;
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
uint32_t div = clk_ll_cpu_get_ls_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
uint32_t hs_div = clk_ll_cpu_get_hs_divider();
|
||||
#else
|
||||
uint32_t div = 0;
|
||||
#endif
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
case SOC_CPU_CLK_SRC_PLL_F160M: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_PLL_F240M: {
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ;
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
case SOC_CPU_CLK_SRC_PLL: {
|
||||
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
freq_mhz = source_freq_mhz / hs_div;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
div = clk_ll_cpu_get_divider();
|
||||
source_freq_mhz = 20;
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
@ -356,8 +435,14 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
|
||||
{
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
} else if (((config->source == SOC_CPU_CLK_SRC_PLL_F160M) || (config->source == SOC_CPU_CLK_SRC_PLL_F240M)) &&
|
||||
s_cur_pll_freq == config->source_freq_mhz) {
|
||||
} else if (
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
((config->source == SOC_CPU_CLK_SRC_PLL_F160M) || (config->source == SOC_CPU_CLK_SRC_PLL_F240M)) &&
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
config->source == SOC_CPU_CLK_SRC_PLL &&
|
||||
#endif
|
||||
s_cur_pll_freq == config->source_freq_mhz
|
||||
) {
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
@ -391,7 +476,16 @@ void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz)
|
||||
|
||||
soc_xtal_freq_t rtc_clk_xtal_freq_get(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
return CONFIG_XTAL_FREQ;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||
if (xtal_freq_mhz == 0) {
|
||||
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
|
||||
return RTC_XTAL_FREQ_40M;
|
||||
}
|
||||
return (soc_xtal_freq_t)xtal_freq_mhz;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq)
|
||||
@ -405,6 +499,7 @@ static uint32_t rtc_clk_ahb_freq_get(void)
|
||||
uint32_t soc_root_freq_mhz;
|
||||
uint32_t divider;
|
||||
switch (source) {
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
|
||||
divider = clk_ll_ahb_get_divider();
|
||||
@ -421,6 +516,20 @@ static uint32_t rtc_clk_ahb_freq_get(void)
|
||||
soc_root_freq_mhz = 20;
|
||||
divider = clk_ll_ahb_get_divider();
|
||||
break;
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
divider = clk_ll_ahb_get_hs_divider();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
soc_root_freq_mhz = 20;
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// Unknown SOC_ROOT clock source
|
||||
soc_root_freq_mhz = 0;
|
||||
@ -452,3 +561,10 @@ bool rtc_dig_8m_enabled(void)
|
||||
{
|
||||
return clk_ll_rc_fast_digi_is_enabled();
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
/* Name used in libphy.a:phy_chip_v7.o
|
||||
* TODO: update the library to use rtc_clk_xtal_freq_get
|
||||
*/
|
||||
rtc_xtal_freq_t rtc_get_xtal(void) __attribute__((alias("rtc_clk_xtal_freq_get")));
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "esp32c5/rom/rtc.h"
|
||||
#include "esp32c5/rom/uart.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "regi2c_ctrl.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
@ -21,8 +22,10 @@
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "hal/modem_syscon_ll.h"
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#endif
|
||||
#include "pmu_param.h"
|
||||
|
||||
static const char *TAG = "rtc_clk_init";
|
||||
@ -44,17 +47,18 @@ static void rtc_clk_modem_clock_domain_active_state_icg_map_preinit(void)
|
||||
/* Configure modem ICG code in PMU_ACTIVE state */
|
||||
pmu_ll_hp_set_icg_modem(&PMU, PMU_MODE_HP_ACTIVE, PMU_HP_ICG_MODEM_CODE_ACTIVE);
|
||||
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
/* Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in PMU_ACTIVE state */
|
||||
modem_syscon_ll_set_modem_apb_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_lpcon_ll_set_i2c_master_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
modem_lpcon_ll_set_lp_apb_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE));
|
||||
#endif
|
||||
|
||||
/* Software trigger force update modem ICG code and ICG switch */
|
||||
pmu_ll_imm_update_dig_icg_modem_code(&PMU, true);
|
||||
pmu_ll_imm_update_dig_icg_switch(&PMU, true);
|
||||
}
|
||||
|
||||
|
||||
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||
{
|
||||
rtc_cpu_freq_config_t old_config, new_config;
|
||||
|
@ -211,7 +211,6 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
|
||||
// TODO: IDF-8642 Check whether this workaround still need for C5
|
||||
// /*The Fosc CLK of calibration circuit is divided by 32.
|
||||
// So we need to divide the calibrate cycles of the FOSC by 32 to
|
||||
@ -221,7 +220,6 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
// }
|
||||
|
||||
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
|
||||
|
||||
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ esp_err_t sleep_clock_system_retention_init(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C6
|
||||
#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
#define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_1_REG - DR_REG_PCR_BASE) / 4) + 1)
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
|
||||
#endif
|
||||
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
|
||||
|
@ -99,6 +99,7 @@ menu "ESP System Settings"
|
||||
default y if IDF_TARGET_ESP32C6
|
||||
default n if IDF_TARGET_ESP32H2 # IDF-5667
|
||||
default y if IDF_TARGET_ESP32P4
|
||||
default y if IDF_TARGET_ESP32C5
|
||||
depends on SOC_RTC_FAST_MEM_SUPPORTED
|
||||
|
||||
config ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||
@ -359,7 +360,8 @@ menu "ESP System Settings"
|
||||
prompt "UART console baud rate" if ESP_CONSOLE_UART_CUSTOM
|
||||
depends on ESP_CONSOLE_UART
|
||||
default 74880 if (IDF_TARGET_ESP32C2 && XTAL_FREQ_26)
|
||||
default 138240 if (IDF_TARGET_ESP32C5_BETA3_VERSION && XTAL_FREQ_48)
|
||||
# TODO: IDF-8651 Check if need update
|
||||
default 138240 if (IDF_TARGET_ESP32C5 && XTAL_FREQ_48)
|
||||
default 115200
|
||||
range 1200 4000000 if !PM_ENABLE
|
||||
range 1200 1000000 if PM_ENABLE
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "esp32h2/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#include "esp32p4/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
#include "esp32c5/rom/rtc.h"
|
||||
#endif
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* ESP32-C5 Linker Script Memory Layout
|
||||
* This file describes the memory layout (memory blocks) by virtual memory addresses.
|
||||
* This linker script is passed through the C preprocessor to include configuration options.
|
||||
* Please use preprocessor features sparingly!
|
||||
* Restrict to simple macros with numeric values, and/or #if/#endif blocks.
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "ld.common"
|
||||
|
||||
/**
|
||||
* physical memory is mapped twice to the vritual address (IRAM and DRAM).
|
||||
* `I_D_SRAM_OFFSET` is the offset between the two locations of the same physical memory
|
||||
*/
|
||||
#define SRAM_IRAM_START 0x40800000
|
||||
#define SRAM_DRAM_START 0x40800000
|
||||
|
||||
#define I_D_SRAM_OFFSET (SRAM_IRAM_START - SRAM_DRAM_START)
|
||||
#define SRAM_DRAM_END 0x4086E610 - I_D_SRAM_OFFSET /* 2nd stage bootloader iram_loader_seg start address */
|
||||
|
||||
#define SRAM_IRAM_ORG (SRAM_IRAM_START)
|
||||
#define SRAM_DRAM_ORG (SRAM_DRAM_START)
|
||||
|
||||
#define I_D_SRAM_SIZE SRAM_DRAM_END - SRAM_DRAM_ORG
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/*
|
||||
* IDRAM0_2_SEG_SIZE_DEFAULT is used when page size is 64KB
|
||||
*/
|
||||
#define IDRAM0_2_SEG_SIZE (CONFIG_MMU_PAGE_SIZE << 8)
|
||||
#endif
|
||||
|
||||
#define DRAM0_0_SEG_LEN I_D_SRAM_SIZE
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/**
|
||||
* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
|
||||
* of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
* are connected to the data port of the CPU and eg allow byte-wise access.
|
||||
*/
|
||||
|
||||
/* IRAM for PRO CPU. */
|
||||
iram0_0_seg (RX) : org = SRAM_IRAM_ORG, len = I_D_SRAM_SIZE
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped instruction data */
|
||||
irom_seg (RX) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||
|
||||
/**
|
||||
* (0x20 offset above is a convenience for the app binary image generation.
|
||||
* Flash cache has 64KB pages. The .bin file which is flashed to the chip
|
||||
* has a 0x18 byte file header, and each segment has a 0x08 byte segment
|
||||
* header. Setting this offset makes it simple to meet the flash cache MMU's
|
||||
* constraint that (paddr % 64KB == vaddr % 64KB).)
|
||||
*/
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
/**
|
||||
* Shared data RAM, excluding memory reserved for ROM bss/data/stack.
|
||||
* Enabling Bluetooth & Trace Memory features in menuconfig will decrease the amount of RAM available.
|
||||
*/
|
||||
dram0_0_seg (RW) : org = SRAM_DRAM_ORG, len = DRAM0_0_SEG_LEN
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
/* Flash mapped constant data */
|
||||
drom_seg (R) : org = 0x42000020, len = IDRAM0_2_SEG_SIZE - 0x20
|
||||
|
||||
/* (See irom_seg for meaning of 0x20 offset in the above.) */
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
/**
|
||||
* lp ram memory (RWX). Persists over deep sleep. // TODO: IDF-5667
|
||||
*/
|
||||
#if CONFIG_ULP_COPROC_ENABLED
|
||||
lp_ram_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM,
|
||||
len = 0x4000 - CONFIG_ULP_COPROC_RESERVE_MEM - RESERVE_RTC_MEM
|
||||
#else
|
||||
lp_ram_seg(RW) : org = 0x50000000, len = 0x4000 - RESERVE_RTC_MEM
|
||||
#endif // CONFIG_ULP_COPROC_ENABLED
|
||||
|
||||
/* We reduced the size of lp_ram_seg by RESERVE_RTC_MEM value.
|
||||
It reserves the amount of LP memory that we use for this memory segment.
|
||||
This segment is intended for keeping:
|
||||
- (lower addr) rtc timer data (s_rtc_timer_retain_mem, see esp_clk.c files).
|
||||
- (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on).
|
||||
The aim of this is to keep data that will not be moved around and have a fixed address.
|
||||
*/
|
||||
lp_reserved_seg(RW) : org = 0x50000000 + 0x4000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM
|
||||
}
|
||||
|
||||
/* Heap ends at top of dram0_0_seg */
|
||||
_heap_end = 0x40000000;
|
||||
|
||||
_data_seg_org = ORIGIN(rtc_data_seg);
|
||||
|
||||
/**
|
||||
* The lines below define location alias for .rtc.data section
|
||||
* C5 has no distinguished LP(RTC) fast and slow memory sections, instead, there is a unified LP_RAM section
|
||||
* Thus, the following region segments are not configurable like on other targets
|
||||
*/
|
||||
REGION_ALIAS("rtc_iram_seg", lp_ram_seg );
|
||||
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
|
||||
REGION_ALIAS("rtc_slow_seg", rtc_iram_seg );
|
||||
REGION_ALIAS("rtc_data_location", rtc_iram_seg );
|
||||
REGION_ALIAS("rtc_reserved_seg", lp_reserved_seg );
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
REGION_ALIAS("default_code_seg", irom_seg);
|
||||
#else
|
||||
REGION_ALIAS("default_code_seg", iram0_0_seg);
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
REGION_ALIAS("default_rodata_seg", drom_seg);
|
||||
#else
|
||||
REGION_ALIAS("default_rodata_seg", dram0_0_seg);
|
||||
#endif // CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
/**
|
||||
* If rodata default segment is placed in `drom_seg`, then flash's first rodata section must
|
||||
* also be first in the segment.
|
||||
*/
|
||||
#if CONFIG_APP_BUILD_USE_FLASH_SECTIONS
|
||||
ASSERT(_flash_rodata_dummy_start == ORIGIN(default_rodata_seg),
|
||||
".flash_rodata_dummy section must be placed at the beginning of the rodata segment.")
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
|
||||
ASSERT ((__eh_frame_end > __eh_frame), "Error: eh_frame size is null!");
|
||||
ASSERT ((__eh_frame_hdr_end > __eh_frame_hdr), "Error: eh_frame_hdr size is null!");
|
||||
#endif
|
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "ld.common"
|
||||
|
||||
/* Default entry point */
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/**
|
||||
* RTC fast memory holds RTC wake stub code,
|
||||
* including from any source file named rtc_wake_stub*.c
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_start = ABSOLUTE(.);
|
||||
_rtc_text_start = ABSOLUTE(.);
|
||||
*(.rtc.entry.text)
|
||||
|
||||
mapping[rtc_text]
|
||||
|
||||
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
|
||||
*(.rtc_text_end_test)
|
||||
|
||||
/* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */
|
||||
. += _esp_memprot_prefetch_pad_size;
|
||||
. = ALIGN(4);
|
||||
|
||||
_rtc_text_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
* This section located in RTC FAST Memory area.
|
||||
* It holds data marked with RTC_FAST_ATTR attribute.
|
||||
* See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc.force_fast :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_force_fast_start = ABSOLUTE(.);
|
||||
|
||||
mapping[rtc_force_fast]
|
||||
|
||||
*(.rtc.force_fast .rtc.force_fast.*)
|
||||
. = ALIGN(4) ;
|
||||
|
||||
_rtc_force_fast_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
* RTC data section holds RTC wake stub
|
||||
* data/rodata, including from any source file
|
||||
* named rtc_wake_stub*.c and the data marked with
|
||||
* RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
|
||||
*/
|
||||
.rtc.data :
|
||||
{
|
||||
_rtc_data_start = ABSOLUTE(.);
|
||||
|
||||
mapping[rtc_data]
|
||||
|
||||
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .srodata.*)
|
||||
_rtc_data_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/* RTC bss, from any source file named rtc_wake_stub*.c */
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.*(.bss .bss.* .sbss .sbss.*)
|
||||
*rtc_wake_stub*.*(COMMON)
|
||||
|
||||
mapping[rtc_bss]
|
||||
|
||||
_rtc_bss_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
* This section holds data that should not be initialized at power up
|
||||
* and will be retained during deep sleep.
|
||||
* User data marked with RTC_NOINIT_ATTR will be placed
|
||||
* into this section. See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc_noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_noinit_start = ABSOLUTE(.);
|
||||
*(.rtc_noinit .rtc_noinit.*)
|
||||
. = ALIGN(4) ;
|
||||
_rtc_noinit_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
* This section located in RTC SLOW Memory area.
|
||||
* It holds data marked with RTC_SLOW_ATTR attribute.
|
||||
* See the file "esp_attr.h" for more information.
|
||||
*/
|
||||
.rtc.force_slow :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_force_slow_start = ABSOLUTE(.);
|
||||
*(.rtc.force_slow .rtc.force_slow.*)
|
||||
. = ALIGN(4) ;
|
||||
_rtc_force_slow_end = ABSOLUTE(.);
|
||||
} > lp_ram_seg
|
||||
|
||||
/**
|
||||
* This section holds RTC data that should have fixed addresses.
|
||||
* The data are not initialized at power-up and are retained during deep sleep.
|
||||
*/
|
||||
.rtc_reserved (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_reserved_start = ABSOLUTE(.);
|
||||
/* New data can only be added here to ensure existing data are not moved.
|
||||
Because data have adhered to the end of the segment and code is relied on it.
|
||||
>> put new data here << */
|
||||
|
||||
*(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*)
|
||||
KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*))
|
||||
_rtc_reserved_end = ABSOLUTE(.);
|
||||
} > rtc_reserved_seg
|
||||
|
||||
_rtc_reserved_length = _rtc_reserved_end - _rtc_reserved_start;
|
||||
ASSERT((_rtc_reserved_length <= LENGTH(rtc_reserved_seg)),
|
||||
"RTC reserved segment data does not fit.")
|
||||
|
||||
/* Get size of rtc slow data based on rtc_data_location alias */
|
||||
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_slow_end - _rtc_data_start)
|
||||
: (_rtc_force_slow_end - _rtc_force_slow_start);
|
||||
|
||||
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
|
||||
? (_rtc_force_fast_end - _rtc_fast_start)
|
||||
: (_rtc_noinit_end - _rtc_fast_start);
|
||||
|
||||
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
|
||||
"RTC_SLOW segment data does not fit.")
|
||||
|
||||
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
|
||||
"RTC_FAST segment data does not fit.")
|
||||
|
||||
.iram0.text :
|
||||
{
|
||||
_iram_start = ABSOLUTE(.);
|
||||
/* Vectors go to start of IRAM */
|
||||
ASSERT(ABSOLUTE(.) % 0x100 == 0, "vector address must be 256 byte aligned");
|
||||
KEEP(*(.exception_vectors_table.text));
|
||||
KEEP(*(.exception_vectors.text));
|
||||
. = ALIGN(4);
|
||||
|
||||
_invalid_pc_placeholder = ABSOLUTE(.);
|
||||
|
||||
/* Code marked as running out of IRAM */
|
||||
_iram_text_start = ABSOLUTE(.);
|
||||
|
||||
mapping[iram0_text]
|
||||
|
||||
} > iram0_0_seg
|
||||
|
||||
/* Marks the end of IRAM code segment */
|
||||
.iram0.text_end (NOLOAD) :
|
||||
{
|
||||
/* ESP32-C5 memprot requires 16B padding for possible CPU prefetch and 512B alignment for PMS split lines */
|
||||
. += _esp_memprot_prefetch_pad_size;
|
||||
. = ALIGN(_esp_memprot_align_size);
|
||||
/* iram_end_test section exists for use by memprot unit tests only */
|
||||
*(.iram_end_test)
|
||||
_iram_text_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
.iram0.data :
|
||||
{
|
||||
. = ALIGN(16);
|
||||
_iram_data_start = ABSOLUTE(.);
|
||||
|
||||
mapping[iram0_data]
|
||||
|
||||
_iram_data_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
.iram0.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(16);
|
||||
_iram_bss_start = ABSOLUTE(.);
|
||||
|
||||
mapping[iram0_bss]
|
||||
|
||||
_iram_bss_end = ABSOLUTE(.);
|
||||
. = ALIGN(16);
|
||||
_iram_end = ABSOLUTE(.);
|
||||
} > iram0_0_seg
|
||||
|
||||
/**
|
||||
* This section is required to skip .iram0.text area because iram0_0_seg and
|
||||
* dram0_0_seg reflect the same address space on different buses.
|
||||
*/
|
||||
.dram0.dummy (NOLOAD):
|
||||
{
|
||||
. = ORIGIN(dram0_0_seg) + _iram_end - _iram_start;
|
||||
} > dram0_0_seg
|
||||
|
||||
.dram0.data :
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
__global_pointer$ = . + 0x800;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
|
||||
mapping[dram0_data]
|
||||
|
||||
_data_end = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
} > dram0_0_seg
|
||||
|
||||
/**
|
||||
* This section holds data that should not be initialized at power up.
|
||||
* The section located in Internal SRAM memory region. The macro _NOINIT
|
||||
* can be used as attribute to place data into this section.
|
||||
* See the "esp_attr.h" file for more information.
|
||||
*/
|
||||
.noinit (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_noinit_start = ABSOLUTE(.);
|
||||
*(.noinit .noinit.*)
|
||||
. = ALIGN(4) ;
|
||||
_noinit_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
/* Shared RAM */
|
||||
.dram0.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
|
||||
/* ldgen places all bss-related data to mapping[dram0_bss] (See esp_system/app.lf). */
|
||||
mapping[dram0_bss]
|
||||
|
||||
. = ALIGN(4);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
|
||||
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)), "DRAM segment data does not fit.")
|
||||
|
||||
.flash.text :
|
||||
{
|
||||
_stext = .;
|
||||
_instruction_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.text start, this can be used for mmu driver to maintain virtual address */
|
||||
_text_start = ABSOLUTE(.);
|
||||
|
||||
mapping[flash_text]
|
||||
|
||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
|
||||
/** CPU will try to prefetch up to 16 bytes of
|
||||
* of instructions. This means that any configuration (e.g. MMU, PMS) must allow
|
||||
* safe access to up to 16 bytes after the last real instruction, add
|
||||
* dummy bytes to ensure this
|
||||
*/
|
||||
. += _esp_flash_mmap_prefetch_pad_size;
|
||||
|
||||
_text_end = ABSOLUTE(.);
|
||||
_instruction_reserved_end = ABSOLUTE(.); /* This is a symbol marking the flash.text end, this can be used for mmu driver to maintain virtual address */
|
||||
_etext = .;
|
||||
|
||||
/**
|
||||
* Similar to _iram_start, this symbol goes here so it is
|
||||
* resolved by addr2line in preference to the first symbol in
|
||||
* the flash.text segment.
|
||||
*/
|
||||
_flash_cache_start = ABSOLUTE(0);
|
||||
} > default_code_seg
|
||||
|
||||
/**
|
||||
* This dummy section represents the .flash.text section but in default_rodata_seg.
|
||||
* Thus, it must have its alignment and (at least) its size.
|
||||
*/
|
||||
.flash_rodata_dummy (NOLOAD):
|
||||
{
|
||||
_flash_rodata_dummy_start = .;
|
||||
/* Start at the same alignment constraint than .flash.text */
|
||||
. = ALIGN(ALIGNOF(.flash.text));
|
||||
/* Create an empty gap as big as .flash.text section */
|
||||
. = . + SIZEOF(.flash.text);
|
||||
/* Prepare the alignment of the section above. Few bytes (0x20) must be
|
||||
* added for the mapping header. */
|
||||
. = ALIGN(_esp_mmu_block_size) + 0x20;
|
||||
} > default_rodata_seg
|
||||
|
||||
.flash.appdesc : ALIGN(0x10)
|
||||
{
|
||||
_rodata_reserved_start = ABSOLUTE(.); /* This is a symbol marking the flash.rodata start, this can be used for mmu driver to maintain virtual address */
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
|
||||
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
|
||||
|
||||
/* Create an empty gap within this section. Thanks to this, the end of this
|
||||
* section will match .flash.rodata's begin address. Thus, both sections
|
||||
* will be merged when creating the final bin image. */
|
||||
. = ALIGN(ALIGNOF(.flash.rodata));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.appdesc, .flash.rodata)
|
||||
|
||||
.flash.rodata : ALIGN(0x10)
|
||||
{
|
||||
_flash_rodata_start = ABSOLUTE(.);
|
||||
|
||||
mapping[flash_rodata]
|
||||
|
||||
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
. = (. + 7) & ~ 3;
|
||||
/*
|
||||
* C++ constructor and destructor tables
|
||||
* Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt.
|
||||
*
|
||||
* RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead.
|
||||
* But the init_priority sections will be sorted for iteration in ascending order during startup.
|
||||
* The rest of the init_array sections is sorted for iteration in descending order during startup, however.
|
||||
* Hence a different section is generated for the init_priority functions which is iterated in
|
||||
* ascending order during startup. The corresponding code can be found in startup.c.
|
||||
*/
|
||||
__init_priority_array_start = ABSOLUTE(.);
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
|
||||
__init_priority_array_end = ABSOLUTE(.);
|
||||
__init_array_start = ABSOLUTE(.);
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.*(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
/* Addresses of memory regions reserved via SOC_RESERVE_MEMORY_REGION() */
|
||||
soc_reserved_memory_region_start = ABSOLUTE(.);
|
||||
KEEP (*(.reserved_memory_address))
|
||||
soc_reserved_memory_region_end = ABSOLUTE(.);
|
||||
/* System init functions registered via ESP_SYSTEM_INIT_FN */
|
||||
_esp_system_init_fn_array_start = ABSOLUTE(.);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.esp_system_init_fn.*)))
|
||||
_esp_system_init_fn_array_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
/* Literals are also RO data. */
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
. = ALIGN(ALIGNOF(.flash.tls));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.rodata, .flash.tls)
|
||||
|
||||
.flash.tls : ALIGN(8)
|
||||
{
|
||||
_thread_local_start = ABSOLUTE(.);
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
_thread_local_end = ABSOLUTE(.);
|
||||
. = ALIGN(ALIGNOF(.eh_frame));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.flash.tls, .eh_frame)
|
||||
|
||||
/* Keep this section shall be at least aligned on 4 */
|
||||
.eh_frame : ALIGN(8)
|
||||
{
|
||||
__eh_frame = ABSOLUTE(.);
|
||||
KEEP (*(.eh_frame))
|
||||
__eh_frame_end = ABSOLUTE(.);
|
||||
/* Guarantee that this section and the next one will be merged by making
|
||||
* them adjacent. */
|
||||
. = ALIGN(ALIGNOF(.eh_frame_hdr));
|
||||
} > default_rodata_seg
|
||||
ASSERT_SECTIONS_GAP(.eh_frame, .eh_frame_hdr)
|
||||
|
||||
/* To avoid any exception in C++ exception frame unwinding code, this section
|
||||
* shall be aligned on 8. */
|
||||
.eh_frame_hdr : ALIGN(8)
|
||||
{
|
||||
__eh_frame_hdr = ABSOLUTE(.);
|
||||
KEEP (*(.eh_frame_hdr))
|
||||
__eh_frame_hdr_end = ABSOLUTE(.);
|
||||
} > default_rodata_seg
|
||||
|
||||
/*
|
||||
This section is a place where we dump all the rodata which aren't used at runtime,
|
||||
so as to avoid binary size increase
|
||||
*/
|
||||
.flash.rodata_noload (NOLOAD) :
|
||||
{
|
||||
/*
|
||||
This is a symbol marking the flash.rodata end, this can be used for mmu driver to maintain virtual address
|
||||
We don't need to include the noload rodata in this section
|
||||
*/
|
||||
_rodata_reserved_end = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
mapping[rodata_noload]
|
||||
} > default_rodata_seg
|
||||
|
||||
/* Marks the end of data, bss and possibly rodata */
|
||||
.dram0.heap_start (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
_heap_start = ABSOLUTE(.);
|
||||
} > dram0_0_seg
|
||||
}
|
||||
|
||||
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
|
||||
"IRAM0 segment data does not fit.")
|
||||
|
||||
ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
|
||||
"DRAM segment data does not fit.")
|
@ -15,18 +15,24 @@
|
||||
#include "esp32c5/rom/ets_sys.h"
|
||||
#include "esp32c5/rom/uart.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#endif
|
||||
#include "esp_private/esp_modem_clock.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
#include "ocode_init.h"
|
||||
#endif
|
||||
|
||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
||||
* Larger values increase startup delay. Smaller values may cause false positive
|
||||
@ -43,16 +49,30 @@ static const char *TAG = "clk";
|
||||
// TODO: [ESP32C5] IDF-8642
|
||||
__attribute__((weak)) void esp_clk_init(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#if SOC_PMU_SUPPORTED
|
||||
pmu_init();
|
||||
#endif
|
||||
|
||||
assert((rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_40M) || (rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_48M));
|
||||
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
modem_lpcon_ll_set_pwr_tick_target(&MODEM_LPCON, rtc_clk_xtal_freq_get() - 1);
|
||||
#endif
|
||||
rtc_clk_8m_enable(true);
|
||||
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
pmu_init();
|
||||
if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
||||
esp_ocode_calib_init();
|
||||
}
|
||||
|
||||
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
|
||||
|
||||
rtc_clk_8m_enable(true);
|
||||
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
||||
@ -76,7 +96,11 @@ __attribute__((weak)) void esp_clk_init(void)
|
||||
#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
|
||||
#else
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
abort();
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||
@ -141,7 +165,7 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 32 kHz oscillator");
|
||||
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K;
|
||||
#else
|
||||
@ -182,7 +206,10 @@ void rtc_clk_select_rtc_slow_clk(void)
|
||||
*/
|
||||
__attribute__((weak)) void esp_perip_clk_init(void)
|
||||
{
|
||||
#if 0 // TODO: [ESP32C5] IDF-8844
|
||||
// TODO: [ESP32C5] IDF-8844
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
// modem_clock_domain_pmu_state_icg_map_init();
|
||||
#endif
|
||||
/* During system initialization, the low-power clock source of the modem
|
||||
* (WiFi, BLE or Coexist) follows the configuration of the slow clock source
|
||||
* of the system. If the WiFi, BLE or Coexist module needs a higher
|
||||
@ -190,15 +217,14 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
* oscillator (40 MHz) to provide the clock during the sleep process in some
|
||||
* scenarios), the module needs to switch to the required clock source by
|
||||
* itself. */ //TODO - WIFI-5233
|
||||
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(\
|
||||
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K \
|
||||
: (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? MODEM_CLOCK_LPCLK_SRC_RC32K \
|
||||
: (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K \
|
||||
: MODEM_CLOCK_LPCLK_SRC_RC32K);
|
||||
|
||||
modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0);
|
||||
#endif
|
||||
// soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||
// modem_clock_lpclk_src_t modem_lpclk_src = (modem_clock_lpclk_src_t)(
|
||||
// (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_RC_SLOW
|
||||
// : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? MODEM_CLOCK_LPCLK_SRC_XTAL32K
|
||||
// : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) ? MODEM_CLOCK_LPCLK_SRC_RC32K
|
||||
// : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K
|
||||
// : SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
|
||||
// modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0);
|
||||
|
||||
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
|
||||
#if 0 // TODO: [ESP32C5] IDF-8844
|
||||
@ -292,7 +318,11 @@ __attribute__((weak)) void esp_perip_clk_init(void)
|
||||
|
||||
/* Set WiFi light sleep clock source to RTC slow clock */
|
||||
REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0);
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M);
|
||||
#endif
|
||||
SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW);
|
||||
|
||||
/* Enable RNG clock. */
|
||||
|
@ -13,16 +13,21 @@
|
||||
#include "esp_rom_sys.h"
|
||||
#include "riscv/rv_utils.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_private/rtc_clk.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#endif
|
||||
#include "hal/wdt_hal.h"
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
#include "hal/modem_syscon_ll.h"
|
||||
#include "hal/modem_lpcon_ll.h"
|
||||
#endif
|
||||
#include "esp_private/cache_err_int.h"
|
||||
|
||||
#include "esp32c5/rom/cache.h"
|
||||
@ -35,32 +40,48 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void)
|
||||
esp_rom_output_tx_wait_idle(0);
|
||||
esp_rom_output_tx_wait_idle(1);
|
||||
|
||||
// TODO: IDF-8845
|
||||
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||
modem_syscon_ll_reset_all(&MODEM_SYSCON);
|
||||
modem_lpcon_ll_reset_all(&MODEM_LPCON);
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
// Set SPI Flash Freq to 40M
|
||||
clk_ll_mspi_fast_set_src(MSPI_CLK_SRC_XTAL);
|
||||
clk_ll_mspi_fast_set_divider(1);
|
||||
|
||||
// Set Peripheral clk rst
|
||||
SET_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
#endif
|
||||
// Set Peripheral clk rst
|
||||
SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN);
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN);
|
||||
|
||||
// Clear Peripheral clk rst
|
||||
CLEAR_PERI_REG_MASK(PCR_MSPI_CLK_CONF_REG, PCR_MSPI_AXI_RST_EN);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN);
|
||||
SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN);
|
||||
#endif
|
||||
// Clear Peripheral clk rst
|
||||
CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN);
|
||||
CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN);
|
||||
CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN);
|
||||
CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN);
|
||||
CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN);
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN);
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
// CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN);
|
||||
#endif
|
||||
CLEAR_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN);
|
||||
CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN);
|
||||
}
|
||||
@ -98,7 +119,11 @@ void IRAM_ATTR esp_restart_noos(void)
|
||||
wdt_hal_write_protect_enable(&wdt1_context);
|
||||
|
||||
// Disable cache
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
Cache_Disable_ICache();
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
Cache_Disable_Cache();
|
||||
#endif
|
||||
|
||||
// Reset wifi/bluetooth/ethernet/sdio (bb/mac)
|
||||
// Moved to module internal
|
||||
|
@ -665,8 +665,11 @@ static inline void __attribute__((always_inline)) vPortExitCriticalSafe(portMUX_
|
||||
|
||||
FORCE_INLINE_ATTR bool xPortCanYield(void)
|
||||
{
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
// TODO: [ESP32C5] IDF-8655 simplify the code for c5 mp
|
||||
#if !CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
/* When CLIC is supported:
|
||||
* - The lowest interrupt threshold level is 0. Therefore, an interrupt threshold level above 0 would mean that we
|
||||
* are in a critical section.
|
||||
@ -679,12 +682,22 @@ FORCE_INLINE_ATTR bool xPortCanYield(void)
|
||||
threshold = threshold >> (CLIC_CPU_INT_THRESH_S + (8 - NLBITS));
|
||||
|
||||
return ((intr_level == 0) && (threshold == 0));
|
||||
#endif /* SOC_INT_CLIC_SUPPORTED */
|
||||
#else
|
||||
#define MINTSTATUS 0xfb1
|
||||
#define MINTTHRESH 0x347
|
||||
uint32_t threshold1 = (RV_READ_CSR(MINTTHRESH)) >> (8 - NLBITS);
|
||||
uint32_t threshold2 = (RV_READ_CSR(MINTSTATUS)) >> (24 + (8 - NLBITS));
|
||||
return (threshold1 == 0) && (threshold2 == 0) ;
|
||||
#endif
|
||||
|
||||
#else/* !SOC_INT_CLIC_SUPPORTED */
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
|
||||
* and exit critical code, will recover threshold value (1). so threshold <= 1
|
||||
* means not in critical code
|
||||
*/
|
||||
return (threshold <= 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user