refactor(hal): Refactor and update the ESP32-P4 APM LL/HAL APIs

This commit is contained in:
Laukik Hase
2026-05-21 12:15:50 +05:30
parent 384eba8a11
commit 3acb4a3e0c
7 changed files with 1333 additions and 492 deletions
+116 -12
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,15 +17,38 @@ extern "C" {
#endif
typedef enum {
AXI_ICM_MASTER_CPU = 0, // An aggregate master port for other users, like HP CPU, LP CPU, USB, EMAC, SDMMC, AHB-GDMA, etc
AXI_ICM_MASTER_CACHE = 1, // Cache master port
AXI_ICM_MASTER_DW_GDMA_M0 = 5, // DW-GDMA master port 0
AXI_ICM_MASTER_DW_GDMA_M1 = 6, // DW-GDMA master port 1
AXI_ICM_MASTER_GDMA = 8, // AXI-GDMA
AXI_ICM_MASTER_DMA2D = 10, // DMA2D
AXI_ICM_MASTER_H264_M0 = 11, // H264 master port 0
AXI_ICM_MASTER_H264_M1 = 12, // H264 master port 1
} axi_icm_ll_master_id_t;
AXI_ICM_MASTER_CPU = 0, // An aggregate master port for other users, like HP CPU, LP CPU, USB, EMAC, SDMMC, AHB-GDMA, etc
AXI_ICM_MASTER_CACHE = 1, // Cache master port
AXI_ICM_MASTER_DW_GDMA_M0 = 5, // DW-GDMA master port 0
AXI_ICM_MASTER_DW_GDMA_M1 = 6, // DW-GDMA master port 1
AXI_ICM_MASTER_GDMA = 8, // AXI-GDMA
AXI_ICM_MASTER_DMA2D = 10, // DMA2D
AXI_ICM_MASTER_H264_M0 = 11, // H264 master port 0
AXI_ICM_MASTER_H264_M1 = 12, // H264 master port 1
} axi_icm_ll_sys_master_id_t;
typedef enum {
AXI_ICM_CPU_MASTER_HP_CPU0 = 0, // HP CPU core 0
AXI_ICM_CPU_MASTER_HP_CPU1 = 1, // HP CPU core 1
AXI_ICM_CPU_MASTER_LP_CPU = 2, // LP CPU
AXI_ICM_CPU_MASTER_USBOTG_FS = 3, // USB OTG full-speed
AXI_ICM_CPU_MASTER_REGDMA = 4, // REGDMA
AXI_ICM_CPU_MASTER_GMAC = 5, // GMAC
AXI_ICM_CPU_MASTER_SDMMC = 6, // SDMMC
AXI_ICM_CPU_MASTER_USBOTG_HS = 7, // USB OTG high-speed
AXI_ICM_CPU_MASTER_TRACE0 = 8, // Trace 0
AXI_ICM_CPU_MASTER_TRACE1 = 9, // Trace 1
AXI_ICM_CPU_MASTER_TCM_MON = 10, // TCM monitor
AXI_ICM_CPU_MASTER_L2MEM_MON = 11, // L2MEM monitor
AXI_ICM_CPU_MASTER_AHB_PDMA_I3C = 16, // AHB PDMA I3C
AXI_ICM_CPU_MASTER_AHB_PDMA_UHCI = 18, // AHB PDMA UHCI
AXI_ICM_CPU_MASTER_AHB_PDMA_I2S0 = 19, // AHB PDMA I2S0
AXI_ICM_CPU_MASTER_AHB_PDMA_I2S1 = 20, // AHB PDMA I2S1
AXI_ICM_CPU_MASTER_AHB_PDMA_I2S2 = 21, // AHB PDMA I2S
AXI_ICM_CPU_MASTER_AHB_PDMA_ADC = 24, // AHB PDMA ADC
AXI_ICM_CPU_MASTER_AHB_PDMA_RMT = 26, // AHB PDMA RMT
AXI_ICM_CPU_MASTER_MAX = 31,
} axi_icm_ll_cpu_master_id_t;
/**
* @brief AXI ICM has independent channels for read and write access.
@@ -35,6 +58,25 @@ typedef enum {
AXI_ICM_ACCESS_WRITE = 1,
} axi_icm_ll_access_type_t;
/**
* @brief AXI ICM interrupt types
*/
typedef enum {
AXI_ICM_INTR_DEADLOCK = 0, /*!< Deadlock interrupt */
AXI_ICM_INTR_SYS_ADDRHOLE = 1, /*!< System addrhole interrupt */
AXI_ICM_INTR_CPU_ADDRHOLE = 2, /*!< CPU addrhole interrupt */
} axi_icm_ll_intr_type_t;
/**
* @brief AXI ICM addrhole exception info
*/
typedef struct {
uint32_t addr; /*!< Faulting address */
uint8_t id; /*!< Master ID */
bool is_wr; /*!< Write access */
bool is_secure; /*!< Secure access */
} axi_icm_ll_excp_info_t;
/**
* @brief Set QoS burstiness for a master port, also enable the regulator
*
@@ -42,7 +84,7 @@ typedef enum {
* @param burstiness Burstiness value. It represents the depth of the token bucket.
* @param access_type 0: read, 1: write
*/
static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uint32_t burstiness, axi_icm_ll_access_type_t access_type)
static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_sys_master_id_t mid, uint32_t burstiness, axi_icm_ll_access_type_t access_type)
{
HAL_ASSERT(burstiness >= 1 && burstiness <= 256);
// wait for the previous command to finish
@@ -80,7 +122,7 @@ static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uin
* @param transaction_level Transaction level, lower value means higher rate
* @param access_type 0: read, 1: write
*/
static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_master_id_t mid, uint32_t peak_level,
static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_sys_master_id_t mid, uint32_t peak_level,
uint32_t transaction_level, axi_icm_ll_access_type_t access_type)
{
HAL_ASSERT(peak_level < transaction_level && transaction_level <= 11);
@@ -186,6 +228,68 @@ static inline void axi_icm_ll_set_cpu_qos_arbiter_prio(uint32_t write_prio, uint
AXI_ICM.mst_arqos_reg0.reg_cpu_arqos = read_prio;
}
/**
* @brief Enable/disable AXI ICM interrupt
*
* @param mask Interrupt mask (use BIT(axi_icm_ll_intr_type_t))
* @param enable true to enable, false to disable
*/
static inline void axi_icm_ll_enable_intr(uint32_t mask, bool enable)
{
if (enable) {
AXI_ICM.int_ena.val |= mask;
} else {
AXI_ICM.int_ena.val &= ~mask;
}
}
/**
* @brief Get AXI ICM interrupt status
*
* @param mask Interrupt mask
* @return Status mask
*/
static inline uint32_t axi_icm_ll_get_intr_status(uint32_t mask)
{
return AXI_ICM.int_st.val & mask;
}
/**
* @brief Clear AXI ICM interrupt
*
* @param mask Interrupt mask
*/
static inline void axi_icm_ll_clear_intr(uint32_t mask)
{
AXI_ICM.int_clr.val = mask;
}
/**
* @brief Get SYS addrhole exception info
*
* @param[out] info Pointer to store exception information
*/
static inline void axi_icm_ll_get_sys_excp_info(axi_icm_ll_excp_info_t *info)
{
info->addr = AXI_ICM.sys_addrhole_addr.reg_icm_sys_addrhole_addr;
info->id = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_id;
info->is_wr = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_wr;
info->is_secure = AXI_ICM.sys_addrhole_info.reg_icm_sys_addrhole_secure;
}
/**
* @brief Get CPU addrhole exception info
*
* @param[out] info Pointer to store exception information
*/
static inline void axi_icm_ll_get_cpu_excp_info(axi_icm_ll_excp_info_t *info)
{
info->addr = AXI_ICM.cpu_addrhole_addr.reg_icm_cpu_addrhole_addr;
info->id = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_id;
info->is_wr = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_wr;
info->is_secure = AXI_ICM.cpu_addrhole_info.reg_icm_cpu_addrhole_secure;
}
#ifdef __cplusplus
}
#endif
@@ -25,6 +25,29 @@ extern "C" {
#define MEM_AUX_LIGHTSLEEP BIT(1)
#define MEM_AUX_DEEPSLEEP BIT(2)
/**
* @brief LP SYS interrupt types
*/
typedef enum {
LP_SYS_INTR_LP_ADDRHOLE = 0, /*!< LP addrhole interrupt (LP peri, LP RAM TEE APM, LP matrix default slave) */
LP_SYS_INTR_IDBUS_ADDRHOLE = 1, /*!< IDBUS addrhole interrupt (LP CPU ibus and dbus) */
LP_SYS_INTR_LP_CORE_AHB_TOUT = 2, /*!< LP core AHB bus timeout interrupt */
LP_SYS_INTR_LP_CORE_IBUS_TOUT = 3, /*!< LP core ibus timeout interrupt */
LP_SYS_INTR_LP_CORE_DBUS_TOUT = 4, /*!< LP core dbus timeout interrupt */
LP_SYS_INTR_ETM_TASK_ULP = 5, /*!< ETM task ULP interrupt */
LP_SYS_INTR_SLOW_CLK_TICK = 6, /*!< Slow clock tick interrupt */
} lp_sys_ll_intr_type_t;
/**
* @brief LP SYS addrhole exception info
*/
typedef struct {
uint32_t addr; /*!< Faulting address */
uint8_t id; /*!< Master ID */
bool is_wr; /*!< Write access */
bool is_secure; /*!< Secure access */
} lp_sys_ll_excp_info_t;
/**
* @brief ROM obtains the wake-up type through LP_SYS_STORE9_REG[0].
* Set the flag to inform
@@ -100,6 +123,60 @@ static inline uint32_t lp_sys_ll_load_wakeup_cause(void)
return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG);
}
FORCE_INLINE_ATTR void lp_sys_ll_enable_intr(uint32_t mask, bool enable)
{
if (enable) {
LP_SYS.int_ena.val |= mask;
} else {
LP_SYS.int_ena.val &= ~mask;
}
}
FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_intr_status(uint32_t mask)
{
return LP_SYS.int_st.val & mask;
}
FORCE_INLINE_ATTR void lp_sys_ll_clear_intr(uint32_t mask)
{
LP_SYS.int_clr.val = mask;
}
FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_ahb_excp_addr(void)
{
return LP_SYS.lp_addrhole_addr.lp_addrhole_addr;
}
FORCE_INLINE_ATTR void lp_sys_ll_get_ahb_excp_info(lp_sys_ll_excp_info_t *info)
{
info->addr = LP_SYS.lp_addrhole_addr.lp_addrhole_addr;
info->id = LP_SYS.lp_addrhole_info.lp_addrhole_id;
info->is_wr = LP_SYS.lp_addrhole_info.lp_addrhole_wr;
info->is_secure = LP_SYS.lp_addrhole_info.lp_addrhole_secure;
}
FORCE_INLINE_ATTR uint32_t lp_sys_ll_get_idbus_excp_addr(void)
{
return LP_SYS.idbus_addrhole_addr.idbus_addrhole_addr;
}
FORCE_INLINE_ATTR void lp_sys_ll_get_idbus_excp_info(lp_sys_ll_excp_info_t *info)
{
info->addr = LP_SYS.idbus_addrhole_addr.idbus_addrhole_addr;
info->id = LP_SYS.idbus_addrhole_info.idbus_addrhole_id;
info->is_wr = LP_SYS.idbus_addrhole_info.idbus_addrhole_wr;
info->is_secure = LP_SYS.idbus_addrhole_info.idbus_addrhole_secure;
}
FORCE_INLINE_ATTR void lp_sys_ll_enable_lp_core_err_resp(bool enable)
{
if (enable) {
LP_SYS.lp_core_err_resp_dis.val = 0x00U;
} else {
LP_SYS.lp_core_err_resp_dis.val = 0x07U;
}
}
#ifdef __cplusplus
}
#endif