mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
Merge branch 'feat/support_esp32h4_top' into 'master'
Support cpu & modem & top domain and minimum system peripherals retention in esp32h4 beta5 Closes PM-449, PM-484, PM-448, PM-451, PM-497, IDF-12283, and IDF-12286 See merge request espressif/esp-idf!40605
This commit is contained in:
@@ -97,10 +97,10 @@ static void * cache_sleep_frame_init(void)
|
|||||||
static void * clint_sleep_frame_init(void)
|
static void * clint_sleep_frame_init(void)
|
||||||
{
|
{
|
||||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||||
{ .start = CLINT_MINT_SIP_REG, .end = CLINT_MINT_SIP_REG + 4 },
|
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 },
|
||||||
{ .start = CLINT_MINT_MTIMECMP_L_REG, .end = CLINT_MINT_MTIMECMP_H_REG + 4 },
|
{ .start = CPU_DOMAIN_DEV_START_ADDR1, .end = CPU_DOMAIN_DEV_END_ADDR1 },
|
||||||
{ .start = CLINT_MINT_TIMECTL_REG, .end = CLINT_MINT_TIMECTL_REG + 4 },
|
{ .start = CPU_DOMAIN_DEV_START_ADDR2, .end = CPU_DOMAIN_DEV_END_ADDR2 },
|
||||||
{ .start = CLINT_MINT_MTIME_L_REG, .end = CLINT_MINT_MTIME_H_REG + 4 }
|
{ .start = CPU_DOMAIN_DEV_START_ADDR3, .end = CPU_DOMAIN_DEV_END_ADDR3 }
|
||||||
};
|
};
|
||||||
static uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(4)] __attribute__((aligned(4)));
|
static uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(4)] __attribute__((aligned(4)));
|
||||||
return cpu_domain_dev_sleep_frame_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
return cpu_domain_dev_sleep_frame_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
||||||
|
212
components/esp_hw_support/lowpower/port/esp32h4/rvsleep-frames.h
Normal file
212
components/esp_hw_support/lowpower/port/esp32h4/rvsleep-frames.h
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RVSLEEP_FRAMES_H__
|
||||||
|
#define __RVSLEEP_FRAMES_H__
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
|
||||||
|
#define ALIGNUP(n, val) (((val) + (n) - 1) & -(n))
|
||||||
|
|
||||||
|
#ifdef STRUCT_BEGIN
|
||||||
|
#undef STRUCT_BEGIN
|
||||||
|
#undef STRUCT_FIELD
|
||||||
|
#undef STRUCT_AFIELD
|
||||||
|
#undef STRUCT_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||||
|
#ifdef __clang__
|
||||||
|
#define STRUCT_BEGIN .set RV_STRUCT_OFFSET, 0
|
||||||
|
#define STRUCT_FIELD(ctype,size,asname,name) .set asname, RV_STRUCT_OFFSET; .set RV_STRUCT_OFFSET, asname + size
|
||||||
|
#define STRUCT_AFIELD(ctype,size,asname,name,n) .set asname, RV_STRUCT_OFFSET;\
|
||||||
|
.set RV_STRUCT_OFFSET, asname + (size)*(n);
|
||||||
|
#define STRUCT_END(sname) .set sname##Size, RV_STRUCT_OFFSET;
|
||||||
|
#else // __clang__
|
||||||
|
#define STRUCT_BEGIN .pushsection .text; .struct 0
|
||||||
|
#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
|
||||||
|
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
|
||||||
|
#define STRUCT_END(sname) sname##Size:; .popsection
|
||||||
|
#endif // __clang__
|
||||||
|
#else
|
||||||
|
#define STRUCT_BEGIN typedef struct {
|
||||||
|
#define STRUCT_FIELD(ctype,size,asname,name) ctype name;
|
||||||
|
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
|
||||||
|
#define STRUCT_END(sname) } sname;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------------
|
||||||
|
* RISC-V CORE CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP
|
||||||
|
* -------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
STRUCT_BEGIN
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MEPC, mepc) /* Machine Exception Program Counter */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_RA, ra) /* Return address */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_SP, sp) /* Stack pointer */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_GP, gp) /* Global pointer */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TP, tp) /* Thread pointer */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T0, t0) /* Temporary/alternate link register */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T1, t1) /* t1-2: Temporaries */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T2, t2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S0, s0) /* Saved register/frame pointer */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S1, s1) /* Saved register */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A0, a0) /* a0-1: Function arguments/return address */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A1, a1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A2, a2) /* a2-7: Function arguments */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A3, a3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A4, a4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A5, a5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A6, a6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_A7, a7)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S2, s2) /* s2-11: Saved registers */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S3, s3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S4, s4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S5, s5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S6, s6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S7, s7)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S8, s8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S9, s9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S10, s10)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_S11, s11)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T3, t3) /* t3-6: Temporaries */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T4, t4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T5, t5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_T6, t6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MSTATUS, mstatus) /* Machine Status */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVEC, mtvec) /* Machine Trap-Vector Base Address */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCAUSE, mcause) /* Machine Trap Cause */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */
|
||||||
|
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going
|
||||||
|
* to sleep or has just been awakened. We use the
|
||||||
|
* lowest 2 bits as indication information, 3 means
|
||||||
|
* being awakened, 1 means going to sleep */
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CSF_CTX_CRC, frame_crc) /* Used to check RvCoreCriticalSleepFrame integrity */
|
||||||
|
#endif
|
||||||
|
STRUCT_END(RvCoreCriticalSleepFrame)
|
||||||
|
|
||||||
|
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||||
|
#define RV_SLEEP_CTX_SZ1 RvCoreCriticalSleepFrameSize
|
||||||
|
#else
|
||||||
|
#define RV_SLEEP_CTX_SZ1 sizeof(RvCoreCriticalSleepFrame)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sleep stack frame size, after align up to 16 bytes boundary
|
||||||
|
*/
|
||||||
|
#define RV_SLEEP_CTX_FRMSZ (ALIGNUP(0x10, RV_SLEEP_CTX_SZ1))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------------
|
||||||
|
* RISC-V CORE NON-CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP
|
||||||
|
* -------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
STRUCT_BEGIN
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCH, mscratch)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MISA, misa)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCHCSW, mscratchcsw)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCHCSW1, mscratchcsw1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLEH, mcycleh)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINSTRET, minstret)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINSTRETH, minstreth)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCOUNTEREN, mcounteren)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCOUNTINHIBIT, mcountinhibit)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER8, mhpmcounter8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER9, mhpmcounter9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER13, mhpmcounter13)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER8H, mhpmcounter8h)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER9H, mhpmcounter9h)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMCOUNTER13H, mhpmcounter13h)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT8, mhpmevent8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT9, mhpmevent9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHPMEVENT13, mhpmevent13)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCONTEXT, mcontext)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_USTATUS, ustatus)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_UTVEC, utvec)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_USCRATCH, uscratch)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_UCAUSE, ucause)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_UINTTHRESH, uintthresh)
|
||||||
|
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TSELECT, tselect)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA1, tdata1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA2, tdata2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA3, tdata3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_TCONTROL, tcontrol)
|
||||||
|
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR0, pmpaddr0)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR1, pmpaddr1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR2, pmpaddr2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR3, pmpaddr3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR4, pmpaddr4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR5, pmpaddr5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR6, pmpaddr6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR7, pmpaddr7)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR8, pmpaddr8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR9, pmpaddr9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR10, pmpaddr10)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR11, pmpaddr11)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR12, pmpaddr12)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR13, pmpaddr13)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR14, pmpaddr14)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR15, pmpaddr15)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG0, pmpcfg0)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG1, pmpcfg1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG2, pmpcfg2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG3, pmpcfg3)
|
||||||
|
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR0, pmaaddr0)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR1, pmaaddr1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR2, pmaaddr2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR3, pmaaddr3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR4, pmaaddr4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR5, pmaaddr5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR6, pmaaddr6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR7, pmaaddr7)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR8, pmaaddr8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR9, pmaaddr9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR10, pmaaddr10)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR11, pmaaddr11)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR12, pmaaddr12)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR13, pmaaddr13)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR14, pmaaddr14)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMAADDR15, pmaaddr15)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG0, pmacfg0)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG1, pmacfg1)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG2, pmacfg2)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG3, pmacfg3)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG4, pmacfg4)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG5, pmacfg5)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG6, pmacfg6)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG7, pmacfg7)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG8, pmacfg8)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG9, pmacfg9)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG10, pmacfg10)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG11, pmacfg11)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG12, pmacfg12)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG13, pmacfg13)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG14, pmacfg14)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_PMACFG15, pmacfg15)
|
||||||
|
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MCYCLE, mcycle)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVT, mtvt)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MINTTHRESH, mintthresh)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MXSTATUS, mxstatus)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHCR, mhcr)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MHINT, mhint)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_MEXSTATUS, mexstatus)
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_CTX_JVT, jvt)
|
||||||
|
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
STRUCT_FIELD (long, 4, RV_SLP_NCSF_CTX_CRC, frame_crc) /* Used to check RvCoreNonCriticalSleepFrame integrity */
|
||||||
|
#endif
|
||||||
|
STRUCT_END(RvCoreNonCriticalSleepFrame)
|
||||||
|
|
||||||
|
#endif /* #ifndef __RVSLEEP_FRAMES_H__ */
|
140
components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c
Normal file
140
components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "esp_private/sleep_clock.h"
|
||||||
|
#include "soc/pcr_reg.h"
|
||||||
|
#include "modem/modem_syscon_reg.h"
|
||||||
|
#include "modem/modem_lpcon_reg.h"
|
||||||
|
#include "soc/i2c_ana_mst_reg.h"
|
||||||
|
#include "soc/pmu_reg.h"
|
||||||
|
#include "soc/lp_analog_peri_reg.h"
|
||||||
|
|
||||||
|
static const char *TAG = "sleep_clock";
|
||||||
|
|
||||||
|
esp_err_t sleep_clock_system_retention_init(void *arg)
|
||||||
|
{
|
||||||
|
#define N_REGS_PCR() (((PCR_ZERO_DET_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1)
|
||||||
|
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
|
||||||
|
/* Clock configuration retention */
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(1), PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(2), PCR_BUS_CLK_UPDATE_REG, PCR_BUS_CLOCK_UPDATE, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[3] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(3), PCR_BUS_CLK_UPDATE_REG, 0x0, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
|
||||||
|
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention");
|
||||||
|
ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization");
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
#undef N_REGS_PCR
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
esp_err_t sleep_clock_modem_retention_init(void *arg)
|
||||||
|
{
|
||||||
|
#define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1)
|
||||||
|
#define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1)
|
||||||
|
|
||||||
|
/* In ESP32H4, the I2C control registers (syscon, lpcon) are placed in the modem domain,
|
||||||
|
and the BBPL requires I2C for calibration. This is the reason why the code for the BPLL enableq
|
||||||
|
section needs to be placed in this function.*/
|
||||||
|
const static sleep_retention_entries_config_t modem_regs_retention[] = {
|
||||||
|
/* SYSCON LPCON configuration retention */
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK (0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM LPCON */
|
||||||
|
/* Enable i2c master clock */
|
||||||
|
[2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(1), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = ENTRY(0) },
|
||||||
|
/* Start BBPLL self-calibration */
|
||||||
|
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(2), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) },
|
||||||
|
[4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(3), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) },
|
||||||
|
/* Wait calibration done */
|
||||||
|
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_MODEMSYSCON_LINK(4), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE, I2C_MST_BBPLL_CAL_DONE, 1, 0), .owner = ENTRY(0) },
|
||||||
|
/* Stop BBPLL self-calibration */
|
||||||
|
[6] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(5), I2C_ANA_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_LOW, 1, 0), .owner = ENTRY(0) },
|
||||||
|
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(6), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) },
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM);
|
||||||
|
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority");
|
||||||
|
ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization");
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
#undef N_REGS_LPCON
|
||||||
|
#undef N_REGS_SYSCON
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool clock_domain_pd_allowed(void)
|
||||||
|
{
|
||||||
|
const sleep_retention_module_bitmap_t inited_modules = sleep_retention_get_inited_modules();
|
||||||
|
const sleep_retention_module_bitmap_t created_modules = sleep_retention_get_created_modules();
|
||||||
|
const sleep_retention_module_bitmap_t sys_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap[SLEEP_RETENTION_MODULE_SYS_PERIPH >> 5] = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH % 32) };
|
||||||
|
|
||||||
|
/* The clock and reset of MODEM (BLE and 15.4) modules are managed
|
||||||
|
* through MODEM_SYSCON, when one or more MODEMs are initialized, it is
|
||||||
|
* necessary to check the state of CLOCK_MODEM to determine MODEM domain on
|
||||||
|
* or off. The clock and reset of digital peripherals are managed through
|
||||||
|
* PCR, with TOP domain similar to MODEM domain. */
|
||||||
|
#if SOC_BLE_SUPPORTED || SOC_IEEE802154_SUPPORTED
|
||||||
|
sleep_retention_module_bitmap_t modem_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } };
|
||||||
|
#endif
|
||||||
|
#if SOC_BT_SUPPORTED
|
||||||
|
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BLE_MAC >> 5] |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC % 32);
|
||||||
|
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BT_BB >> 5] |= BIT(SLEEP_RETENTION_MODULE_BT_BB % 32);
|
||||||
|
#endif
|
||||||
|
#if SOC_IEEE802154_SUPPORTED
|
||||||
|
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_802154_MAC >> 5] |= BIT(SLEEP_RETENTION_MODULE_802154_MAC % 32);
|
||||||
|
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BT_BB >> 5] |= BIT(SLEEP_RETENTION_MODULE_BT_BB % 32);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const sleep_retention_module_bitmap_t null_module = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } };
|
||||||
|
|
||||||
|
sleep_retention_module_bitmap_t mask = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } };
|
||||||
|
const sleep_retention_module_bitmap_t system_modules = sleep_retention_module_bitmap_and(inited_modules, sys_clk_dep_modules);
|
||||||
|
if (!sleep_retention_module_bitmap_eq(system_modules, null_module)) {
|
||||||
|
mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM % 32);
|
||||||
|
}
|
||||||
|
#if SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED
|
||||||
|
const sleep_retention_module_bitmap_t modem_modules = sleep_retention_module_bitmap_and(inited_modules, modem_clk_dep_modules);
|
||||||
|
if (!sleep_retention_module_bitmap_eq(modem_modules, null_module)) {
|
||||||
|
mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
mask.bitmap[SLEEP_RETENTION_MODULE_CLOCK_MODEM >> 5] |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM % 32);
|
||||||
|
#endif
|
||||||
|
const sleep_retention_module_bitmap_t clock_domain_inited_modules = sleep_retention_module_bitmap_and(inited_modules, mask);
|
||||||
|
const sleep_retention_module_bitmap_t clock_domain_created_modules = sleep_retention_module_bitmap_and(created_modules, mask);
|
||||||
|
return sleep_retention_module_bitmap_eq(clock_domain_inited_modules, clock_domain_created_modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, SECONDARY, BIT(0), 106)
|
||||||
|
{
|
||||||
|
sleep_retention_module_init_param_t init_param = {
|
||||||
|
.cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } },
|
||||||
|
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
|
||||||
|
};
|
||||||
|
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param);
|
||||||
|
|
||||||
|
#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE || SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
init_param = (sleep_retention_module_init_param_t) {
|
||||||
|
.cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } },
|
||||||
|
#if !SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
.attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param);
|
||||||
|
#endif
|
||||||
|
#if SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
if (sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_CLOCK_MODEM) != ESP_OK) {
|
||||||
|
// even though the modem clock retention module create failed, sleep process can be executed without pd the modem domain, so just warning here
|
||||||
|
ESP_LOGW(TAG, "create retention link failed on modem clock, modem power domain won't be turned off during sleep");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
556
components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c
Normal file
556
components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu.c
Normal file
@@ -0,0 +1,556 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include "esp_attr.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_ipc_isr.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_rom_crc.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "riscv/csr.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "soc/intpri_reg.h"
|
||||||
|
#include "soc/cache_reg.h"
|
||||||
|
#include "soc/clint_reg.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
#include "soc/pcr_reg.h"
|
||||||
|
#include "soc/rtc_periph.h"
|
||||||
|
#include "esp_private/esp_pmu.h"
|
||||||
|
#include "esp_private/sleep_cpu.h"
|
||||||
|
#include "esp_private/sleep_event.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "esp32h4/rom/rtc.h"
|
||||||
|
#include "esp32h4/rom/cache.h"
|
||||||
|
#include "rvsleep-frames.h"
|
||||||
|
#include "sleep_cpu_retention.h"
|
||||||
|
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
#include "esp_private/system_internal.h"
|
||||||
|
#include "hal/uart_hal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
static DRAM_ATTR smp_retention_state_t s_smp_retention_state[portNUM_PROCESSORS];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static __attribute__((unused)) const char *TAG = "sleep";
|
||||||
|
|
||||||
|
static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention;
|
||||||
|
|
||||||
|
#define CUSTOM_CSR_MTVT (0x307)
|
||||||
|
#define CUSTOM_CSR_MNXTI (0x345)
|
||||||
|
#define CUSTOM_CSR_MINTTHRESH (0x347)
|
||||||
|
#define CUSTOM_CSR_MSCRATCHCSW (0x348)
|
||||||
|
#define CUSTOM_CSR_MSCRATCHCSW1 (0x349)
|
||||||
|
#define CUSTOM_CSR_UINTTHRESH (0x047)
|
||||||
|
#define CUSTOM_CSR_UINTSTATUS (0xCB1)
|
||||||
|
#define CUSTOM_CSR_MXSTATUS (0x7c0)
|
||||||
|
#define CUSTOM_CSR_MHCR (0x7c1)
|
||||||
|
#define CUSTOM_CSR_MHINT (0x7c5)
|
||||||
|
#define CUSTOM_CSR_MEXSTATUS (0x7e1)
|
||||||
|
#define CUSTOM_CSR_JVT (0x017)
|
||||||
|
|
||||||
|
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS];
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR uint32_t save_mstatus_and_disable_global_int(void)
|
||||||
|
{
|
||||||
|
return RV_READ_MSTATUS_AND_DISABLE_INTR();
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void restore_mstatus(uint32_t mstatus_val)
|
||||||
|
{
|
||||||
|
RV_WRITE_CSR(mstatus, mstatus_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void)
|
||||||
|
{
|
||||||
|
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()];
|
||||||
|
|
||||||
|
frame->mscratch = RV_READ_CSR(mscratch);
|
||||||
|
frame->misa = RV_READ_CSR(misa);
|
||||||
|
frame->tselect = RV_READ_CSR(tselect);
|
||||||
|
frame->tdata1 = RV_READ_CSR(tdata1);
|
||||||
|
frame->tdata2 = RV_READ_CSR(tdata2);
|
||||||
|
frame->tdata3 = RV_READ_CSR(tdata3);
|
||||||
|
frame->tcontrol = RV_READ_CSR(tcontrol);
|
||||||
|
frame->mscratchcsw = RV_READ_CSR(CUSTOM_CSR_MSCRATCHCSW);
|
||||||
|
frame->mscratchcsw1 = RV_READ_CSR(CUSTOM_CSR_MSCRATCHCSW1);
|
||||||
|
frame->mcycleh = RV_READ_CSR(mcycleh);
|
||||||
|
frame->minstret = RV_READ_CSR(minstret);
|
||||||
|
frame->minstreth = RV_READ_CSR(minstreth);
|
||||||
|
frame->mcounteren = RV_READ_CSR(mcounteren);
|
||||||
|
frame->mcountinhibit = RV_READ_CSR(mcountinhibit);
|
||||||
|
frame->mhpmcounter8 = RV_READ_CSR(mhpmcounter8);
|
||||||
|
frame->mhpmcounter9 = RV_READ_CSR(mhpmcounter9);
|
||||||
|
frame->mhpmcounter13 = RV_READ_CSR(mhpmcounter13);
|
||||||
|
frame->mhpmcounter8h = RV_READ_CSR(mhpmcounter8h);
|
||||||
|
frame->mhpmcounter9h = RV_READ_CSR(mhpmcounter9h);
|
||||||
|
frame->mhpmcounter13h = RV_READ_CSR(mhpmcounter13h);
|
||||||
|
frame->mhpmevent8 = RV_READ_CSR(mhpmevent8);
|
||||||
|
frame->mhpmevent9 = RV_READ_CSR(mhpmevent9);
|
||||||
|
frame->mhpmevent13 = RV_READ_CSR(mhpmevent13);
|
||||||
|
frame->mcontext = RV_READ_CSR(mcontext);
|
||||||
|
frame->ustatus = RV_READ_CSR(ustatus);
|
||||||
|
frame->utvec = RV_READ_CSR(utvec);
|
||||||
|
frame->uscratch = RV_READ_CSR(uscratch);
|
||||||
|
frame->ucause = RV_READ_CSR(ucause);
|
||||||
|
frame->uintthresh = RV_READ_CSR(CUSTOM_CSR_UINTTHRESH);
|
||||||
|
|
||||||
|
frame->pmpaddr0 = RV_READ_CSR(pmpaddr0);
|
||||||
|
frame->pmpaddr1 = RV_READ_CSR(pmpaddr1);
|
||||||
|
frame->pmpaddr2 = RV_READ_CSR(pmpaddr2);
|
||||||
|
frame->pmpaddr3 = RV_READ_CSR(pmpaddr3);
|
||||||
|
frame->pmpaddr4 = RV_READ_CSR(pmpaddr4);
|
||||||
|
frame->pmpaddr5 = RV_READ_CSR(pmpaddr5);
|
||||||
|
frame->pmpaddr6 = RV_READ_CSR(pmpaddr6);
|
||||||
|
frame->pmpaddr7 = RV_READ_CSR(pmpaddr7);
|
||||||
|
frame->pmpaddr8 = RV_READ_CSR(pmpaddr8);
|
||||||
|
frame->pmpaddr9 = RV_READ_CSR(pmpaddr9);
|
||||||
|
frame->pmpaddr10 = RV_READ_CSR(pmpaddr10);
|
||||||
|
frame->pmpaddr11 = RV_READ_CSR(pmpaddr11);
|
||||||
|
frame->pmpaddr12 = RV_READ_CSR(pmpaddr12);
|
||||||
|
frame->pmpaddr13 = RV_READ_CSR(pmpaddr13);
|
||||||
|
frame->pmpaddr14 = RV_READ_CSR(pmpaddr14);
|
||||||
|
frame->pmpaddr15 = RV_READ_CSR(pmpaddr15);
|
||||||
|
frame->pmpcfg0 = RV_READ_CSR(pmpcfg0);
|
||||||
|
frame->pmpcfg1 = RV_READ_CSR(pmpcfg1);
|
||||||
|
frame->pmpcfg2 = RV_READ_CSR(pmpcfg2);
|
||||||
|
frame->pmpcfg3 = RV_READ_CSR(pmpcfg3);
|
||||||
|
|
||||||
|
frame->pmaaddr0 = RV_READ_CSR(CSR_PMAADDR(0));
|
||||||
|
frame->pmaaddr1 = RV_READ_CSR(CSR_PMAADDR(1));
|
||||||
|
frame->pmaaddr2 = RV_READ_CSR(CSR_PMAADDR(2));
|
||||||
|
frame->pmaaddr3 = RV_READ_CSR(CSR_PMAADDR(3));
|
||||||
|
frame->pmaaddr4 = RV_READ_CSR(CSR_PMAADDR(4));
|
||||||
|
frame->pmaaddr5 = RV_READ_CSR(CSR_PMAADDR(5));
|
||||||
|
frame->pmaaddr6 = RV_READ_CSR(CSR_PMAADDR(6));
|
||||||
|
frame->pmaaddr7 = RV_READ_CSR(CSR_PMAADDR(7));
|
||||||
|
frame->pmaaddr8 = RV_READ_CSR(CSR_PMAADDR(8));
|
||||||
|
frame->pmaaddr9 = RV_READ_CSR(CSR_PMAADDR(9));
|
||||||
|
frame->pmaaddr10 = RV_READ_CSR(CSR_PMAADDR(10));
|
||||||
|
frame->pmaaddr11 = RV_READ_CSR(CSR_PMAADDR(11));
|
||||||
|
frame->pmaaddr12 = RV_READ_CSR(CSR_PMAADDR(12));
|
||||||
|
frame->pmaaddr13 = RV_READ_CSR(CSR_PMAADDR(13));
|
||||||
|
frame->pmaaddr14 = RV_READ_CSR(CSR_PMAADDR(14));
|
||||||
|
frame->pmaaddr15 = RV_READ_CSR(CSR_PMAADDR(15));
|
||||||
|
frame->pmacfg0 = RV_READ_CSR(CSR_PMACFG(0));
|
||||||
|
frame->pmacfg1 = RV_READ_CSR(CSR_PMACFG(1));
|
||||||
|
frame->pmacfg2 = RV_READ_CSR(CSR_PMACFG(2));
|
||||||
|
frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(3));
|
||||||
|
frame->pmacfg4 = RV_READ_CSR(CSR_PMACFG(4));
|
||||||
|
frame->pmacfg5 = RV_READ_CSR(CSR_PMACFG(5));
|
||||||
|
frame->pmacfg6 = RV_READ_CSR(CSR_PMACFG(6));
|
||||||
|
frame->pmacfg7 = RV_READ_CSR(CSR_PMACFG(7));
|
||||||
|
frame->pmacfg8 = RV_READ_CSR(CSR_PMACFG(8));
|
||||||
|
frame->pmacfg9 = RV_READ_CSR(CSR_PMACFG(9));
|
||||||
|
frame->pmacfg10 = RV_READ_CSR(CSR_PMACFG(10));
|
||||||
|
frame->pmacfg11 = RV_READ_CSR(CSR_PMACFG(11));
|
||||||
|
frame->pmacfg12 = RV_READ_CSR(CSR_PMACFG(12));
|
||||||
|
frame->pmacfg13 = RV_READ_CSR(CSR_PMACFG(13));
|
||||||
|
frame->pmacfg14 = RV_READ_CSR(CSR_PMACFG(14));
|
||||||
|
frame->pmacfg15 = RV_READ_CSR(CSR_PMACFG(15));
|
||||||
|
|
||||||
|
frame->mcycle = RV_READ_CSR(mcycle);
|
||||||
|
frame->mtvt = RV_READ_CSR(CUSTOM_CSR_MTVT);
|
||||||
|
frame->mintthresh = RV_READ_CSR(CUSTOM_CSR_MINTTHRESH);
|
||||||
|
frame->mxstatus = RV_READ_CSR(CUSTOM_CSR_MXSTATUS);
|
||||||
|
frame->mhcr = RV_READ_CSR(CUSTOM_CSR_MHCR);
|
||||||
|
frame->mhint = RV_READ_CSR(CUSTOM_CSR_MHINT);
|
||||||
|
frame->mexstatus = RV_READ_CSR(CUSTOM_CSR_MEXSTATUS);
|
||||||
|
frame->jvt = RV_READ_CSR(CUSTOM_CSR_JVT);
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRAM_ATTR void rv_core_noncritical_regs_restore(void)
|
||||||
|
{
|
||||||
|
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[esp_cpu_get_core_id()];
|
||||||
|
|
||||||
|
RV_WRITE_CSR(mscratch, frame->mscratch);
|
||||||
|
RV_WRITE_CSR(misa, frame->misa);
|
||||||
|
RV_WRITE_CSR(tselect, frame->tselect);
|
||||||
|
RV_WRITE_CSR(tdata1, frame->tdata1);
|
||||||
|
RV_WRITE_CSR(tdata2, frame->tdata2);
|
||||||
|
RV_WRITE_CSR(tdata3, frame->tdata3);
|
||||||
|
RV_WRITE_CSR(tcontrol, frame->tcontrol);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MSCRATCHCSW, frame->mscratchcsw);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MSCRATCHCSW1, frame->mscratchcsw1);
|
||||||
|
RV_WRITE_CSR(mcycleh, frame->mcycleh);
|
||||||
|
RV_WRITE_CSR(minstret, frame->minstret);
|
||||||
|
RV_WRITE_CSR(minstreth, frame->minstreth);
|
||||||
|
RV_WRITE_CSR(mcounteren, frame->mcounteren);
|
||||||
|
RV_WRITE_CSR(mcountinhibit, frame->mcountinhibit);
|
||||||
|
RV_WRITE_CSR(mhpmcounter8, frame->mhpmcounter8);
|
||||||
|
RV_WRITE_CSR(mhpmcounter9, frame->mhpmcounter9);
|
||||||
|
RV_WRITE_CSR(mhpmcounter13, frame->mhpmcounter13);
|
||||||
|
RV_WRITE_CSR(mhpmcounter8h, frame->mhpmcounter8h);
|
||||||
|
RV_WRITE_CSR(mhpmcounter9h, frame->mhpmcounter9h);
|
||||||
|
RV_WRITE_CSR(mhpmcounter13h, frame->mhpmcounter13h);
|
||||||
|
RV_WRITE_CSR(mhpmevent8, frame->mhpmevent8);
|
||||||
|
RV_WRITE_CSR(mhpmevent9, frame->mhpmevent9);
|
||||||
|
RV_WRITE_CSR(mhpmevent13, frame->mhpmevent13);
|
||||||
|
RV_WRITE_CSR(mcontext, frame->mcontext);
|
||||||
|
RV_WRITE_CSR(ustatus, frame->ustatus);
|
||||||
|
RV_WRITE_CSR(utvec, frame->utvec);
|
||||||
|
RV_WRITE_CSR(uscratch, frame->uscratch);
|
||||||
|
RV_WRITE_CSR(ucause, frame->ucause);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_UINTTHRESH, frame->uintthresh);
|
||||||
|
|
||||||
|
RV_WRITE_CSR(pmpaddr0, frame->pmpaddr0);
|
||||||
|
RV_WRITE_CSR(pmpaddr1, frame->pmpaddr1);
|
||||||
|
RV_WRITE_CSR(pmpaddr2, frame->pmpaddr2);
|
||||||
|
RV_WRITE_CSR(pmpaddr3, frame->pmpaddr3);
|
||||||
|
RV_WRITE_CSR(pmpaddr4, frame->pmpaddr4);
|
||||||
|
RV_WRITE_CSR(pmpaddr5, frame->pmpaddr5);
|
||||||
|
RV_WRITE_CSR(pmpaddr6, frame->pmpaddr6);
|
||||||
|
RV_WRITE_CSR(pmpaddr7, frame->pmpaddr7);
|
||||||
|
RV_WRITE_CSR(pmpaddr8, frame->pmpaddr8);
|
||||||
|
RV_WRITE_CSR(pmpaddr9, frame->pmpaddr9);
|
||||||
|
RV_WRITE_CSR(pmpaddr10,frame->pmpaddr10);
|
||||||
|
RV_WRITE_CSR(pmpaddr11,frame->pmpaddr11);
|
||||||
|
RV_WRITE_CSR(pmpaddr12,frame->pmpaddr12);
|
||||||
|
RV_WRITE_CSR(pmpaddr13,frame->pmpaddr13);
|
||||||
|
RV_WRITE_CSR(pmpaddr14,frame->pmpaddr14);
|
||||||
|
RV_WRITE_CSR(pmpaddr15,frame->pmpaddr15);
|
||||||
|
RV_WRITE_CSR(pmpcfg0, frame->pmpcfg0);
|
||||||
|
RV_WRITE_CSR(pmpcfg1, frame->pmpcfg1);
|
||||||
|
RV_WRITE_CSR(pmpcfg2, frame->pmpcfg2);
|
||||||
|
RV_WRITE_CSR(pmpcfg3, frame->pmpcfg3);
|
||||||
|
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(0), frame->pmaaddr0);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(1), frame->pmaaddr1);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(2), frame->pmaaddr2);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(3), frame->pmaaddr3);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(4), frame->pmaaddr4);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(5), frame->pmaaddr5);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(6), frame->pmaaddr6);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(7), frame->pmaaddr7);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(8), frame->pmaaddr8);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(9), frame->pmaaddr9);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(10),frame->pmaaddr10);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(11),frame->pmaaddr11);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(12),frame->pmaaddr12);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(13),frame->pmaaddr13);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(14),frame->pmaaddr14);
|
||||||
|
RV_WRITE_CSR(CSR_PMAADDR(15),frame->pmaaddr15);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(0), frame->pmacfg0);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(1), frame->pmacfg1);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(2), frame->pmacfg2);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(3), frame->pmacfg3);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(4), frame->pmacfg4);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(5), frame->pmacfg5);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(6), frame->pmacfg6);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(7), frame->pmacfg7);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(8), frame->pmacfg8);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(9), frame->pmacfg9);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(10), frame->pmacfg10);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(11), frame->pmacfg11);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(12), frame->pmacfg12);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(13), frame->pmacfg13);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(14), frame->pmacfg14);
|
||||||
|
RV_WRITE_CSR(CSR_PMACFG(15), frame->pmacfg15);
|
||||||
|
|
||||||
|
RV_WRITE_CSR(mcycle, frame->mcycle);
|
||||||
|
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MTVT, frame->mtvt);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MINTTHRESH, frame->mintthresh);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MXSTATUS, frame->mxstatus);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MHCR, frame->mhcr);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MHINT, frame->mhint);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_MEXSTATUS, frame->mexstatus);
|
||||||
|
RV_WRITE_CSR(CUSTOM_CSR_JVT, frame->jvt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame)
|
||||||
|
{
|
||||||
|
assert(frame);
|
||||||
|
cpu_domain_dev_regs_region_t *region = frame->region;
|
||||||
|
uint32_t *regs_frame = frame->regs_frame;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
for (int i = 0; i < frame->region_num; i++) {
|
||||||
|
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
||||||
|
regs_frame[offset++] = *(uint32_t *)addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame)
|
||||||
|
{
|
||||||
|
assert(frame);
|
||||||
|
cpu_domain_dev_regs_region_t *region = frame->region;
|
||||||
|
uint32_t *regs_frame = frame->regs_frame;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
for (int i = 0; i < frame->region_num; i++) {
|
||||||
|
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
||||||
|
*(uint32_t *)addr = regs_frame[offset++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
static IRAM_ATTR void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
|
||||||
|
{
|
||||||
|
*(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IRAM_ATTR void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr)
|
||||||
|
{
|
||||||
|
if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){
|
||||||
|
// resume uarts
|
||||||
|
for (int i = 0; i < SOC_UART_NUM; ++i) {
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||||
|
if (!uart_ll_is_enabled(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
uart_ll_force_xon(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Since it is still in the critical now, use ESP_EARLY_LOG */
|
||||||
|
ESP_EARLY_LOGE(TAG, "Sleep retention frame is corrupted");
|
||||||
|
esp_restart_noos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern RvCoreCriticalSleepFrame * rv_core_critical_regs_save(void);
|
||||||
|
extern RvCoreCriticalSleepFrame * rv_core_critical_regs_restore(void);
|
||||||
|
typedef uint32_t (* sleep_cpu_entry_cb_t)(uint32_t, uint32_t, uint32_t, bool);
|
||||||
|
|
||||||
|
static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep,
|
||||||
|
uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
|
||||||
|
{
|
||||||
|
__attribute__((unused)) uint8_t core_id = esp_cpu_get_core_id();
|
||||||
|
/* mstatus is core privated CSR, do it near the core critical regs restore */
|
||||||
|
uint32_t mstatus = save_mstatus_and_disable_global_int();
|
||||||
|
rv_core_critical_regs_save();
|
||||||
|
|
||||||
|
RvCoreCriticalSleepFrame * frame = s_cpu_retention.retent.critical_frame[core_id];
|
||||||
|
if ((frame->pmufunc & 0x3) == 0x1) {
|
||||||
|
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0);
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
/* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */
|
||||||
|
update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
|
||||||
|
#endif
|
||||||
|
REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore);
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE);
|
||||||
|
while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_BACKUP_DONE) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
|
||||||
|
}
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
else {
|
||||||
|
validate_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
restore_mstatus(mstatus);
|
||||||
|
return pmu_sleep_finish(dslp);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool),
|
||||||
|
uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
|
||||||
|
{
|
||||||
|
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0);
|
||||||
|
uint8_t core_id = esp_cpu_get_core_id();
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame[core_id]);
|
||||||
|
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]);
|
||||||
|
cpu_domain_dev_regs_save(s_cpu_retention.retent.cache_config_frame);
|
||||||
|
rv_core_noncritical_regs_save();
|
||||||
|
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame[core_id];
|
||||||
|
/* Minus sizeof(long) is for bypass `frame_crc` field */
|
||||||
|
update_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t err = do_cpu_retention(goto_sleep, wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp);
|
||||||
|
|
||||||
|
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
|
||||||
|
validate_retention_frame_crc((uint32_t*)frame, sizeof(RvCoreNonCriticalSleepFrame) - sizeof(long), (uint32_t *)(&frame->frame_crc));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
// Start core1
|
||||||
|
if (core_id == 0) {
|
||||||
|
REG_SET_BIT(PCR_CORE1_CONF_REG, PCR_CORE1_CLK_EN);
|
||||||
|
REG_CLR_BIT(PCR_CORE1_CONF_REG, PCR_CORE1_RST_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_START);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rv_core_noncritical_regs_restore();
|
||||||
|
cpu_domain_dev_regs_restore(s_cpu_retention.retent.cache_config_frame);
|
||||||
|
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]);
|
||||||
|
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame[core_id]);
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE);
|
||||||
|
#endif
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init(void)
|
||||||
|
{
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
return esp_sleep_cpu_retention_init_impl(& s_cpu_retention, s_smp_retention_state);
|
||||||
|
#else
|
||||||
|
return esp_sleep_cpu_retention_init_impl(& s_cpu_retention);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_sleep_cpu_retention_deinit(void)
|
||||||
|
{
|
||||||
|
return esp_sleep_cpu_retention_deinit_impl(& s_cpu_retention);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cpu_domain_pd_allowed(void)
|
||||||
|
{
|
||||||
|
bool allowed = true;
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
allowed &= (s_cpu_retention.retent.critical_frame[core_id] != NULL);
|
||||||
|
allowed &= (s_cpu_retention.retent.non_critical_frame[core_id] != NULL);
|
||||||
|
}
|
||||||
|
allowed &= (s_cpu_retention.retent.cache_config_frame != NULL);
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
allowed &= (s_cpu_retention.retent.clic_frame[core_id] != NULL);
|
||||||
|
allowed &= (s_cpu_retention.retent.clint_frame[core_id] != NULL);
|
||||||
|
}
|
||||||
|
return allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t sleep_cpu_configure(bool light_sleep_enable)
|
||||||
|
{
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||||
|
if (light_sleep_enable) {
|
||||||
|
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_init(), TAG, "Failed to enable CPU power down during light sleep.");
|
||||||
|
} else {
|
||||||
|
ESP_RETURN_ON_ERROR(esp_sleep_cpu_retention_deinit(), TAG, "Failed to release CPU retention memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !CONFIG_FREERTOS_UNICORE
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||||
|
static IRAM_ATTR void smp_core_do_retention(void)
|
||||||
|
{
|
||||||
|
uint8_t core_id = esp_cpu_get_core_id();
|
||||||
|
|
||||||
|
if (core_id == 0) {
|
||||||
|
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_2_REG, 0);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_3_REG, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait another core start to do retention
|
||||||
|
bool smp_skip_retention = false;
|
||||||
|
smp_retention_state_t another_core_state;
|
||||||
|
while (1) {
|
||||||
|
another_core_state = atomic_load(&s_smp_retention_state[!core_id]);
|
||||||
|
if (another_core_state == SMP_SKIP_RETENTION) {
|
||||||
|
// If another core skips the retention, the current core should also have to skip it.
|
||||||
|
smp_skip_retention = true;
|
||||||
|
break;
|
||||||
|
} else if (another_core_state == SMP_BACKUP_START) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smp_skip_retention) {
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_START);
|
||||||
|
uint32_t mstatus = save_mstatus_and_disable_global_int();
|
||||||
|
rv_core_noncritical_regs_save();
|
||||||
|
cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame[core_id]);
|
||||||
|
cpu_domain_dev_regs_save(s_cpu_retention.retent.clic_frame[core_id]);
|
||||||
|
rv_core_critical_regs_save();
|
||||||
|
RvCoreCriticalSleepFrame *frame_critical = s_cpu_retention.retent.critical_frame[core_id];
|
||||||
|
if ((frame_critical->pmufunc & 0x3) == 0x1) {
|
||||||
|
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE);
|
||||||
|
// wait another core trigger sleep and wakeup
|
||||||
|
while (1) {
|
||||||
|
// If another core's sleep request is rejected by the hardware, jumps out of blocking.
|
||||||
|
another_core_state = atomic_load(&s_smp_retention_state[!core_id]);
|
||||||
|
if (another_core_state == SMP_SKIP_RETENTION) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Start core1
|
||||||
|
if (core_id == 0) {
|
||||||
|
REG_SET_BIT(PCR_CORE1_CONF_REG, PCR_CORE1_CLK_EN);
|
||||||
|
REG_CLR_BIT(PCR_CORE1_CONF_REG, PCR_CORE1_RST_EN);
|
||||||
|
}
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_START);
|
||||||
|
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clic_frame[core_id]);
|
||||||
|
cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame[core_id]);
|
||||||
|
rv_core_noncritical_regs_restore();
|
||||||
|
restore_mstatus(mstatus);
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_RESTORE_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// wait another core out sleep
|
||||||
|
while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_IDLE) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_IDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IRAM_ATTR void esp_sleep_cpu_skip_retention(void) {
|
||||||
|
atomic_store(&s_smp_retention_state[esp_cpu_get_core_id()], SMP_SKIP_RETENTION);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void sleep_smp_cpu_sleep_prepare(void)
|
||||||
|
{
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||||
|
while (atomic_load(&s_smp_retention_state[!esp_cpu_get_core_id()]) != SMP_IDLE) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
esp_ipc_isr_call((esp_ipc_isr_func_t)smp_core_do_retention, NULL);
|
||||||
|
#else
|
||||||
|
esp_ipc_isr_stall_other_cpu();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void sleep_smp_cpu_wakeup_prepare(void)
|
||||||
|
{
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||||
|
uint8_t core_id = esp_cpu_get_core_id();
|
||||||
|
if (atomic_load(&s_smp_retention_state[core_id]) == SMP_RESTORE_DONE) {
|
||||||
|
while (atomic_load(&s_smp_retention_state[!core_id]) != SMP_RESTORE_DONE) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atomic_store(&s_smp_retention_state[core_id], SMP_IDLE);
|
||||||
|
#else
|
||||||
|
esp_ipc_isr_release_other_cpu();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif //!CONFIG_FREERTOS_UNICORE
|
219
components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu_asm.S
Normal file
219
components/esp_hw_support/lowpower/port/esp32h4/sleep_cpu_asm.S
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/soc.h"
|
||||||
|
#include "rvsleep-frames.h"
|
||||||
|
#include "freertos/FreeRTOSConfig.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "soc/cache_reg.h"
|
||||||
|
#define CACHE_MAP_L1_CACHE_MASK (BIT(0) | BIT(1) | BIT(4))
|
||||||
|
|
||||||
|
.section .data1,"aw"
|
||||||
|
.global rv_core_critical_regs_frame
|
||||||
|
.type rv_core_critical_regs_frame,@object
|
||||||
|
.align 4
|
||||||
|
rv_core_critical_regs_frame:
|
||||||
|
.rept (portNUM_PROCESSORS)
|
||||||
|
.word 0
|
||||||
|
.endr
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This assembly subroutine is used to save the critical registers of the CPU
|
||||||
|
core to the internal RAM before sleep, and modify the PMU control flag to
|
||||||
|
indicate that the system needs to sleep. When the subroutine returns, it
|
||||||
|
will return the memory pointer that saves the context information of the CPU
|
||||||
|
critical registers.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .iram1,"ax"
|
||||||
|
.global rv_core_critical_regs_save
|
||||||
|
.type rv_core_critical_regs_save,@function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
rv_core_critical_regs_save:
|
||||||
|
|
||||||
|
/* arrived here in critical section. we need:
|
||||||
|
save riscv core critical registers to RvCoreCriticalSleepFrame
|
||||||
|
*/
|
||||||
|
csrw mscratch, t0 /* use mscratch as temp storage */
|
||||||
|
la a0, rv_core_critical_regs_frame
|
||||||
|
csrr t1, mhartid
|
||||||
|
slli t1, t1, 2
|
||||||
|
add a0, a0, t1
|
||||||
|
lw t0, 0(a0) /* t0 pointer to RvCoreCriticalSleepFrame object */
|
||||||
|
|
||||||
|
sw ra, RV_SLP_CTX_RA(t0)
|
||||||
|
sw sp, RV_SLP_CTX_SP(t0)
|
||||||
|
sw gp, RV_SLP_CTX_GP(t0)
|
||||||
|
sw tp, RV_SLP_CTX_TP(t0)
|
||||||
|
sw t1, RV_SLP_CTX_T1(t0)
|
||||||
|
sw t2, RV_SLP_CTX_T2(t0)
|
||||||
|
sw s0, RV_SLP_CTX_S0(t0)
|
||||||
|
sw s1, RV_SLP_CTX_S1(t0)
|
||||||
|
|
||||||
|
/* a0 is caller saved, so it does not need to be saved, but it should be the
|
||||||
|
pointer value of RvCoreCriticalSleepFrame for return.
|
||||||
|
*/
|
||||||
|
mv a0, t0
|
||||||
|
sw a0, RV_SLP_CTX_A0(t0)
|
||||||
|
sw a1, RV_SLP_CTX_A1(t0)
|
||||||
|
sw a2, RV_SLP_CTX_A2(t0)
|
||||||
|
sw a3, RV_SLP_CTX_A3(t0)
|
||||||
|
sw a4, RV_SLP_CTX_A4(t0)
|
||||||
|
sw a5, RV_SLP_CTX_A5(t0)
|
||||||
|
sw a6, RV_SLP_CTX_A6(t0)
|
||||||
|
sw a7, RV_SLP_CTX_A7(t0)
|
||||||
|
sw s2, RV_SLP_CTX_S2(t0)
|
||||||
|
sw s3, RV_SLP_CTX_S3(t0)
|
||||||
|
sw s4, RV_SLP_CTX_S4(t0)
|
||||||
|
sw s5, RV_SLP_CTX_S5(t0)
|
||||||
|
sw s6, RV_SLP_CTX_S6(t0)
|
||||||
|
sw s7, RV_SLP_CTX_S7(t0)
|
||||||
|
sw s8, RV_SLP_CTX_S8(t0)
|
||||||
|
sw s9, RV_SLP_CTX_S9(t0)
|
||||||
|
sw s10, RV_SLP_CTX_S10(t0)
|
||||||
|
sw s11, RV_SLP_CTX_S11(t0)
|
||||||
|
sw t3, RV_SLP_CTX_T3(t0)
|
||||||
|
sw t4, RV_SLP_CTX_T4(t0)
|
||||||
|
sw t5, RV_SLP_CTX_T5(t0)
|
||||||
|
sw t6, RV_SLP_CTX_T6(t0)
|
||||||
|
|
||||||
|
csrr t1, mstatus
|
||||||
|
sw t1, RV_SLP_CTX_MSTATUS(t0)
|
||||||
|
csrr t2, mtvec
|
||||||
|
sw t2, RV_SLP_CTX_MTVEC(t0)
|
||||||
|
csrr t3, mcause
|
||||||
|
sw t3, RV_SLP_CTX_MCAUSE(t0)
|
||||||
|
|
||||||
|
csrr t1, mtval
|
||||||
|
sw t1, RV_SLP_CTX_MTVAL(t0)
|
||||||
|
csrr t2, mie
|
||||||
|
sw t2, RV_SLP_CTX_MIE(t0)
|
||||||
|
csrr t3, mip
|
||||||
|
sw t3, RV_SLP_CTX_MIP(t0)
|
||||||
|
csrr t1, mepc
|
||||||
|
sw t1, RV_SLP_CTX_MEPC(t0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
!!! Let idf knows it's going to sleep !!!
|
||||||
|
|
||||||
|
RV_SLP_STK_PMUFUNC field is used to identify whether it is going to sleep or
|
||||||
|
has just been awakened. We use the lowest 2 bits as indication information,
|
||||||
|
3 means being awakened, 1 means going to sleep.
|
||||||
|
*/
|
||||||
|
li t1, ~0x3
|
||||||
|
lw t2, RV_SLP_CTX_PMUFUNC(t0)
|
||||||
|
and t2, t1, t2
|
||||||
|
ori t2, t2, 0x1
|
||||||
|
sw t2, RV_SLP_CTX_PMUFUNC(t0)
|
||||||
|
|
||||||
|
mv t3, t0
|
||||||
|
csrr t0, mscratch
|
||||||
|
sw t0, RV_SLP_CTX_T0(t3)
|
||||||
|
lw t1, RV_SLP_CTX_T1(t3)
|
||||||
|
lw t2, RV_SLP_CTX_T2(t3)
|
||||||
|
lw t3, RV_SLP_CTX_T3(t3)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.size rv_core_critical_regs_save, . - rv_core_critical_regs_save
|
||||||
|
|
||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
This assembly subroutine is used to restore the CPU core critical register
|
||||||
|
context before sleep after system wakes up, modify the PMU control
|
||||||
|
information, and return the critical register context memory object pointer.
|
||||||
|
After the subroutine returns, continue to restore other modules of the
|
||||||
|
system.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .iram1,"ax"
|
||||||
|
.global rv_core_critical_regs_restore
|
||||||
|
.weak rv_core_critical_regs_restore
|
||||||
|
.type rv_core_critical_regs_restore,@function
|
||||||
|
.global _rv_core_critical_regs_restore
|
||||||
|
.type _rv_core_critical_regs_restore,@function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
_rv_core_critical_regs_restore: /* export a strong symbol to jump to here, used
|
||||||
|
* for a static callback */
|
||||||
|
nop
|
||||||
|
|
||||||
|
rv_core_critical_regs_restore:
|
||||||
|
la t0, rv_core_critical_regs_frame
|
||||||
|
csrr t1, mhartid
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0) /* t0 pointer to RvCoreCriticalSleepFrame object */
|
||||||
|
beqz t0, .skip_restore /* make sure we do not jump to zero address */
|
||||||
|
|
||||||
|
/*
|
||||||
|
!!! Let idf knows it's sleep awake. !!!
|
||||||
|
|
||||||
|
RV_SLP_STK_PMUFUNC field is used to identify whether it is going to sleep or
|
||||||
|
has just been awakened. We use the lowest 2 bits as indication information,
|
||||||
|
3 means being awakened, 1 means going to sleep.
|
||||||
|
*/
|
||||||
|
lw t1, RV_SLP_CTX_PMUFUNC(t0)
|
||||||
|
ori t1, t1, 0x3
|
||||||
|
sw t1, RV_SLP_CTX_PMUFUNC(t0)
|
||||||
|
|
||||||
|
lw t2, RV_SLP_CTX_MEPC(t0)
|
||||||
|
csrw mepc, t2
|
||||||
|
lw t3, RV_SLP_CTX_MIP(t0)
|
||||||
|
csrw mip, t3
|
||||||
|
lw t1, RV_SLP_CTX_MIE(t0)
|
||||||
|
csrw mie, t1
|
||||||
|
lw t2, RV_SLP_CTX_MSTATUS(t0)
|
||||||
|
csrw mstatus, t2
|
||||||
|
lw t3, RV_SLP_CTX_MTVEC(t0)
|
||||||
|
csrw mtvec, t3
|
||||||
|
lw t1, RV_SLP_CTX_MCAUSE(t0)
|
||||||
|
csrw mcause, t1
|
||||||
|
lw t2, RV_SLP_CTX_MTVAL(t0)
|
||||||
|
csrw mtval, t2
|
||||||
|
|
||||||
|
lw t6, RV_SLP_CTX_T6(t0)
|
||||||
|
lw t5, RV_SLP_CTX_T5(t0)
|
||||||
|
lw t4, RV_SLP_CTX_T4(t0)
|
||||||
|
lw t3, RV_SLP_CTX_T3(t0)
|
||||||
|
lw s11, RV_SLP_CTX_S11(t0)
|
||||||
|
lw s10, RV_SLP_CTX_S10(t0)
|
||||||
|
lw s9, RV_SLP_CTX_S9(t0)
|
||||||
|
lw s8, RV_SLP_CTX_S8(t0)
|
||||||
|
lw s7, RV_SLP_CTX_S7(t0)
|
||||||
|
lw s6, RV_SLP_CTX_S6(t0)
|
||||||
|
lw s5, RV_SLP_CTX_S5(t0)
|
||||||
|
lw s4, RV_SLP_CTX_S4(t0)
|
||||||
|
lw s3, RV_SLP_CTX_S3(t0)
|
||||||
|
lw s2, RV_SLP_CTX_S2(t0)
|
||||||
|
lw a7, RV_SLP_CTX_A7(t0)
|
||||||
|
lw a6, RV_SLP_CTX_A6(t0)
|
||||||
|
lw a5, RV_SLP_CTX_A5(t0)
|
||||||
|
lw a4, RV_SLP_CTX_A4(t0)
|
||||||
|
lw a3, RV_SLP_CTX_A3(t0)
|
||||||
|
lw a2, RV_SLP_CTX_A2(t0)
|
||||||
|
lw a1, RV_SLP_CTX_A1(t0)
|
||||||
|
lw a0, RV_SLP_CTX_A0(t0)
|
||||||
|
lw s1, RV_SLP_CTX_S1(t0)
|
||||||
|
lw s0, RV_SLP_CTX_S0(t0)
|
||||||
|
lw t2, RV_SLP_CTX_T2(t0)
|
||||||
|
lw t1, RV_SLP_CTX_T1(t0)
|
||||||
|
lw tp, RV_SLP_CTX_TP(t0)
|
||||||
|
lw gp, RV_SLP_CTX_GP(t0)
|
||||||
|
lw sp, RV_SLP_CTX_SP(t0)
|
||||||
|
lw ra, RV_SLP_CTX_RA(t0)
|
||||||
|
lw t0, RV_SLP_CTX_T0(t0)
|
||||||
|
|
||||||
|
.skip_restore:
|
||||||
|
ret
|
||||||
|
|
||||||
|
.size rv_core_critical_regs_restore, . - rv_core_critical_regs_restore
|
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "soc/cache_reg.h"
|
||||||
|
#include "soc/clint_reg.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
|
||||||
|
#include "rvsleep-frames.h"
|
||||||
|
#include "sleep_cpu_retention.h"
|
||||||
|
|
||||||
|
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS];
|
||||||
|
|
||||||
|
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num)
|
||||||
|
{
|
||||||
|
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
|
||||||
|
int regs_frame_sz = 0;
|
||||||
|
for (int num = 0; num < region_num; num++) {
|
||||||
|
regs_frame_sz += regions[num].end - regions[num].start;
|
||||||
|
}
|
||||||
|
void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||||
|
if (frame) {
|
||||||
|
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
|
||||||
|
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
|
||||||
|
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
|
||||||
|
memset(regs_frame, 0, regs_frame_sz);
|
||||||
|
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
|
||||||
|
.region = region,
|
||||||
|
.region_num = region_num,
|
||||||
|
.regs_frame = (uint32_t *)regs_frame
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||||
|
{ .start = CACHE_L1_ICACHE_CTRL_REG, .end = CACHE_L1_DCACHE_CTRL_REG + 4 },
|
||||||
|
{ .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
|
||||||
|
};
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void * cpu_domain_clint_sleep_frame_alloc_and_init(uint8_t core_id)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[portNUM_PROCESSORS][3] = {
|
||||||
|
[0 ... portNUM_PROCESSORS - 1] = {
|
||||||
|
{ .start = CLINT_MINT_SIP_REG, .end = CLINT_MINT_SIP_REG + 4 },
|
||||||
|
{ .start = CLINT_MINT_MTIMECMP_L_REG, .end = CLINT_MINT_TIMECTL_REG + 4 },
|
||||||
|
{ .start = CLINT_MINT_MTIME_L_REG, .end = CLINT_MINT_MTIME_H_REG + 4 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions[core_id], sizeof(regions[core_id]) / sizeof(regions[core_id][0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void * cpu_domain_clic_sleep_frame_alloc_and_init(uint8_t core_id)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[portNUM_PROCESSORS][4] = {
|
||||||
|
[0 ... portNUM_PROCESSORS - 1] = {
|
||||||
|
{ .start = CLIC_INT_CONFIG_REG, .end = CLIC_INT_THRESH_REG + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(3), .end = CLIC_INT_CTRL_REG(3) + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(7), .end = CLIC_INT_CTRL_REG(7) + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(16), .end = CLIC_INT_CTRL_REG(47) + 4 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions[core_id], sizeof(regions[core_id]) / sizeof(regions[core_id][0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr, smp_retention_state_t *s_smp_retention_state)
|
||||||
|
{
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id] == NULL) {
|
||||||
|
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = (RvCoreCriticalSleepFrame *)frame;
|
||||||
|
rv_core_critical_regs_frame[core_id] = (RvCoreCriticalSleepFrame *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] == NULL) {
|
||||||
|
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = (RvCoreNonCriticalSleepFrame *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clic_sleep_frame_alloc_and_init(core_id);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clint_sleep_frame_alloc_and_init(core_id);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||||
|
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
atomic_init(&s_smp_retention_state[core_id], SMP_IDLE);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
err:
|
||||||
|
esp_sleep_cpu_retention_deinit();
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||||
|
{
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id] == NULL) {
|
||||||
|
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = (RvCoreCriticalSleepFrame *)frame;
|
||||||
|
rv_core_critical_regs_frame[core_id] = (RvCoreCriticalSleepFrame *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] == NULL) {
|
||||||
|
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = (RvCoreNonCriticalSleepFrame *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clic_sleep_frame_alloc_and_init(core_id);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clint_sleep_frame_alloc_and_init(core_id);
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||||
|
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
err:
|
||||||
|
esp_sleep_cpu_retention_deinit();
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||||
|
{
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id]) {
|
||||||
|
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.critical_frame[core_id]);
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = NULL;
|
||||||
|
rv_core_critical_regs_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id]) {
|
||||||
|
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.non_critical_frame[core_id]);
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id]) {
|
||||||
|
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.clic_frame[core_id]);
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id]) {
|
||||||
|
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.clint_frame[core_id]);
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
|
||||||
|
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.cache_config_frame);
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SLEEP_CPU_RETENTION_H__
|
||||||
|
#define __SLEEP_CPU_RETENTION_H__
|
||||||
|
|
||||||
|
#include "rvsleep-frames.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include "soc/hp_system_reg.h"
|
||||||
|
typedef enum {
|
||||||
|
SMP_IDLE,
|
||||||
|
SMP_BACKUP_START,
|
||||||
|
SMP_BACKUP_DONE,
|
||||||
|
SMP_RESTORE_START,
|
||||||
|
SMP_RESTORE_DONE,
|
||||||
|
SMP_SKIP_RETENTION,
|
||||||
|
} smp_retention_state_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
|
} cpu_domain_dev_regs_region_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
cpu_domain_dev_regs_region_t *region;
|
||||||
|
int region_num;
|
||||||
|
uint32_t *regs_frame;
|
||||||
|
} cpu_domain_dev_sleep_frame_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal structure which holds all requested light sleep cpu retention parameters
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
RvCoreCriticalSleepFrame *critical_frame[portNUM_PROCESSORS];
|
||||||
|
RvCoreNonCriticalSleepFrame *non_critical_frame[portNUM_PROCESSORS];
|
||||||
|
cpu_domain_dev_sleep_frame_t *cache_config_frame;
|
||||||
|
cpu_domain_dev_sleep_frame_t *clic_frame[portNUM_PROCESSORS];
|
||||||
|
cpu_domain_dev_sleep_frame_t *clint_frame[portNUM_PROCESSORS];
|
||||||
|
} retent;
|
||||||
|
} sleep_cpu_retention_t;
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr, smp_retention_state_t *s_smp_retention_state);
|
||||||
|
#else
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
|
||||||
|
|
||||||
|
#endif /* #ifndef __SLEEP_CPU_RETENTION_H__ */
|
@@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "soc/cache_reg.h"
|
||||||
|
#include "soc/clint_reg.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
|
||||||
|
#include "rvsleep-frames.h"
|
||||||
|
#include "sleep_cpu_retention.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame[portNUM_PROCESSORS];
|
||||||
|
|
||||||
|
#define R_CONCAT(s1, s2) _R_CONCAT(s1, s2)
|
||||||
|
#define _R_CONCAT(s1, s2) s1 ## s2
|
||||||
|
|
||||||
|
#define CPU_DOMAIN_DEV_SZ0 (CPU_DOMAIN_DEV_END_ADDR0 - CPU_DOMAIN_DEV_START_ADDR0)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ1 (CPU_DOMAIN_DEV_END_ADDR1 - CPU_DOMAIN_DEV_START_ADDR1)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ2 (CPU_DOMAIN_DEV_END_ADDR2 - CPU_DOMAIN_DEV_START_ADDR2)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ3 (CPU_DOMAIN_DEV_END_ADDR3 - CPU_DOMAIN_DEV_START_ADDR3)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ4 (CPU_DOMAIN_DEV_END_ADDR4 - CPU_DOMAIN_DEV_START_ADDR4)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ5 (CPU_DOMAIN_DEV_END_ADDR5 - CPU_DOMAIN_DEV_START_ADDR5)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ6 (CPU_DOMAIN_DEV_END_ADDR6 - CPU_DOMAIN_DEV_START_ADDR6)
|
||||||
|
#define CPU_DOMAIN_DEV_SZ7 (CPU_DOMAIN_DEV_END_ADDR7 - CPU_DOMAIN_DEV_START_ADDR7)
|
||||||
|
|
||||||
|
#define CPU_DOMAIN_DEV_TOTAL_SZ(n) (R_CONCAT(__TOTAL_SZ, n))
|
||||||
|
|
||||||
|
#define __TOTAL_SZ0 (sizeof(cpu_domain_dev_sleep_frame_t))
|
||||||
|
#define __TOTAL_SZ1 ((__TOTAL_SZ0) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ0)
|
||||||
|
#define __TOTAL_SZ2 ((__TOTAL_SZ1) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ1)
|
||||||
|
#define __TOTAL_SZ3 ((__TOTAL_SZ2) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ2)
|
||||||
|
#define __TOTAL_SZ4 ((__TOTAL_SZ3) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ3)
|
||||||
|
#define __TOTAL_SZ5 ((__TOTAL_SZ4) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ4)
|
||||||
|
#define __TOTAL_SZ6 ((__TOTAL_SZ5) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ5)
|
||||||
|
#define __TOTAL_SZ7 ((__TOTAL_SZ6) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ6)
|
||||||
|
#define __TOTAL_SZ8 ((__TOTAL_SZ7) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ7)
|
||||||
|
|
||||||
|
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num, void * frame)
|
||||||
|
{
|
||||||
|
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
|
||||||
|
int regs_frame_sz = 0;
|
||||||
|
for (int num = 0; num < region_num; num++) {
|
||||||
|
regs_frame_sz += regions[num].end - regions[num].start;
|
||||||
|
}
|
||||||
|
if (frame) {
|
||||||
|
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
|
||||||
|
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
|
||||||
|
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
|
||||||
|
memset(regs_frame, 0, regs_frame_sz);
|
||||||
|
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
|
||||||
|
.region = region,
|
||||||
|
.region_num = region_num,
|
||||||
|
.regs_frame = (uint32_t *)regs_frame
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR1
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR1
|
||||||
|
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR0 (CACHE_L1_ICACHE_CTRL_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR0 (CACHE_L1_DCACHE_CTRL_REG + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR1 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR1 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4)
|
||||||
|
|
||||||
|
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||||
|
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 },
|
||||||
|
{ .start = CPU_DOMAIN_DEV_START_ADDR1, .end = CPU_DOMAIN_DEV_END_ADDR1 }
|
||||||
|
};
|
||||||
|
static uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(2)] __attribute__((aligned(4)));
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR1
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR1
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR2
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR2
|
||||||
|
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR0 (CLINT_MINT_SIP_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR0 (CLINT_MINT_SIP_REG + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR1 (CLINT_MINT_MTIMECMP_L_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR1 (CLINT_MINT_TIMECTL_REG + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR2 (CLINT_MINT_MTIME_L_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR2 (CLINT_MINT_MTIME_H_REG + 4)
|
||||||
|
|
||||||
|
static inline void * cpu_domain_clint_sleep_frame_alloc_and_init(uint8_t core_id)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[portNUM_PROCESSORS][3] = {
|
||||||
|
[0 ... portNUM_PROCESSORS - 1] = {
|
||||||
|
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 },
|
||||||
|
{ .start = CPU_DOMAIN_DEV_START_ADDR1, .end = CPU_DOMAIN_DEV_END_ADDR1 },
|
||||||
|
{ .start = CPU_DOMAIN_DEV_START_ADDR2, .end = CPU_DOMAIN_DEV_END_ADDR2 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static DRAM_ATTR uint8_t sleep_frame[portNUM_PROCESSORS][CPU_DOMAIN_DEV_TOTAL_SZ(3)] __attribute__((aligned(4)));
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions[core_id], sizeof(regions[core_id]) / sizeof(regions[core_id][0]), sleep_frame[core_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR0
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR1
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR1
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR2
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR2
|
||||||
|
#undef CPU_DOMAIN_DEV_START_ADDR3
|
||||||
|
#undef CPU_DOMAIN_DEV_END_ADDR3
|
||||||
|
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR0 (CLIC_INT_CONFIG_REG)
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR0 (CLIC_INT_THRESH_REG + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR1 (CLIC_INT_CTRL_REG(3))
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR1 (CLIC_INT_CTRL_REG(3) + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR2 (CLIC_INT_CTRL_REG(7))
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR2 (CLIC_INT_CTRL_REG(7) + 4)
|
||||||
|
#define CPU_DOMAIN_DEV_START_ADDR3 (CLIC_INT_CTRL_REG(16))
|
||||||
|
#define CPU_DOMAIN_DEV_END_ADDR3 (CLIC_INT_CTRL_REG(47) + 4)
|
||||||
|
|
||||||
|
static inline void * cpu_domain_clic_sleep_frame_alloc_and_init(uint8_t core_id)
|
||||||
|
{
|
||||||
|
const static cpu_domain_dev_regs_region_t regions[portNUM_PROCESSORS][4] = {
|
||||||
|
[0 ... portNUM_PROCESSORS - 1] = {
|
||||||
|
{ .start = CLIC_INT_CONFIG_REG, .end = CLIC_INT_THRESH_REG + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(3), .end = CLIC_INT_CTRL_REG(3) + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(7), .end = CLIC_INT_CTRL_REG(7) + 4 },
|
||||||
|
{ .start = CLIC_INT_CTRL_REG(16), .end = CLIC_INT_CTRL_REG(47) + 4 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static DRAM_ATTR uint8_t sleep_frame[portNUM_PROCESSORS][CPU_DOMAIN_DEV_TOTAL_SZ(4)] __attribute__((aligned(4)));
|
||||||
|
return cpu_domain_dev_sleep_frame_alloc_and_init(regions[core_id], sizeof(regions[core_id]) / sizeof(regions[core_id][0]), sleep_frame[core_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ESP_SLEEP_POWER_DOWN_CPU && !CONFIG_FREERTOS_UNICORE
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr, smp_retention_state_t *s_smp_retention_state)
|
||||||
|
{
|
||||||
|
static DRAM_ATTR uint8_t rv_core_critical_regs[RV_SLEEP_CTX_FRMSZ * portNUM_PROCESSORS] __attribute__((aligned(4)));
|
||||||
|
static DRAM_ATTR uint8_t rv_core_non_critical_regs[sizeof(RvCoreNonCriticalSleepFrame)* portNUM_PROCESSORS] __attribute__((aligned(4)));
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id] == NULL) {
|
||||||
|
void * regs = rv_core_critical_regs + core_id * RV_SLEEP_CTX_FRMSZ;
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = (RvCoreCriticalSleepFrame *) regs;
|
||||||
|
rv_core_critical_regs_frame[core_id] = (RvCoreCriticalSleepFrame *) regs;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] == NULL) {
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = (RvCoreNonCriticalSleepFrame *)(rv_core_non_critical_regs+core_id * sizeof(RvCoreNonCriticalSleepFrame));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clint_sleep_frame_alloc_and_init(core_id);
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clic_sleep_frame_alloc_and_init(core_id);
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||||
|
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
atomic_init(&s_smp_retention_state[core_id], SMP_IDLE);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||||
|
{
|
||||||
|
static DRAM_ATTR uint8_t rv_core_critical_regs[RV_SLEEP_CTX_FRMSZ * portNUM_PROCESSORS] __attribute__((aligned(4)));
|
||||||
|
static DRAM_ATTR uint8_t rv_core_non_critical_regs[sizeof(RvCoreNonCriticalSleepFrame)* portNUM_PROCESSORS] __attribute__((aligned(4)));
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id] == NULL) {
|
||||||
|
void * regs = rv_core_critical_regs + core_id * RV_SLEEP_CTX_FRMSZ;
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = (RvCoreCriticalSleepFrame *) regs;
|
||||||
|
rv_core_critical_regs_frame[core_id] = (RvCoreCriticalSleepFrame *) regs;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] == NULL) {
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = (RvCoreNonCriticalSleepFrame *)(rv_core_non_critical_regs+core_id * sizeof(RvCoreNonCriticalSleepFrame));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clint_sleep_frame_alloc_and_init(core_id);
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id] == NULL) {
|
||||||
|
void *frame = cpu_domain_clic_sleep_frame_alloc_and_init(core_id);
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
|
||||||
|
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
|
||||||
|
{
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.critical_frame[core_id]) {
|
||||||
|
sleep_cpu_retention_ptr->retent.critical_frame[core_id] = NULL;
|
||||||
|
rv_core_critical_regs_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.non_critical_frame[core_id]) {
|
||||||
|
sleep_cpu_retention_ptr->retent.non_critical_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint8_t core_id = 0; core_id < portNUM_PROCESSORS; ++core_id) {
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clint_frame[core_id]) {
|
||||||
|
sleep_cpu_retention_ptr->retent.clint_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.clic_frame[core_id]) {
|
||||||
|
sleep_cpu_retention_ptr->retent.clic_frame[core_id] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
|
||||||
|
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@@ -527,8 +527,8 @@ typedef struct pmu_sleep_machine_constant {
|
|||||||
.lp = { \
|
.lp = { \
|
||||||
.min_slp_time_us = 450, \
|
.min_slp_time_us = 450, \
|
||||||
.wakeup_wait_cycle = 4, \
|
.wakeup_wait_cycle = 4, \
|
||||||
.analog_wait_time_us = 400, \
|
.analog_wait_time_us = 130, \
|
||||||
.xtal_wait_stable_time_us = 2000, \
|
.xtal_wait_stable_time_us = 160, \
|
||||||
.clk_switch_cycle = 1, \
|
.clk_switch_cycle = 1, \
|
||||||
.clk_power_on_wait_cycle = 1, \
|
.clk_power_on_wait_cycle = 1, \
|
||||||
.isolate_wait_time_us = 1, \
|
.isolate_wait_time_us = 1, \
|
||||||
@@ -540,18 +540,18 @@ typedef struct pmu_sleep_machine_constant {
|
|||||||
.min_slp_time_us = 450, \
|
.min_slp_time_us = 450, \
|
||||||
.clock_domain_sync_time_us = 150, \
|
.clock_domain_sync_time_us = 150, \
|
||||||
.system_dfs_up_work_time_us = 124, \
|
.system_dfs_up_work_time_us = 124, \
|
||||||
.analog_wait_time_us = 800, \
|
.analog_wait_time_us = 2200, \
|
||||||
.isolate_wait_time_us = 1, \
|
.isolate_wait_time_us = 1, \
|
||||||
.reset_wait_time_us = 1, \
|
.reset_wait_time_us = 1, \
|
||||||
.power_supply_wait_time_us = 2, \
|
.power_supply_wait_time_us = 2, \
|
||||||
.power_up_wait_time_us = 2, \
|
.power_up_wait_time_us = 2, \
|
||||||
.regdma_s2m_work_time_us = 172, \
|
.regdma_s2m_work_time_us = 172, \
|
||||||
.regdma_s2a_work_time_us = 480, \
|
.regdma_s2a_work_time_us = 280, \
|
||||||
.regdma_m2a_work_time_us = 278, \
|
.regdma_m2a_work_time_us = 278, \
|
||||||
.regdma_a2s_work_time_us = 382, \
|
.regdma_a2s_work_time_us = 220, \
|
||||||
.regdma_rf_on_work_time_us = 70, \
|
.regdma_rf_on_work_time_us = 70, \
|
||||||
.regdma_rf_off_work_time_us = 23, \
|
.regdma_rf_off_work_time_us = 23, \
|
||||||
.xtal_wait_stable_time_us = 2000, \
|
.xtal_wait_stable_time_us = 160, \
|
||||||
.pll_wait_stable_time_us = 1 \
|
.pll_wait_stable_time_us = 1 \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@@ -19,14 +19,49 @@
|
|||||||
#include "hal/clk_tree_ll.h"
|
#include "hal/clk_tree_ll.h"
|
||||||
#include "hal/pmu_ll.h"
|
#include "hal/pmu_ll.h"
|
||||||
#include "soc/pmu_reg.h"
|
#include "soc/pmu_reg.h"
|
||||||
|
#if SOC_MODEM_CLOCK_SUPPORTED
|
||||||
|
#include "hal/modem_syscon_ll.h"
|
||||||
|
#include "hal/modem_lpcon_ll.h"
|
||||||
|
#endif
|
||||||
#include "pmu_param.h"
|
#include "pmu_param.h"
|
||||||
|
|
||||||
static const char *TAG = "rtc_clk_init";
|
static const char *TAG = "rtc_clk_init";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the ICG map of some modem clock domains in the PMU_ACTIVE state
|
||||||
|
*
|
||||||
|
* A pre-initialization interface is used to initialize the ICG map of the
|
||||||
|
* MODEM_APB, I2C_MST and LP_APB clock domains in the PMU_ACTIVE state, and
|
||||||
|
* disable the clock gating of these clock domains in the PMU_ACTIVE state,
|
||||||
|
* because the system clock source (PLL) in the system boot up process needs
|
||||||
|
* to use the i2c master peripheral.
|
||||||
|
*
|
||||||
|
* ICG map of all modem clock domains under different power states (PMU_ACTIVE,
|
||||||
|
* PMU_MODEM and PMU_SLEEP) will be initialized in esp_perip_clk_init().
|
||||||
|
*/
|
||||||
|
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)
|
void rtc_clk_init(rtc_clk_config_t cfg)
|
||||||
{
|
{
|
||||||
rtc_cpu_freq_config_t old_config, new_config;
|
rtc_cpu_freq_config_t old_config, new_config;
|
||||||
|
|
||||||
|
rtc_clk_modem_clock_domain_active_state_icg_map_preinit();
|
||||||
|
|
||||||
/* Set tuning parameters for RC_FAST and RC_SLOW clocks.
|
/* Set tuning parameters for RC_FAST and RC_SLOW clocks.
|
||||||
* Note: this doesn't attempt to set the clocks to precise frequencies.
|
* Note: this doesn't attempt to set the clocks to precise frequencies.
|
||||||
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
|
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
|
||||||
@@ -38,10 +73,11 @@ void rtc_clk_init(rtc_clk_config_t cfg)
|
|||||||
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
|
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
|
||||||
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313
|
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313
|
||||||
|
|
||||||
uint32_t hp_cali_dbias = get_act_hp_dbias();
|
uint32_t hp_dbias = get_act_hp_dbias();
|
||||||
uint32_t lp_cali_dbias = get_act_lp_dbias();
|
uint32_t lp_dbias = get_act_lp_dbias();
|
||||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias);
|
pmu_ll_hp_set_regulator_xpd(&PMU, PMU_MODE_HP_ACTIVE, true);
|
||||||
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias);
|
pmu_ll_hp_set_regulator_dbias(&PMU, PMU_MODE_HP_ACTIVE, hp_dbias);
|
||||||
|
pmu_ll_lp_set_regulator_dbias(&PMU, PMU_MODE_LP_ACTIVE, lp_dbias);
|
||||||
|
|
||||||
// XTAL freq can be directly informed from register field PCR_CLK_XTAL_FREQ
|
// XTAL freq can be directly informed from register field PCR_CLK_XTAL_FREQ
|
||||||
|
|
||||||
|
@@ -195,7 +195,7 @@
|
|||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
||||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||||
#elif CONFIG_IDF_TARGET_ESP32H4
|
#elif CONFIG_IDF_TARGET_ESP32H4
|
||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (130)
|
||||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)
|
||||||
@@ -1172,7 +1172,6 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl
|
|||||||
{
|
{
|
||||||
rtc_clk_cpu_freq_set_config(&cpu_freq_config);
|
rtc_clk_cpu_freq_set_config(&cpu_freq_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CLK_READY, (void *)0);
|
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CLK_READY, (void *)0);
|
||||||
|
|
||||||
if (!deep_sleep) {
|
if (!deep_sleep) {
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 |
|
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 |
|
||||||
| ----------------- | -------- | -------- | --------- | -------- | -------- |
|
| ----------------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "esp_private/esp_pmu.h"
|
#include "esp_private/esp_pmu.h"
|
||||||
#include "esp_rom_serial_output.h"
|
#include "esp_rom_serial_output.h"
|
||||||
#include "esp_rom_sys.h"
|
#include "esp_rom_sys.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
|
||||||
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
|
/* 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
|
* Larger values increase startup delay. Smaller values may cause false positive
|
||||||
@@ -181,5 +182,9 @@ void rtc_clk_select_rtc_slow_clk(void)
|
|||||||
*/
|
*/
|
||||||
__attribute__((weak)) void esp_perip_clk_init(void)
|
__attribute__((weak)) void esp_perip_clk_init(void)
|
||||||
{
|
{
|
||||||
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
|
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
|
||||||
|
esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t)(\
|
||||||
|
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \
|
||||||
|
: ESP_PD_DOMAIN_MAX);
|
||||||
|
esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON);
|
||||||
}
|
}
|
||||||
|
@@ -86,6 +86,7 @@ SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/p
|
|||||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c on BIT(0)
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_clock.c on BIT(0)
|
||||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c on BIT(0)
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h2/sleep_clock.c on BIT(0)
|
||||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c on BIT(0)
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h21/sleep_clock.c on BIT(0)
|
||||||
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32h4/sleep_clock.c on BIT(0)
|
||||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
|
||||||
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
||||||
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0)
|
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0)
|
||||||
|
92
components/hal/esp32h4/include/hal/clk_gate_ll.h
Normal file
92
components/hal/esp32h4/include/hal/clk_gate_ll.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "esp_attr.h"
|
||||||
|
#include "soc/pcr_struct.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_8m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_8m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_8m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_8m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_8m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_16m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_16m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_16m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_16m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_16m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_32m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_32m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_32m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_32m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_32m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_48m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_48m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_48m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_48m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_48m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_64m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_64m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_64m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_64m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_64m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the clock gate for ref_96m.
|
||||||
|
* @param enable Enable / disable
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_ATTR void _clk_gate_ll_ref_96m_clk_en(bool enable)
|
||||||
|
{
|
||||||
|
PCR.pll_div_clk_en.pll_96m_clk_en = enable;
|
||||||
|
}
|
||||||
|
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||||
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
|
#define clk_gate_ll_ref_96m_clk_en(...) (void)__DECLARE_RCC_ATOMIC_ENV; _clk_gate_ll_ref_96m_clk_en(__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -91,6 +91,21 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
|
|||||||
REG_CLR_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
|
REG_CLR_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the maximum number of linked lists supported by REGDMA
|
||||||
|
* @param count: the maximum number of regdma link
|
||||||
|
*/
|
||||||
|
static inline void lp_aon_ll_set_regdma_link_count(int count)
|
||||||
|
{
|
||||||
|
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg0, aon_branch_link_length_aon, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lp_aon_ll_set_regdma_link_addr(uint32_t addr)
|
||||||
|
{
|
||||||
|
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg2, aon_link_addr_aon, addr);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -77,6 +77,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, boo
|
|||||||
dev->lp_int_ena.main_timer_lp_int_ena = enable;
|
dev->lp_int_ena.main_timer_lp_int_ena = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record the start and finish times for one-time regdma work */
|
||||||
|
FORCE_INLINE_ATTR void lp_timer_ll_record_regdma_work_time_enable(lp_timer_dev_t *dev, bool en)
|
||||||
|
{
|
||||||
|
dev->update.main_timer_regdma_work = en;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -92,6 +92,54 @@ static inline void modem_lpcon_ll_reset_all(modem_lpcon_dev_t *hw)
|
|||||||
hw->rst_conf.val = 0;
|
hw->rst_conf.val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t modem_lpcon_ll_get_wifipwr_icg_bitmap(modem_lpcon_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->clk_conf_power_st.clk_wifipwr_st_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void modem_lpcon_ll_set_wifipwr_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap)
|
||||||
|
{
|
||||||
|
hw->clk_conf_power_st.clk_wifipwr_st_map = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t modem_lpcon_ll_get_coex_icg_bitmap(modem_lpcon_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->clk_conf_power_st.clk_coex_st_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void modem_lpcon_ll_set_coex_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap)
|
||||||
|
{
|
||||||
|
hw->clk_conf_power_st.clk_coex_st_map = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t modem_lpcon_ll_get_i2c_master_icg_bitmap(modem_lpcon_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->clk_conf_power_st.clk_i2c_mst_st_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void modem_lpcon_ll_set_i2c_master_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap)
|
||||||
|
{
|
||||||
|
hw->clk_conf_power_st.clk_i2c_mst_st_map = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t modem_lpcon_ll_get_lp_apb_icg_bitmap(modem_lpcon_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->clk_conf_power_st.clk_lp_apb_st_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void modem_lpcon_ll_set_lp_apb_icg_bitmap(modem_lpcon_dev_t *hw, uint32_t bitmap)
|
||||||
|
{
|
||||||
|
hw->clk_conf_power_st.clk_lp_apb_st_map = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -84,6 +84,11 @@ static inline void pau_ll_set_regdma_timeout_read_mode_try_time(pau_dev_t *dev,
|
|||||||
REG_SET_FIELD(LP_AON_BACKUP_DMA_CFG1_REG, LP_AON_LINK_WAIT_TOUT_THRES_AON, thres);
|
REG_SET_FIELD(LP_AON_BACKUP_DMA_CFG1_REG, LP_AON_LINK_WAIT_TOUT_THRES_AON, thres);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void pau_ll_set_regdma_branch_max_link(pau_dev_t *dev, uint32_t max_link_len)
|
||||||
|
{
|
||||||
|
REG_SET_FIELD(LP_AON_BACKUP_DMA_CFG1_REG, LP_AON_BRANCH_LINK_LENGTH_AON, max_link_len);
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev)
|
static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev)
|
||||||
{
|
{
|
||||||
return dev->regdma_current_link_addr.val;
|
return dev->regdma_current_link_addr.val;
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include "soc/i2c_ana_mst_reg.h"
|
#include "soc/i2c_ana_mst_reg.h"
|
||||||
#include "soc/pmu_reg.h"
|
#include "soc/pmu_reg.h"
|
||||||
#include "modem/modem_lpcon_struct.h"
|
#include "modem/modem_lpcon_struct.h"
|
||||||
|
#include "modem/modem_syscon_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -65,7 +66,7 @@ static inline __attribute__((always_inline)) void regi2c_ctrl_ll_master_force_en
|
|||||||
*/
|
*/
|
||||||
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_master_configure_clock(void)
|
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_master_configure_clock(void)
|
||||||
{
|
{
|
||||||
// Nothing to configure
|
MODEM_SYSCON.clk_conf.clk_i2c_mst_sel_160m = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -13,6 +13,82 @@
|
|||||||
#include "hal/modem_clock_types.h"
|
#include "hal/modem_clock_types.h"
|
||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MODEM_CLOCK_XTAL32K_CODE = 0,
|
||||||
|
MODEM_CLOCK_RC32K_CODE = 1,
|
||||||
|
MODEM_CLOCK_EXT32K_CODE = 2
|
||||||
|
} modem_clock_32k_clk_src_code_t;
|
||||||
|
|
||||||
|
void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX);
|
||||||
|
switch (domain)
|
||||||
|
{
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_APB:
|
||||||
|
modem_syscon_ll_set_modem_apb_icg_bitmap(hal->syscon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_PERIPH:
|
||||||
|
modem_syscon_ll_set_modem_periph_icg_bitmap(hal->syscon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_BT:
|
||||||
|
modem_syscon_ll_set_bt_icg_bitmap(hal->syscon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_FE:
|
||||||
|
modem_syscon_ll_set_fe_icg_bitmap(hal->syscon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_IEEE802154:
|
||||||
|
modem_syscon_ll_set_ieee802154_icg_bitmap(hal->syscon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_LP_APB:
|
||||||
|
modem_lpcon_ll_set_lp_apb_icg_bitmap(hal->lpcon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_I2C_MASTER:
|
||||||
|
modem_lpcon_ll_set_i2c_master_icg_bitmap(hal->lpcon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_COEX:
|
||||||
|
modem_lpcon_ll_set_coex_icg_bitmap(hal->lpcon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_WIFIPWR:
|
||||||
|
modem_lpcon_ll_set_wifipwr_icg_bitmap(hal->lpcon_dev, bitmap);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain)
|
||||||
|
{
|
||||||
|
HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX);
|
||||||
|
uint32_t bitmap = 0;
|
||||||
|
switch (domain)
|
||||||
|
{
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_APB:
|
||||||
|
bitmap = modem_syscon_ll_get_modem_apb_icg_bitmap(hal->syscon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_PERIPH:
|
||||||
|
bitmap = modem_syscon_ll_get_modem_periph_icg_bitmap(hal->syscon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_BT:
|
||||||
|
bitmap = modem_syscon_ll_get_bt_icg_bitmap(hal->syscon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_MODEM_FE:
|
||||||
|
bitmap = modem_syscon_ll_get_fe_icg_bitmap(hal->syscon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_IEEE802154:
|
||||||
|
bitmap = modem_syscon_ll_get_ieee802154_icg_bitmap(hal->syscon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_LP_APB:
|
||||||
|
bitmap = modem_lpcon_ll_get_lp_apb_icg_bitmap(hal->lpcon_dev);
|
||||||
|
break;
|
||||||
|
case MODEM_CLOCK_DOMAIN_I2C_MASTER:
|
||||||
|
bitmap = modem_lpcon_ll_get_i2c_master_icg_bitmap(hal->lpcon_dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(0);
|
||||||
|
}
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
void IRAM_ATTR modem_clock_hal_enable_modem_common_fe_clock(modem_clock_hal_context_t *hal, bool enable)
|
void IRAM_ATTR modem_clock_hal_enable_modem_common_fe_clock(modem_clock_hal_context_t *hal, bool enable)
|
||||||
{
|
{
|
||||||
modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable);
|
modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable);
|
||||||
|
@@ -83,6 +83,10 @@ config SOC_LP_TIMER_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_LP_AON_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_REG_I2C_SUPPORTED
|
config SOC_REG_I2C_SUPPORTED
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
@@ -847,6 +851,10 @@ config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_UART_SUPPORT_SLEEP_RETENTION
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
config SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
@@ -875,10 +883,26 @@ config SOC_PHY_DIG_REGS_MEM_SIZE
|
|||||||
int
|
int
|
||||||
default 21
|
default 21
|
||||||
|
|
||||||
|
config SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_PM_SUPPORT_TOUCH_WAKEUP
|
config SOC_PM_SUPPORT_TOUCH_WAKEUP
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_SUPPORT_CPU_PD
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_SUPPORT_MODEM_PD
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_PM_SUPPORT_XTAL32K_PD
|
config SOC_PM_SUPPORT_XTAL32K_PD
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
@@ -895,6 +919,10 @@ config SOC_PM_SUPPORT_VDDSDIO_PD
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_SUPPORT_TOP_PD
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_PM_SUPPORT_HP_AON_PD
|
config SOC_PM_SUPPORT_HP_AON_PD
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
@@ -903,6 +931,18 @@ config SOC_PM_SUPPORT_MAC_BB_PD
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_CPU_RETENTION_BY_SW
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_MODEM_RETENTION_BY_REGDMA
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_PM_MODEM_CLK_CONF_RETENTION
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_PM_PAU_LINK_NUM
|
config SOC_PM_PAU_LINK_NUM
|
||||||
int
|
int
|
||||||
default 4
|
default 4
|
||||||
|
@@ -74,7 +74,7 @@
|
|||||||
#define SOC_PMU_SUPPORTED 1 // TODO: [ESP32H4] IDF-12286
|
#define SOC_PMU_SUPPORTED 1 // TODO: [ESP32H4] IDF-12286
|
||||||
#define SOC_PAU_SUPPORTED 1
|
#define SOC_PAU_SUPPORTED 1
|
||||||
#define SOC_LP_TIMER_SUPPORTED 1
|
#define SOC_LP_TIMER_SUPPORTED 1
|
||||||
// #define SOC_LP_AON_SUPPORTED 1
|
#define SOC_LP_AON_SUPPORTED 1
|
||||||
// #define SOC_LP_PERIPHERALS_SUPPORTED 1
|
// #define SOC_LP_PERIPHERALS_SUPPORTED 1
|
||||||
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32H4] IDF-12449
|
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32H4] IDF-12449
|
||||||
// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32H4] IDF-12445 IDF-12451
|
// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32H4] IDF-12445 IDF-12451
|
||||||
@@ -488,7 +488,7 @@
|
|||||||
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
|
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
|
||||||
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)
|
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)
|
||||||
|
|
||||||
// #define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */
|
#define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */
|
||||||
|
|
||||||
// #define SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN 5
|
// #define SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN 5
|
||||||
#define SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE (1)
|
#define SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE (1)
|
||||||
@@ -513,16 +513,16 @@
|
|||||||
// TODO: IDF-12286 (inherit from verify code, need check)
|
// TODO: IDF-12286 (inherit from verify code, need check)
|
||||||
/*-------------------------- Power Management CAPS ----------------------------*/
|
/*-------------------------- Power Management CAPS ----------------------------*/
|
||||||
// #define SOC_PM_SUPPORT_BT_WAKEUP (1)
|
// #define SOC_PM_SUPPORT_BT_WAKEUP (1)
|
||||||
// #define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
|
#define SOC_PM_SUPPORT_EXT1_WAKEUP (1)
|
||||||
// #define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
|
#define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*!<Supports one bit per pin to configure the EXT1 trigger level */
|
||||||
#define SOC_PM_SUPPORT_TOUCH_WAKEUP (1)
|
#define SOC_PM_SUPPORT_TOUCH_WAKEUP (1)
|
||||||
// #define SOC_PM_SUPPORT_CPU_PD (1)
|
#define SOC_PM_SUPPORT_CPU_PD (1)
|
||||||
// #define SOC_PM_SUPPORT_MODEM_PD (1)
|
#define SOC_PM_SUPPORT_MODEM_PD (1)
|
||||||
#define SOC_PM_SUPPORT_XTAL32K_PD (1)
|
#define SOC_PM_SUPPORT_XTAL32K_PD (1)
|
||||||
#define SOC_PM_SUPPORT_RC32K_PD (1)
|
#define SOC_PM_SUPPORT_RC32K_PD (1)
|
||||||
#define SOC_PM_SUPPORT_RC_FAST_PD (1)
|
#define SOC_PM_SUPPORT_RC_FAST_PD (1)
|
||||||
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
|
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
|
||||||
// #define SOC_PM_SUPPORT_TOP_PD (1)
|
#define SOC_PM_SUPPORT_TOP_PD (1)
|
||||||
#define SOC_PM_SUPPORT_HP_AON_PD (1)
|
#define SOC_PM_SUPPORT_HP_AON_PD (1)
|
||||||
#define SOC_PM_SUPPORT_MAC_BB_PD (1)
|
#define SOC_PM_SUPPORT_MAC_BB_PD (1)
|
||||||
// #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) // TODO: [ESP32H4] PM-484
|
// #define SOC_PM_SUPPORT_RTC_PERIPH_PD (1) // TODO: [ESP32H4] PM-484
|
||||||
@@ -531,9 +531,9 @@
|
|||||||
// /* macro redefine for pass esp_wifi headers md5sum check */
|
// /* macro redefine for pass esp_wifi headers md5sum check */
|
||||||
// #define MAC_SUPPORT_PMU_MODEM_STATE SOC_PM_SUPPORT_PMU_MODEM_STATE
|
// #define MAC_SUPPORT_PMU_MODEM_STATE SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||||
|
|
||||||
// #define SOC_PM_CPU_RETENTION_BY_SW (1)
|
#define SOC_PM_CPU_RETENTION_BY_SW (1)
|
||||||
// #define SOC_PM_MODEM_RETENTION_BY_REGDMA (1)
|
#define SOC_PM_MODEM_RETENTION_BY_REGDMA (1)
|
||||||
// #define SOC_PM_RETENTION_HAS_CLOCK_BUG (1)
|
#define SOC_PM_MODEM_CLK_CONF_RETENTION (1) /*!< In esp32H4, i2c lpcon is placed in modem domain*/
|
||||||
|
|
||||||
#define SOC_PM_PAU_LINK_NUM (4)
|
#define SOC_PM_PAU_LINK_NUM (4)
|
||||||
#define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)
|
#define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)
|
||||||
|
82
components/soc/esp32h4/include/soc/system_periph_retention.h
Normal file
82
components/soc/esp32h4/include/soc/system_periph_retention.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "soc/regdma.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to interrupt matrix configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define INT_MTX_RETENTION_LINK_LEN 2
|
||||||
|
extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to hp_system configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define HP_SYSTEM_RETENTION_LINK_LEN 2
|
||||||
|
extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to TEE_APM configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define TEE_APM_RETENTION_LINK_LEN 3
|
||||||
|
extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN];
|
||||||
|
#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1
|
||||||
|
extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to IOMUX configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define IOMUX_RETENTION_LINK_LEN 5
|
||||||
|
extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to spimem configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define SPIMEM_RETENTION_LINK_LEN 5
|
||||||
|
extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide access to systimer configuration registers retention
|
||||||
|
* context definition.
|
||||||
|
*
|
||||||
|
* This is an internal function of the sleep retention driver, and is not
|
||||||
|
* useful for external use.
|
||||||
|
*/
|
||||||
|
#define SYSTIMER_RETENTION_LINK_LEN 19
|
||||||
|
extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -10,6 +10,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DR_REG_INTERRUPT_BASE(i) (DR_REG_INTMTX0_BASE + (i) * 0x1000)
|
||||||
|
|
||||||
/** INTERRUPT_CORE0_WIFI_MAC_INTR_MAP_REG register
|
/** INTERRUPT_CORE0_WIFI_MAC_INTR_MAP_REG register
|
||||||
* WIFI_MAC_INTR mapping register
|
* WIFI_MAC_INTR mapping register
|
||||||
*/
|
*/
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "soc/soc.h"
|
#include "soc/soc.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@@ -14,7 +14,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_OUT_REG register
|
/** LP_GPIO_OUT_REG register
|
||||||
* LP_GPIO output register
|
* LP_GPIO output register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_OUT_REG (DR_REG_LP_BASE + 0x4)
|
#define LP_GPIO_OUT_REG (DR_REG_LP_GPIO_BASE + 0x4)
|
||||||
/** LP_GPIO_OUT_DATA_ORIG : R/W/WTC; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_OUT_DATA_ORIG : R/W/WTC; bitpos: [5:0]; default: 0;
|
||||||
* Configures the output value of LP_GPIO0 ~ 5 output in simple LP_GPIO output mode.
|
* Configures the output value of LP_GPIO0 ~ 5 output in simple LP_GPIO output mode.
|
||||||
* 0: Low level
|
* 0: Low level
|
||||||
@@ -30,7 +30,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_OUT_W1TS_REG register
|
/** LP_GPIO_OUT_W1TS_REG register
|
||||||
* LP_GPIO output set register
|
* LP_GPIO output set register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_OUT_W1TS_REG (DR_REG_LP_BASE + 0x8)
|
#define LP_GPIO_OUT_W1TS_REG (DR_REG_LP_GPIO_BASE + 0x8)
|
||||||
/** LP_GPIO_OUT_W1TS : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_OUT_W1TS : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to set the output register LP_GPIO_OUT_REG of LP_GPIO0 ~
|
* Configures whether or not to set the output register LP_GPIO_OUT_REG of LP_GPIO0 ~
|
||||||
* LP_GPIO5.
|
* LP_GPIO5.
|
||||||
@@ -47,7 +47,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_OUT_W1TC_REG register
|
/** LP_GPIO_OUT_W1TC_REG register
|
||||||
* LP_GPIO output clear register
|
* LP_GPIO output clear register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_OUT_W1TC_REG (DR_REG_LP_BASE + 0xc)
|
#define LP_GPIO_OUT_W1TC_REG (DR_REG_LP_GPIO_BASE + 0xc)
|
||||||
/** LP_GPIO_OUT_W1TC : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_OUT_W1TC : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to clear the output register LP_GPIO_OUT_REG of LP_GPIO0
|
* Configures whether or not to clear the output register LP_GPIO_OUT_REG of LP_GPIO0
|
||||||
* ~ LP_GPIO5 output.
|
* ~ LP_GPIO5 output.
|
||||||
@@ -64,7 +64,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_ENABLE_REG register
|
/** LP_GPIO_ENABLE_REG register
|
||||||
* LP_GPIO output enable register
|
* LP_GPIO output enable register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_ENABLE_REG (DR_REG_LP_BASE + 0x10)
|
#define LP_GPIO_ENABLE_REG (DR_REG_LP_GPIO_BASE + 0x10)
|
||||||
/** LP_GPIO_ENABLE_DATA : R/W/WTC; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_ENABLE_DATA : R/W/WTC; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO0 ~ LP_GPIO5.
|
* Configures whether or not to enable the output of LP_GPIO0 ~ LP_GPIO5.
|
||||||
* 0: Not enable
|
* 0: Not enable
|
||||||
@@ -79,7 +79,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_ENABLE_W1TS_REG register
|
/** LP_GPIO_ENABLE_W1TS_REG register
|
||||||
* LP_GPIO output enable set register
|
* LP_GPIO output enable set register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_ENABLE_W1TS_REG (DR_REG_LP_BASE + 0x14)
|
#define LP_GPIO_ENABLE_W1TS_REG (DR_REG_LP_GPIO_BASE + 0x14)
|
||||||
/** LP_GPIO_ENABLE_W1TS : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_ENABLE_W1TS : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to set the output enable register LP_GPIO_ENABLE_REG of
|
* Configures whether or not to set the output enable register LP_GPIO_ENABLE_REG of
|
||||||
* LP_GPIO0 ~ LP_GPIO5.
|
* LP_GPIO0 ~ LP_GPIO5.
|
||||||
@@ -96,7 +96,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_ENABLE_W1TC_REG register
|
/** LP_GPIO_ENABLE_W1TC_REG register
|
||||||
* LP_GPIO output enable clear register
|
* LP_GPIO output enable clear register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_ENABLE_W1TC_REG (DR_REG_LP_BASE + 0x18)
|
#define LP_GPIO_ENABLE_W1TC_REG (DR_REG_LP_GPIO_BASE + 0x18)
|
||||||
/** LP_GPIO_ENABLE_W1TC : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_ENABLE_W1TC : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to clear the output enable register LP_GPIO_ENABLE_REG of
|
* Configures whether or not to clear the output enable register LP_GPIO_ENABLE_REG of
|
||||||
* LP_GPIO0 ~ LP_GPIO5.
|
* LP_GPIO0 ~ LP_GPIO5.
|
||||||
@@ -113,7 +113,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_IN_REG register
|
/** LP_GPIO_IN_REG register
|
||||||
* LP_GPIO input register
|
* LP_GPIO input register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_IN_REG (DR_REG_LP_BASE + 0x1c)
|
#define LP_GPIO_IN_REG (DR_REG_LP_GPIO_BASE + 0x1c)
|
||||||
/** LP_GPIO_IN_DATA_NEXT : RO; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_IN_DATA_NEXT : RO; bitpos: [5:0]; default: 0;
|
||||||
* Represents the input value of LP_GPIO0 ~ LP_GPIO5. Each bit represents a pin input
|
* Represents the input value of LP_GPIO0 ~ LP_GPIO5. Each bit represents a pin input
|
||||||
* value:
|
* value:
|
||||||
@@ -129,7 +129,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_STATUS_REG register
|
/** LP_GPIO_STATUS_REG register
|
||||||
* LP_GPIO interrupt status register
|
* LP_GPIO interrupt status register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_STATUS_REG (DR_REG_LP_BASE + 0x20)
|
#define LP_GPIO_STATUS_REG (DR_REG_LP_GPIO_BASE + 0x20)
|
||||||
/** LP_GPIO_STATUS_INTERRUPT : R/W/WTC; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_STATUS_INTERRUPT : R/W/WTC; bitpos: [5:0]; default: 0;
|
||||||
* The interrupt status of LP_GPIO0 ~ LP_GPIO5, can be configured by the software.
|
* The interrupt status of LP_GPIO0 ~ LP_GPIO5, can be configured by the software.
|
||||||
*
|
*
|
||||||
@@ -150,7 +150,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_STATUS_W1TS_REG register
|
/** LP_GPIO_STATUS_W1TS_REG register
|
||||||
* LP_GPIO interrupt status set register
|
* LP_GPIO interrupt status set register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_STATUS_W1TS_REG (DR_REG_LP_BASE + 0x24)
|
#define LP_GPIO_STATUS_W1TS_REG (DR_REG_LP_GPIO_BASE + 0x24)
|
||||||
/** LP_GPIO_STATUS_W1TS : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_STATUS_W1TS : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to set the interrupt status register
|
* Configures whether or not to set the interrupt status register
|
||||||
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
|
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
|
||||||
@@ -168,7 +168,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_STATUS_W1TC_REG register
|
/** LP_GPIO_STATUS_W1TC_REG register
|
||||||
* LP_GPIO interrupt status clear register
|
* LP_GPIO interrupt status clear register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_STATUS_W1TC_REG (DR_REG_LP_BASE + 0x28)
|
#define LP_GPIO_STATUS_W1TC_REG (DR_REG_LP_GPIO_BASE + 0x28)
|
||||||
/** LP_GPIO_STATUS_W1TC : WT; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_STATUS_W1TC : WT; bitpos: [5:0]; default: 0;
|
||||||
* Configures whether or not to clear the interrupt status register
|
* Configures whether or not to clear the interrupt status register
|
||||||
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
|
* LP_GPIO_STATUS_INTERRUPT of LP_GPIO0 ~ LP_GPIO5.
|
||||||
@@ -186,7 +186,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_STATUS_NEXT_REG register
|
/** LP_GPIO_STATUS_NEXT_REG register
|
||||||
* LP_GPIO interrupt source register
|
* LP_GPIO interrupt source register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_STATUS_NEXT_REG (DR_REG_LP_BASE + 0x2c)
|
#define LP_GPIO_STATUS_NEXT_REG (DR_REG_LP_GPIO_BASE + 0x2c)
|
||||||
/** LP_GPIO_STATUS_INTERRUPT_NEXT : RO; bitpos: [5:0]; default: 0;
|
/** LP_GPIO_STATUS_INTERRUPT_NEXT : RO; bitpos: [5:0]; default: 0;
|
||||||
* Represents the interrupt source signal of LP_GPIO0 ~ LP_GPIO5.
|
* Represents the interrupt source signal of LP_GPIO0 ~ LP_GPIO5.
|
||||||
* Bit0 ~ bit24 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
|
* Bit0 ~ bit24 are corresponding to LP_GPIO0 ~ LP_GPIO5. Bitxx ~ bitxx is invalid.
|
||||||
@@ -204,7 +204,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN0_REG register
|
/** LP_GPIO_PIN0_REG register
|
||||||
* LP_GPIO0 configuration register
|
* LP_GPIO0 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN0_REG (DR_REG_LP_BASE + 0x30)
|
#define LP_GPIO_PIN0_REG (DR_REG_LP_GPIO_BASE + 0x30)
|
||||||
/** LP_GPIO_PIN0_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN0_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -272,7 +272,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN1_REG register
|
/** LP_GPIO_PIN1_REG register
|
||||||
* LP_GPIO1 configuration register
|
* LP_GPIO1 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN1_REG (DR_REG_LP_BASE + 0x34)
|
#define LP_GPIO_PIN1_REG (DR_REG_LP_GPIO_BASE + 0x34)
|
||||||
/** LP_GPIO_PIN1_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN1_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -340,7 +340,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN2_REG register
|
/** LP_GPIO_PIN2_REG register
|
||||||
* LP_GPIO2 configuration register
|
* LP_GPIO2 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN2_REG (DR_REG_LP_BASE + 0x38)
|
#define LP_GPIO_PIN2_REG (DR_REG_LP_GPIO_BASE + 0x38)
|
||||||
/** LP_GPIO_PIN2_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN2_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -408,7 +408,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN3_REG register
|
/** LP_GPIO_PIN3_REG register
|
||||||
* LP_GPIO3 configuration register
|
* LP_GPIO3 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN3_REG (DR_REG_LP_BASE + 0x3c)
|
#define LP_GPIO_PIN3_REG (DR_REG_LP_GPIO_BASE + 0x3c)
|
||||||
/** LP_GPIO_PIN3_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN3_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -476,7 +476,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN4_REG register
|
/** LP_GPIO_PIN4_REG register
|
||||||
* LP_GPIO4 configuration register
|
* LP_GPIO4 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN4_REG (DR_REG_LP_BASE + 0x40)
|
#define LP_GPIO_PIN4_REG (DR_REG_LP_GPIO_BASE + 0x40)
|
||||||
/** LP_GPIO_PIN4_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN4_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -544,7 +544,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_PIN5_REG register
|
/** LP_GPIO_PIN5_REG register
|
||||||
* LP_GPIO5 configuration register
|
* LP_GPIO5 configuration register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_PIN5_REG (DR_REG_LP_BASE + 0x44)
|
#define LP_GPIO_PIN5_REG (DR_REG_LP_GPIO_BASE + 0x44)
|
||||||
/** LP_GPIO_PIN5_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
/** LP_GPIO_PIN5_SYNC2_BYPASS : R/W; bitpos: [1:0]; default: 0;
|
||||||
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
* Configures whether or not to synchronize LP_GPIO input data on either edge of LP IO
|
||||||
* MUX operating clock for the second-level synchronization.
|
* MUX operating clock for the second-level synchronization.
|
||||||
@@ -612,7 +612,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC0_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC0_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO0 output
|
* Configuration register for LP_GPIO0 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC0_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2b0)
|
#define LP_GPIO_FUNC0_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2b0)
|
||||||
/** LP_GPIO_FUNC0_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC0_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -635,7 +635,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC1_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC1_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO1 output
|
* Configuration register for LP_GPIO1 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC1_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2b4)
|
#define LP_GPIO_FUNC1_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2b4)
|
||||||
/** LP_GPIO_FUNC1_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC1_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -658,7 +658,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC2_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC2_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO2 output
|
* Configuration register for LP_GPIO2 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC2_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2b8)
|
#define LP_GPIO_FUNC2_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2b8)
|
||||||
/** LP_GPIO_FUNC2_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC2_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -681,7 +681,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC3_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC3_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO3 output
|
* Configuration register for LP_GPIO3 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC3_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2bc)
|
#define LP_GPIO_FUNC3_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2bc)
|
||||||
/** LP_GPIO_FUNC3_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC3_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -704,7 +704,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC4_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC4_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO4 output
|
* Configuration register for LP_GPIO4 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC4_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2c0)
|
#define LP_GPIO_FUNC4_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2c0)
|
||||||
/** LP_GPIO_FUNC4_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC4_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -727,7 +727,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_FUNC5_OUT_SEL_CFG_REG register
|
/** LP_GPIO_FUNC5_OUT_SEL_CFG_REG register
|
||||||
* Configuration register for LP_GPIO5 output
|
* Configuration register for LP_GPIO5 output
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_FUNC5_OUT_SEL_CFG_REG (DR_REG_LP_BASE + 0x2c4)
|
#define LP_GPIO_FUNC5_OUT_SEL_CFG_REG (DR_REG_LP_GPIO_BASE + 0x2c4)
|
||||||
/** LP_GPIO_FUNC5_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
/** LP_GPIO_FUNC5_OUT_INV_SEL : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to invert the output value.
|
* Configures whether or not to invert the output value.
|
||||||
* 0: Not invert
|
* 0: Not invert
|
||||||
@@ -750,7 +750,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_CLOCK_GATE_REG register
|
/** LP_GPIO_CLOCK_GATE_REG register
|
||||||
* LP_GPIO clock gate register
|
* LP_GPIO clock gate register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_CLOCK_GATE_REG (DR_REG_LP_BASE + 0x3f8)
|
#define LP_GPIO_CLOCK_GATE_REG (DR_REG_LP_GPIO_BASE + 0x3f8)
|
||||||
/** LP_GPIO_CLK_EN : R/W; bitpos: [0]; default: 1;
|
/** LP_GPIO_CLK_EN : R/W; bitpos: [0]; default: 1;
|
||||||
* Configures whether or not to enable clock gate.
|
* Configures whether or not to enable clock gate.
|
||||||
* 0: Not enable
|
* 0: Not enable
|
||||||
@@ -764,7 +764,7 @@ extern "C" {
|
|||||||
/** LP_GPIO_DATE_REG register
|
/** LP_GPIO_DATE_REG register
|
||||||
* LP_GPIO version register
|
* LP_GPIO version register
|
||||||
*/
|
*/
|
||||||
#define LP_GPIO_DATE_REG (DR_REG_LP_BASE + 0x3fc)
|
#define LP_GPIO_DATE_REG (DR_REG_LP_GPIO_BASE + 0x3fc)
|
||||||
/** LP_GPIO_DATE : R/W; bitpos: [27:0]; default: 37769744;
|
/** LP_GPIO_DATE : R/W; bitpos: [27:0]; default: 37769744;
|
||||||
* Version control register.
|
* Version control register.
|
||||||
*/
|
*/
|
||||||
|
@@ -14,7 +14,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO0_REG register
|
/** LP_IO_MUX_GPIO0_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO0
|
* LP IO MUX configuration register for LP_GPIO0
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO0_REG (DR_REG_LP_BASE + 0x0)
|
#define LP_IO_MUX_GPIO0_REG (DR_REG_LP_IO_MUX_BASE + 0x0)
|
||||||
/** LP_IO_MUX_GPIO0_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO0_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO0 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO0 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -151,7 +151,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO1_REG register
|
/** LP_IO_MUX_GPIO1_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO1
|
* LP IO MUX configuration register for LP_GPIO1
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO1_REG (DR_REG_LP_BASE + 0x4)
|
#define LP_IO_MUX_GPIO1_REG (DR_REG_LP_IO_MUX_BASE + 0x4)
|
||||||
/** LP_IO_MUX_GPIO1_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO1_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO1 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO1 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -288,7 +288,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO2_REG register
|
/** LP_IO_MUX_GPIO2_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO2
|
* LP IO MUX configuration register for LP_GPIO2
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO2_REG (DR_REG_LP_BASE + 0x8)
|
#define LP_IO_MUX_GPIO2_REG (DR_REG_LP_IO_MUX_BASE + 0x8)
|
||||||
/** LP_IO_MUX_GPIO2_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO2_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO2 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO2 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -425,7 +425,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO3_REG register
|
/** LP_IO_MUX_GPIO3_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO3
|
* LP IO MUX configuration register for LP_GPIO3
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO3_REG (DR_REG_LP_BASE + 0xc)
|
#define LP_IO_MUX_GPIO3_REG (DR_REG_LP_IO_MUX_BASE + 0xc)
|
||||||
/** LP_IO_MUX_GPIO3_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO3_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO3 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO3 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -562,7 +562,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO4_REG register
|
/** LP_IO_MUX_GPIO4_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO4
|
* LP IO MUX configuration register for LP_GPIO4
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO4_REG (DR_REG_LP_BASE + 0x10)
|
#define LP_IO_MUX_GPIO4_REG (DR_REG_LP_IO_MUX_BASE + 0x10)
|
||||||
/** LP_IO_MUX_GPIO4_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO4_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO4 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO4 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -699,7 +699,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_GPIO5_REG register
|
/** LP_IO_MUX_GPIO5_REG register
|
||||||
* LP IO MUX configuration register for LP_GPIO5
|
* LP IO MUX configuration register for LP_GPIO5
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_GPIO5_REG (DR_REG_LP_BASE + 0x14)
|
#define LP_IO_MUX_GPIO5_REG (DR_REG_LP_IO_MUX_BASE + 0x14)
|
||||||
/** LP_IO_MUX_GPIO5_MCU_OE : R/W; bitpos: [0]; default: 0;
|
/** LP_IO_MUX_GPIO5_MCU_OE : R/W; bitpos: [0]; default: 0;
|
||||||
* Configures whether or not to enable the output of LP_GPIO5 in sleep mode.
|
* Configures whether or not to enable the output of LP_GPIO5 in sleep mode.
|
||||||
* 0: Disable
|
* 0: Disable
|
||||||
@@ -836,7 +836,7 @@ extern "C" {
|
|||||||
/** LP_IO_MUX_DATE_REG register
|
/** LP_IO_MUX_DATE_REG register
|
||||||
* Version control register
|
* Version control register
|
||||||
*/
|
*/
|
||||||
#define LP_IO_MUX_DATE_REG (DR_REG_LP_BASE + 0x1fc)
|
#define LP_IO_MUX_DATE_REG (DR_REG_LP_IO_MUX_BASE + 0x1fc)
|
||||||
/** LP_IO_MUX_REG_DATE : R/W; bitpos: [27:0]; default: 37769744;
|
/** LP_IO_MUX_REG_DATE : R/W; bitpos: [27:0]; default: 37769744;
|
||||||
* Version control register
|
* Version control register
|
||||||
*/
|
*/
|
||||||
|
@@ -14,7 +14,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_TAR0_LOW_REG register
|
/** LP_TIMER_TAR0_LOW_REG register
|
||||||
* RTC timer threshold low bits register0
|
* RTC timer threshold low bits register0
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_TAR0_LOW_REG (DR_REG_LP_BASE + 0x0)
|
#define LP_TIMER_TAR0_LOW_REG (DR_REG_LP_TIMER_BASE + 0x0)
|
||||||
/** LP_TIMER_MAIN_TIMER_TAR_LOW0 : R/W; bitpos: [31:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_TAR_LOW0 : R/W; bitpos: [31:0]; default: 0;
|
||||||
* Configures the lower 32 bits of the trigger threshold for the RTC timer compare0.
|
* Configures the lower 32 bits of the trigger threshold for the RTC timer compare0.
|
||||||
*/
|
*/
|
||||||
@@ -26,7 +26,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_TAR0_HIGH_REG register
|
/** LP_TIMER_TAR0_HIGH_REG register
|
||||||
* RTC timer enable register0
|
* RTC timer enable register0
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_TAR0_HIGH_REG (DR_REG_LP_BASE + 0x4)
|
#define LP_TIMER_TAR0_HIGH_REG (DR_REG_LP_TIMER_BASE + 0x4)
|
||||||
/** LP_TIMER_MAIN_TIMER_TAR_HIGH0 : R/W; bitpos: [15:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_TAR_HIGH0 : R/W; bitpos: [15:0]; default: 0;
|
||||||
* Configures the higher 16 bits of the trigger threshold for the RTC timer compare0
|
* Configures the higher 16 bits of the trigger threshold for the RTC timer compare0
|
||||||
*/
|
*/
|
||||||
@@ -47,7 +47,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_TAR1_LOW_REG register
|
/** LP_TIMER_TAR1_LOW_REG register
|
||||||
* RTC timer threshold low bits register1
|
* RTC timer threshold low bits register1
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_TAR1_LOW_REG (DR_REG_LP_BASE + 0x8)
|
#define LP_TIMER_TAR1_LOW_REG (DR_REG_LP_TIMER_BASE + 0x8)
|
||||||
/** LP_TIMER_MAIN_TIMER_TAR_LOW1 : R/W; bitpos: [31:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_TAR_LOW1 : R/W; bitpos: [31:0]; default: 0;
|
||||||
* Configures the lower 32 bits of the trigger threshold for the RTC timer compare1.
|
* Configures the lower 32 bits of the trigger threshold for the RTC timer compare1.
|
||||||
*/
|
*/
|
||||||
@@ -59,7 +59,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_TAR1_HIGH_REG register
|
/** LP_TIMER_TAR1_HIGH_REG register
|
||||||
* RTC timer threshold high bits register0
|
* RTC timer threshold high bits register0
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_TAR1_HIGH_REG (DR_REG_LP_BASE + 0xc)
|
#define LP_TIMER_TAR1_HIGH_REG (DR_REG_LP_TIMER_BASE + 0xc)
|
||||||
/** LP_TIMER_MAIN_TIMER_TAR_HIGH1 : R/W; bitpos: [15:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_TAR_HIGH1 : R/W; bitpos: [15:0]; default: 0;
|
||||||
* Configures the higher 16 bits of the trigger threshold for the RTC timer compare1
|
* Configures the higher 16 bits of the trigger threshold for the RTC timer compare1
|
||||||
*/
|
*/
|
||||||
@@ -80,7 +80,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_UPDATE_REG register
|
/** LP_TIMER_UPDATE_REG register
|
||||||
* RTC timer update control register
|
* RTC timer update control register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_UPDATE_REG (DR_REG_LP_BASE + 0x10)
|
#define LP_TIMER_UPDATE_REG (DR_REG_LP_TIMER_BASE + 0x10)
|
||||||
/** LP_TIMER_MAIN_TIMER_UPDATE : WT; bitpos: [27]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_UPDATE : WT; bitpos: [27]; default: 0;
|
||||||
* Triggers timer by software
|
* Triggers timer by software
|
||||||
*/
|
*/
|
||||||
@@ -123,7 +123,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_MAIN_BUF0_LOW_REG register
|
/** LP_TIMER_MAIN_BUF0_LOW_REG register
|
||||||
* RTC timer buffer0 low bits register
|
* RTC timer buffer0 low bits register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_MAIN_BUF0_LOW_REG (DR_REG_LP_BASE + 0x14)
|
#define LP_TIMER_MAIN_BUF0_LOW_REG (DR_REG_LP_TIMER_BASE + 0x14)
|
||||||
/** LP_TIMER_MAIN_TIMER_BUF0_LOW : RO; bitpos: [31:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_BUF0_LOW : RO; bitpos: [31:0]; default: 0;
|
||||||
* RTC timer buffer0 low bits register
|
* RTC timer buffer0 low bits register
|
||||||
*/
|
*/
|
||||||
@@ -135,7 +135,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_MAIN_BUF0_HIGH_REG register
|
/** LP_TIMER_MAIN_BUF0_HIGH_REG register
|
||||||
* RTC timer buffer0 high bits register
|
* RTC timer buffer0 high bits register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_MAIN_BUF0_HIGH_REG (DR_REG_LP_BASE + 0x18)
|
#define LP_TIMER_MAIN_BUF0_HIGH_REG (DR_REG_LP_TIMER_BASE + 0x18)
|
||||||
/** LP_TIMER_MAIN_TIMER_BUF0_HIGH : RO; bitpos: [15:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_BUF0_HIGH : RO; bitpos: [15:0]; default: 0;
|
||||||
* RTC timer buffer0 high bits register
|
* RTC timer buffer0 high bits register
|
||||||
*/
|
*/
|
||||||
@@ -147,7 +147,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_MAIN_BUF1_LOW_REG register
|
/** LP_TIMER_MAIN_BUF1_LOW_REG register
|
||||||
* RTC timer buffer1 low bits register
|
* RTC timer buffer1 low bits register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_MAIN_BUF1_LOW_REG (DR_REG_LP_BASE + 0x1c)
|
#define LP_TIMER_MAIN_BUF1_LOW_REG (DR_REG_LP_TIMER_BASE + 0x1c)
|
||||||
/** LP_TIMER_MAIN_TIMER_BUF1_LOW : RO; bitpos: [31:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_BUF1_LOW : RO; bitpos: [31:0]; default: 0;
|
||||||
* RTC timer buffer1 low bits register
|
* RTC timer buffer1 low bits register
|
||||||
*/
|
*/
|
||||||
@@ -159,7 +159,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_MAIN_BUF1_HIGH_REG register
|
/** LP_TIMER_MAIN_BUF1_HIGH_REG register
|
||||||
* RTC timer buffer1 high bits register
|
* RTC timer buffer1 high bits register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_MAIN_BUF1_HIGH_REG (DR_REG_LP_BASE + 0x20)
|
#define LP_TIMER_MAIN_BUF1_HIGH_REG (DR_REG_LP_TIMER_BASE + 0x20)
|
||||||
/** LP_TIMER_MAIN_TIMER_BUF1_HIGH : RO; bitpos: [15:0]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_BUF1_HIGH : RO; bitpos: [15:0]; default: 0;
|
||||||
* RTC timer buffer1 high bits register
|
* RTC timer buffer1 high bits register
|
||||||
*/
|
*/
|
||||||
@@ -171,7 +171,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_INT_RAW_REG register
|
/** LP_TIMER_INT_RAW_REG register
|
||||||
* RTC timer interrupt raw register
|
* RTC timer interrupt raw register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_INT_RAW_REG (DR_REG_LP_BASE + 0x28)
|
#define LP_TIMER_INT_RAW_REG (DR_REG_LP_TIMER_BASE + 0x28)
|
||||||
/** LP_TIMER_OVERFLOW_RAW : R/WTC/SS; bitpos: [30]; default: 0;
|
/** LP_TIMER_OVERFLOW_RAW : R/WTC/SS; bitpos: [30]; default: 0;
|
||||||
* Triggered when counter register of RTC main timer overflow.
|
* Triggered when counter register of RTC main timer overflow.
|
||||||
*/
|
*/
|
||||||
@@ -190,7 +190,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_INT_ST_REG register
|
/** LP_TIMER_INT_ST_REG register
|
||||||
* RTC timer interrupt status register
|
* RTC timer interrupt status register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_INT_ST_REG (DR_REG_LP_BASE + 0x2c)
|
#define LP_TIMER_INT_ST_REG (DR_REG_LP_TIMER_BASE + 0x2c)
|
||||||
/** LP_TIMER_OVERFLOW_ST : RO; bitpos: [30]; default: 0;
|
/** LP_TIMER_OVERFLOW_ST : RO; bitpos: [30]; default: 0;
|
||||||
* Status of RTC main timer overflow interrupt .
|
* Status of RTC main timer overflow interrupt .
|
||||||
*/
|
*/
|
||||||
@@ -209,7 +209,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_INT_ENA_REG register
|
/** LP_TIMER_INT_ENA_REG register
|
||||||
* RTC timer interrupt enable register
|
* RTC timer interrupt enable register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_INT_ENA_REG (DR_REG_LP_BASE + 0x30)
|
#define LP_TIMER_INT_ENA_REG (DR_REG_LP_TIMER_BASE + 0x30)
|
||||||
/** LP_TIMER_OVERFLOW_ENA : R/W; bitpos: [30]; default: 0;
|
/** LP_TIMER_OVERFLOW_ENA : R/W; bitpos: [30]; default: 0;
|
||||||
* Enable the RTC main timer overflow interrupt..
|
* Enable the RTC main timer overflow interrupt..
|
||||||
* 0 : Disable
|
* 0 : Disable
|
||||||
@@ -232,7 +232,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_INT_CLR_REG register
|
/** LP_TIMER_INT_CLR_REG register
|
||||||
* RTC timer interrupt clear register
|
* RTC timer interrupt clear register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_INT_CLR_REG (DR_REG_LP_BASE + 0x34)
|
#define LP_TIMER_INT_CLR_REG (DR_REG_LP_TIMER_BASE + 0x34)
|
||||||
/** LP_TIMER_OVERFLOW_CLR : WT; bitpos: [30]; default: 0;
|
/** LP_TIMER_OVERFLOW_CLR : WT; bitpos: [30]; default: 0;
|
||||||
* Clear the RTC main timer overflow raw interrupt..
|
* Clear the RTC main timer overflow raw interrupt..
|
||||||
*/
|
*/
|
||||||
@@ -251,7 +251,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_LP_INT_RAW_REG register
|
/** LP_TIMER_LP_INT_RAW_REG register
|
||||||
* RTC timer interrupt raw register(For ULP)
|
* RTC timer interrupt raw register(For ULP)
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_LP_INT_RAW_REG (DR_REG_LP_BASE + 0x38)
|
#define LP_TIMER_LP_INT_RAW_REG (DR_REG_LP_TIMER_BASE + 0x38)
|
||||||
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_RAW : R/WTC/SS; bitpos: [30]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_RAW : R/WTC/SS; bitpos: [30]; default: 0;
|
||||||
* Triggered when counter register of RTC main timer overflow
|
* Triggered when counter register of RTC main timer overflow
|
||||||
*/
|
*/
|
||||||
@@ -270,7 +270,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_LP_INT_ST_REG register
|
/** LP_TIMER_LP_INT_ST_REG register
|
||||||
* RTC timer interrupt status register(For ULP)
|
* RTC timer interrupt status register(For ULP)
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_LP_INT_ST_REG (DR_REG_LP_BASE + 0x3c)
|
#define LP_TIMER_LP_INT_ST_REG (DR_REG_LP_TIMER_BASE + 0x3c)
|
||||||
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_ST : RO; bitpos: [30]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_ST : RO; bitpos: [30]; default: 0;
|
||||||
* Status of RTC main timer overflow interrupt .
|
* Status of RTC main timer overflow interrupt .
|
||||||
*/
|
*/
|
||||||
@@ -289,7 +289,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_LP_INT_ENA_REG register
|
/** LP_TIMER_LP_INT_ENA_REG register
|
||||||
* RTC timer interrupt enable register(For ULP)
|
* RTC timer interrupt enable register(For ULP)
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_LP_INT_ENA_REG (DR_REG_LP_BASE + 0x40)
|
#define LP_TIMER_LP_INT_ENA_REG (DR_REG_LP_TIMER_BASE + 0x40)
|
||||||
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_ENA : R/W; bitpos: [30]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_ENA : R/W; bitpos: [30]; default: 0;
|
||||||
* Enable the RTC main timer overflow interrupt..
|
* Enable the RTC main timer overflow interrupt..
|
||||||
* 0 : Disable
|
* 0 : Disable
|
||||||
@@ -312,7 +312,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_LP_INT_CLR_REG register
|
/** LP_TIMER_LP_INT_CLR_REG register
|
||||||
* RTC timer interrupt clear register(For ULP)
|
* RTC timer interrupt clear register(For ULP)
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_LP_INT_CLR_REG (DR_REG_LP_BASE + 0x44)
|
#define LP_TIMER_LP_INT_CLR_REG (DR_REG_LP_TIMER_BASE + 0x44)
|
||||||
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_CLR : WT; bitpos: [30]; default: 0;
|
/** LP_TIMER_MAIN_TIMER_OVERFLOW_LP_INT_CLR : WT; bitpos: [30]; default: 0;
|
||||||
* Clear the RTC main timer overflow clear interrupt..
|
* Clear the RTC main timer overflow clear interrupt..
|
||||||
*/
|
*/
|
||||||
@@ -331,7 +331,7 @@ extern "C" {
|
|||||||
/** LP_TIMER_DATE_REG register
|
/** LP_TIMER_DATE_REG register
|
||||||
* Date register
|
* Date register
|
||||||
*/
|
*/
|
||||||
#define LP_TIMER_DATE_REG (DR_REG_LP_BASE + 0x3fc)
|
#define LP_TIMER_DATE_REG (DR_REG_LP_TIMER_BASE + 0x3fc)
|
||||||
/** LP_TIMER_DATE : R/W; bitpos: [30:0]; default: 36769936;
|
/** LP_TIMER_DATE : R/W; bitpos: [30:0]; default: 36769936;
|
||||||
* Version data
|
* Version data
|
||||||
*/
|
*/
|
||||||
|
110
components/soc/esp32h4/system_retention_periph.c
Normal file
110
components/soc/esp32h4/system_retention_periph.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/regdma.h"
|
||||||
|
#include "soc/system_periph_retention.h"
|
||||||
|
#include "soc/timer_periph.h"
|
||||||
|
#include "soc/uart_reg.h"
|
||||||
|
#include "soc/systimer_reg.h"
|
||||||
|
#include "soc/timer_group_reg.h"
|
||||||
|
#include "soc/spi_mem_reg.h"
|
||||||
|
#include "soc/hp_system_reg.h"
|
||||||
|
#include "soc/tee_reg.h"
|
||||||
|
#include "soc/hp_apm_reg.h"
|
||||||
|
#include "soc/gpio_reg.h"
|
||||||
|
#include "soc/io_mux_reg.h"
|
||||||
|
#include "soc/interrupt_matrix_reg.h"
|
||||||
|
#include "soc/clic_reg.h"
|
||||||
|
|
||||||
|
/* Interrupt Matrix Registers Context */
|
||||||
|
#define N_REGS_INTR_MATRIX(i) (((INTERRUPT_CORE0_CLOCK_GATE_REG(i) - (DR_REG_INTERRUPT_CORE0_BASE + (i) * 0x1000)) / 4) + 1)
|
||||||
|
const regdma_entries_config_t intr_matrix_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_CORE0_BASE, DR_REG_INTERRUPT_CORE0_BASE, N_REGS_INTR_MATRIX(0), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* intr matrix */
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(1), DR_REG_INTERRUPT_CORE1_BASE, DR_REG_INTERRUPT_CORE1_BASE, N_REGS_INTR_MATRIX(1), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */
|
||||||
|
};
|
||||||
|
_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions");
|
||||||
|
|
||||||
|
/* HP System Registers Context */
|
||||||
|
#define N_REGS_HP_SYSTEM_0() (((HP_SYSTEM_CORE_DEBUG_RUNSTALL_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1)
|
||||||
|
#define N_REGS_HP_SYSTEM_1() (((HP_SYSTEM_AXI_MST_PRI_REG - HP_SYSTEM_SPROM_CTRL_REG) / 4) + 1)
|
||||||
|
const regdma_entries_config_t hp_system_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0x0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0x1), HP_SYSTEM_SPROM_CTRL_REG, HP_SYSTEM_SPROM_CTRL_REG, N_REGS_HP_SYSTEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
};
|
||||||
|
_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions");
|
||||||
|
|
||||||
|
/* TEE/APM Registers Context */
|
||||||
|
#define N_REGS_TEE_0() (((TEE_ZERO_DET_CTRL_REG - DR_REG_TEE_BASE) / 4) + 1)
|
||||||
|
#define N_REGS_TEE_1() (((TEE_CLOCK_GATE_REG - TEE_BUS_ERR_CONF_REG) / 4) + 1)
|
||||||
|
#define N_REGS_APM() (((HP_APM_INT_EN_REG - DR_REG_HP_APM_BASE) / 4) + 1)
|
||||||
|
const regdma_entries_config_t tee_apm_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* tee */
|
||||||
|
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(2), TEE_BUS_ERR_CONF_REG, TEE_BUS_ERR_CONF_REG, N_REGS_TEE_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* tee */
|
||||||
|
|
||||||
|
};
|
||||||
|
const regdma_entries_config_t tee_apm_highpri_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(3), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) }
|
||||||
|
};
|
||||||
|
_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions");
|
||||||
|
|
||||||
|
/* IO MUX Registers Context */
|
||||||
|
#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO39 - REG_IO_MUX_BASE) / 4) + 1)
|
||||||
|
#define N_REGS_IOMUX_1() (((GPIO_FUNC39_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1)
|
||||||
|
#define N_REGS_IOMUX_2() (((GPIO_FUNC189_IN_SEL_CFG_REG - GPIO_FUNC0_IN_SEL_CFG_REG) / 4) + 1)
|
||||||
|
#define N_REGS_IOMUX_3() (((GPIO_PIN39_REG - GPIO_PIN0_REG) / 4) + 1)
|
||||||
|
#define N_REGS_IOMUX_4() (((GPIO_STATUS1_REG - GPIO_OUT_REG) / 4) + 1)
|
||||||
|
const regdma_entries_config_t iomux_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */
|
||||||
|
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_FUNC0_IN_SEL_CFG_REG, GPIO_FUNC0_IN_SEL_CFG_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), GPIO_PIN0_REG, GPIO_PIN0_REG, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x04), GPIO_OUT_REG, GPIO_OUT_REG, N_REGS_IOMUX_4(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }
|
||||||
|
};
|
||||||
|
_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions");
|
||||||
|
|
||||||
|
/* Memory SPI Registers Context */
|
||||||
|
const regdma_entries_config_t flash_spimem_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_SPIMEM_LINK(0x00), SPI_MEM_CMD_REG(0), SPI_MEM_CMD_REG(0), 47, 0, 0, 0x3fa9fd, 0x10000, 0xa5ffffff, 0x100), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), 9, 0, 0, 0x1, 0x0, 0x870001, 0xe), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_TIMING_CALI_REG(0), SPI_MEM_TIMING_CALI_REG(0), 8, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x03), SPI_MEM_TIMING_CALI_REG(0), SPI_MEM_TIMING_CALI_UPDATE, SPI_MEM_TIMING_CALI_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[4] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_SPIMEM_LINK(0x04), SPI_MEM_CMD_REG(1), SPI_MEM_CMD_REG(1), 17, 0, 0, 0xafff, 0x1, 0x2000000, 0x2000000), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
};
|
||||||
|
_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions");
|
||||||
|
|
||||||
|
/* Systimer Registers Context */
|
||||||
|
#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1)
|
||||||
|
const regdma_entries_config_t systimer_regs_retention[] = {
|
||||||
|
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */
|
||||||
|
[1] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[5] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */
|
||||||
|
|
||||||
|
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[16] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
|
||||||
|
|
||||||
|
[17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */
|
||||||
|
[18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */
|
||||||
|
};
|
||||||
|
_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions");
|
Reference in New Issue
Block a user