Merge branch 'feat/axi_icm_qos' into 'master'

feat(axi_icm): AXI interconnect QoS

See merge request espressif/esp-idf!30894
This commit is contained in:
morris 2024-05-21 14:35:56 +08:00
commit 4db2236626
7 changed files with 220 additions and 34 deletions

View File

@ -0,0 +1,180 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "hal/assert.h"
#include "soc/icm_sys_qos_struct.h"
#include "soc/icm_sys_struct.h"
#ifdef __cplusplus
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;
/**
* @brief Set QoS burstiness for a master port, also enable the regulator
*
* @param mid Master port ID
* @param burstiness Burstiness value. It represents the depth of the token bucket.
*/
static inline void axi_icm_ll_set_qos_burstiness(axi_icm_ll_master_id_t mid, uint32_t burstiness)
{
HAL_ASSERT(burstiness >= 1 && burstiness <= 256);
// wait for the previous command to finish
while (AXI_ICM_QOS.cmd.reg_axi_cmd_en);
// write data register
// data[23:16] - burstiness, data[0] - enable regulator
AXI_ICM_QOS.data.val = (burstiness - 1) << 16 | 0x1;
// command write operation
AXI_ICM_QOS.cmd.reg_axi_rd_wr_cmd = 1;
// write addr channel
AXI_ICM_QOS.cmd.reg_rd_wr_chan = 1;
// select master port
AXI_ICM_QOS.cmd.reg_axi_master_port = mid;
// set command type: burstiness regulator
AXI_ICM_QOS.cmd.reg_axi_cmd = 0;
// command enable bit
AXI_ICM_QOS.cmd.reg_axi_cmd_en = 1;
// wait for the data to be synced to internal register
while (AXI_ICM_QOS.cmd.reg_axi_cmd_en);
}
/**
* @brief Set QoS peak and transaction rate for a master port
*
* @note Relationship between "level" and fractional rate:
* level = 0: 1/2
* level = 1: 1/4
* ...
* level = 11: 1/4096
*
* @note if the transaction rate is set to 1/N, every N cycles, the master port can accept one transfer request (offer a token).
*
* @param mid Master port ID
* @param peak_level Peak level, lower value means higher rate
* @param transaction_level Transaction level, lower value means higher rate
*/
static inline void axi_icm_ll_set_qos_peak_transaction_rate(axi_icm_ll_master_id_t mid, uint32_t peak_level, uint32_t transaction_level)
{
HAL_ASSERT(peak_level < transaction_level && transaction_level <= 11);
while (AXI_ICM_QOS.cmd.reg_axi_cmd_en);
// program data register
// data[31:20] - peak_rate, data[15:4] - transaction_rate
AXI_ICM_QOS.data.val = (0x80000000 >> peak_level) + (0x8000 >> transaction_level);
// command write operation
AXI_ICM_QOS.cmd.reg_axi_rd_wr_cmd = 1;
// write addr channel
AXI_ICM_QOS.cmd.reg_rd_wr_chan = 1;
// select master port
AXI_ICM_QOS.cmd.reg_axi_master_port = mid;
// set command type: peak rate xct rate
AXI_ICM_QOS.cmd.reg_axi_cmd = 1;
// command enable bit
AXI_ICM_QOS.cmd.reg_axi_cmd_en = 1;
// wait for the data to be synced to internal register
while (AXI_ICM_QOS.cmd.reg_axi_cmd_en);
}
/**
* @brief Set QoS priority for DMA2D master port
*
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_dma2d_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio)
{
AXI_ICM.mst_awqos_reg0.reg_dma2d_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_dma2d_arqos = read_prio;
}
/**
* @brief Set QoS priority for AXI-GDMA master port
*
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_gdma_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio)
{
AXI_ICM.mst_awqos_reg0.reg_pdma_int_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_axi_pdma_int_arqos = read_prio;
}
/**
* @brief Set QoS priority for DW_GDMA master port
*
* @param master_port DW_GDMA master port ID
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_dw_gdma_qos_arbiter_prio(uint32_t master_port, uint32_t write_prio, uint32_t read_prio)
{
if (master_port == 0) {
AXI_ICM.mst_awqos_reg0.reg_gdma_mst1_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_gdma_mst1_arqos = read_prio;
} else {
AXI_ICM.mst_awqos_reg0.reg_gdma_mst2_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_gdma_mst2_arqos = read_prio;
}
}
/**
* @brief Set QoS priority for H264 master port
*
* @param master_port H264 master port ID
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_h264_dma_qos_arbiter_prio(uint32_t master_port, uint32_t write_prio, uint32_t read_prio)
{
if (master_port == 0) {
AXI_ICM.mst_awqos_reg0.reg_h264_dma2d_m1_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_h264_dma2d_m1_arqos = read_prio;
} else {
AXI_ICM.mst_awqos_reg0.reg_h264_dma2d_m2_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_h264_dma2d_m2_arqos = read_prio;
}
}
/**
* @brief Set QoS priority for Cache master port
*
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_cache_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio)
{
AXI_ICM.mst_awqos_reg0.reg_cache_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_cache_arqos = read_prio;
}
/**
* @brief Set QoS priority for CPU master port
*
* @param write_prio Write priority
* @param read_prio Read priority
*/
static inline void axi_icm_ll_set_cpu_qos_arbiter_prio(uint32_t write_prio, uint32_t read_prio)
{
AXI_ICM.mst_awqos_reg0.reg_cpu_awqos = write_prio;
AXI_ICM.mst_arqos_reg0.reg_cpu_arqos = read_prio;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -14,7 +14,7 @@ extern "C" {
/** ICM_VERID_FILEDS_REG register
* NA
*/
#define ICM_VERID_FILEDS_REG (DR_REG_ICM_BASE + 0x0)
#define ICM_VERID_FILEDS_REG (DR_REG_AXI_ICM_QOS_BASE + 0x0)
/** ICM_REG_VERID : RO; bitpos: [31:0]; default: 875574314;
* NA
*/
@ -26,7 +26,7 @@ extern "C" {
/** ICM_HW_CFG_REG_REG register
* NA
*/
#define ICM_HW_CFG_REG_REG (DR_REG_ICM_BASE + 0x4)
#define ICM_HW_CFG_REG_REG (DR_REG_AXI_ICM_QOS_BASE + 0x4)
/** ICM_REG_AXI_HWCFG_QOS_SUPPORT : RO; bitpos: [0]; default: 1;
* NA
*/
@ -108,7 +108,7 @@ extern "C" {
/** ICM_CMD_REG register
* NA
*/
#define ICM_CMD_REG (DR_REG_ICM_BASE + 0x8)
#define ICM_CMD_REG (DR_REG_AXI_ICM_QOS_BASE + 0x8)
/** ICM_REG_AXI_CMD : R/W; bitpos: [2:0]; default: 0;
* NA
*/
@ -162,7 +162,7 @@ extern "C" {
/** ICM_DATA_REG register
* NA
*/
#define ICM_DATA_REG (DR_REG_ICM_BASE + 0xc)
#define ICM_DATA_REG (DR_REG_AXI_ICM_QOS_BASE + 0xc)
/** ICM_REG_DATA : R/W; bitpos: [31:0]; default: 0;
* NA
*/

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -10,7 +10,7 @@
extern "C" {
#endif
/** Group: ICM AXI VERID FILEDS REG */
/** Group: ICM AXI VERID FIELDS REG */
/** Type of verid_fileds register
* NA
*/
@ -144,11 +144,13 @@ typedef struct {
volatile icm_hw_cfg_reg_reg_t hw_cfg_reg;
volatile icm_cmd_reg_t cmd;
volatile icm_data_reg_t data;
} icm_dev_t;
} axi_icm_qos_dev_t;
extern axi_icm_qos_dev_t AXI_ICM_QOS;
#ifndef __cplusplus
_Static_assert(sizeof(icm_dev_t) == 0x10, "Invalid size of icm_dev_t structure");
_Static_assert(sizeof(axi_icm_qos_dev_t) == 0x10, "Invalid size of axi_icm_qos_dev_t structure");
#endif
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -14,7 +14,7 @@ extern "C" {
/** ICM_VER_DATE_REG register
* NA
*/
#define ICM_VER_DATE_REG (DR_REG_ICM_BASE + 0x0)
#define ICM_VER_DATE_REG (DR_REG_AXI_ICM_BASE + 0x0)
/** ICM_REG_VER_DATE : R/W; bitpos: [31:0]; default: 539165204;
* NA
*/
@ -26,7 +26,7 @@ extern "C" {
/** ICM_CLK_EN_REG register
* NA
*/
#define ICM_CLK_EN_REG (DR_REG_ICM_BASE + 0x4)
#define ICM_CLK_EN_REG (DR_REG_AXI_ICM_BASE + 0x4)
/** ICM_REG_CLK_EN : R/W; bitpos: [0]; default: 0;
* NA
*/
@ -38,7 +38,7 @@ extern "C" {
/** ICM_DLOCK_STATUS_REG register
* NA
*/
#define ICM_DLOCK_STATUS_REG (DR_REG_ICM_BASE + 0x8)
#define ICM_DLOCK_STATUS_REG (DR_REG_AXI_ICM_BASE + 0x8)
/** ICM_REG_DLOCK_MST : RO; bitpos: [3:0]; default: 0;
* Lowest numbered deadlocked master
*/
@ -71,7 +71,7 @@ extern "C" {
/** ICM_INT_RAW_REG register
* NA
*/
#define ICM_INT_RAW_REG (DR_REG_ICM_BASE + 0xc)
#define ICM_INT_RAW_REG (DR_REG_AXI_ICM_BASE + 0xc)
/** ICM_REG_DLOCK_INT_RAW : R/WTC/SS; bitpos: [0]; default: 0;
* NA
*/
@ -97,7 +97,7 @@ extern "C" {
/** ICM_INT_ST_REG register
* NA
*/
#define ICM_INT_ST_REG (DR_REG_ICM_BASE + 0x10)
#define ICM_INT_ST_REG (DR_REG_AXI_ICM_BASE + 0x10)
/** ICM_REG_DLOCK_INT_ST : RO; bitpos: [0]; default: 0;
* NA
*/
@ -123,7 +123,7 @@ extern "C" {
/** ICM_INT_ENA_REG register
* NA
*/
#define ICM_INT_ENA_REG (DR_REG_ICM_BASE + 0x14)
#define ICM_INT_ENA_REG (DR_REG_AXI_ICM_BASE + 0x14)
/** ICM_REG_DLOCK_INT_ENA : R/W; bitpos: [0]; default: 1;
* NA
*/
@ -149,7 +149,7 @@ extern "C" {
/** ICM_INT_CLR_REG register
* NA
*/
#define ICM_INT_CLR_REG (DR_REG_ICM_BASE + 0x18)
#define ICM_INT_CLR_REG (DR_REG_AXI_ICM_BASE + 0x18)
/** ICM_REG_DLOCK_INT_CLR : WT; bitpos: [0]; default: 0;
* NA
*/
@ -175,7 +175,7 @@ extern "C" {
/** ICM_MST_ARB_PRIORITY_REG0_REG register
* NA
*/
#define ICM_MST_ARB_PRIORITY_REG0_REG (DR_REG_ICM_BASE + 0x1c)
#define ICM_MST_ARB_PRIORITY_REG0_REG (DR_REG_AXI_ICM_BASE + 0x1c)
/** ICM_REG_CPU_PRIORITY : R/W; bitpos: [3:0]; default: 0;
* CPU arbitration priority for command channels between masters connected to sys_icm
*/
@ -241,7 +241,7 @@ extern "C" {
/** ICM_SLV_ARB_PRIORITY_REG register
* NA
*/
#define ICM_SLV_ARB_PRIORITY_REG (DR_REG_ICM_BASE + 0x24)
#define ICM_SLV_ARB_PRIORITY_REG (DR_REG_AXI_ICM_BASE + 0x24)
/** ICM_REG_L2MEM_PRIORITY : R/W; bitpos: [5:3]; default: 0;
* L2MEM arbitration priority for response channels between slaves connected to sys_icm
*/
@ -285,7 +285,7 @@ extern "C" {
/** ICM_MST_ARQOS_REG0_REG register
* NA
*/
#define ICM_MST_ARQOS_REG0_REG (DR_REG_ICM_BASE + 0x28)
#define ICM_MST_ARQOS_REG0_REG (DR_REG_AXI_ICM_BASE + 0x28)
/** ICM_REG_CPU_ARQOS : R/W; bitpos: [3:0]; default: 0;
* NA
*/
@ -346,7 +346,7 @@ extern "C" {
/** ICM_MST_AWQOS_REG0_REG register
* NA
*/
#define ICM_MST_AWQOS_REG0_REG (DR_REG_ICM_BASE + 0x30)
#define ICM_MST_AWQOS_REG0_REG (DR_REG_AXI_ICM_BASE + 0x30)
/** ICM_REG_CPU_AWQOS : R/W; bitpos: [3:0]; default: 0;
* NA
*/
@ -407,7 +407,7 @@ extern "C" {
/** ICM_SYS_ADDRHOLE_ADDR_REG register
* icm sys addr hole address registers
*/
#define ICM_SYS_ADDRHOLE_ADDR_REG (DR_REG_ICM_BASE + 0x38)
#define ICM_SYS_ADDRHOLE_ADDR_REG (DR_REG_AXI_ICM_BASE + 0x38)
/** ICM_REG_ICM_SYS_ADDRHOLE_ADDR : RO; bitpos: [31:0]; default: 0;
* NA
*/
@ -419,9 +419,9 @@ extern "C" {
/** ICM_SYS_ADDRHOLE_INFO_REG register
* NA
*/
#define ICM_SYS_ADDRHOLE_INFO_REG (DR_REG_ICM_BASE + 0x3c)
#define ICM_SYS_ADDRHOLE_INFO_REG (DR_REG_AXI_ICM_BASE + 0x3c)
/** ICM_REG_ICM_SYS_ADDRHOLE_ID : RO; bitpos: [7:0]; default: 0;
* master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verfiy
* master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verify
* master in icm. CID: 4'h1: cache, 4'h5 gdma mst1, 4'h6: gdma mst2, 4'h8: axi pdma,
* 4'ha: dma2d, 4'hb: h264 mst1, 4'hc: h264 mst2.
*/
@ -448,7 +448,7 @@ extern "C" {
/** ICM_CPU_ADDRHOLE_ADDR_REG register
* icm cpu addr hole address registers
*/
#define ICM_CPU_ADDRHOLE_ADDR_REG (DR_REG_ICM_BASE + 0x40)
#define ICM_CPU_ADDRHOLE_ADDR_REG (DR_REG_AXI_ICM_BASE + 0x40)
/** ICM_REG_ICM_CPU_ADDRHOLE_ADDR : RO; bitpos: [31:0]; default: 0;
* It is illegall access address if reg_icm_cpu_addrhole_secure is 1. Otherwise, it
* the address without permission to access.
@ -461,7 +461,7 @@ extern "C" {
/** ICM_CPU_ADDRHOLE_INFO_REG register
* NA
*/
#define ICM_CPU_ADDRHOLE_INFO_REG (DR_REG_ICM_BASE + 0x44)
#define ICM_CPU_ADDRHOLE_INFO_REG (DR_REG_AXI_ICM_BASE + 0x44)
/** ICM_REG_ICM_CPU_ADDRHOLE_ID : RO; bitpos: [4:0]; default: 0;
* master id: 5'h0: hp core0, 5'h1:hp core1, 5'h2:lp core, 5'h3:usb otg11, 5'h4:
* regdma, 5'h5: gmac, 5'h5 sdmmc, 5'h7: usbotg20, 5'h8: trace0, 5'h9: trace1, 5'ha
@ -489,7 +489,7 @@ extern "C" {
/** ICM_DLOCK_TIMEOUT_REG register
* NA
*/
#define ICM_DLOCK_TIMEOUT_REG (DR_REG_ICM_BASE + 0x48)
#define ICM_DLOCK_TIMEOUT_REG (DR_REG_AXI_ICM_BASE + 0x48)
/** ICM_REG_DLOCK_TIMEOUT : R/W; bitpos: [12:0]; default: 2048;
* if no response until reg_dlock_timeout bus clock cycle, deadlock will happen
*/
@ -501,7 +501,7 @@ extern "C" {
/** ICM_RDN_ECO_CS_REG register
* NA
*/
#define ICM_RDN_ECO_CS_REG (DR_REG_ICM_BASE + 0x50)
#define ICM_RDN_ECO_CS_REG (DR_REG_AXI_ICM_BASE + 0x50)
/** ICM_REG_RDN_ECO_EN : R/W; bitpos: [0]; default: 0;
* NA
*/
@ -520,7 +520,7 @@ extern "C" {
/** ICM_RDN_ECO_LOW_REG register
* NA
*/
#define ICM_RDN_ECO_LOW_REG (DR_REG_ICM_BASE + 0x54)
#define ICM_RDN_ECO_LOW_REG (DR_REG_AXI_ICM_BASE + 0x54)
/** ICM_RDN_ECO_LOW : R/W; bitpos: [31:0]; default: 0;
* NA
*/
@ -532,7 +532,7 @@ extern "C" {
/** ICM_RDN_ECO_HIGH_REG register
* NA
*/
#define ICM_RDN_ECO_HIGH_REG (DR_REG_ICM_BASE + 0x58)
#define ICM_RDN_ECO_HIGH_REG (DR_REG_AXI_ICM_BASE + 0x58)
/** ICM_RDN_ECO_HIGH : R/W; bitpos: [31:0]; default: 4294967295;
* NA
*/

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -373,7 +373,7 @@ typedef union {
typedef union {
struct {
/** reg_icm_sys_addrhole_id : RO; bitpos: [7:0]; default: 0;
* master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verfiy
* master id = 4-bit CID + 4-bit UID(refer to related IP) . CID is used to verify
* master in icm. CID: 4'h1: cache, 4'h5 gdma mst1, 4'h6: gdma mst2, 4'h8: axi pdma,
* 4'ha: dma2d, 4'hb: h264 mst1, 4'hc: h264 mst2.
*/
@ -508,11 +508,12 @@ typedef struct {
volatile icm_rdn_eco_cs_reg_t rdn_eco_cs;
volatile icm_rdn_eco_low_reg_t rdn_eco_low;
volatile icm_rdn_eco_high_reg_t rdn_eco_high;
} icm_dev_t;
} axi_icm_dev_t;
extern axi_icm_dev_t AXI_ICM;
#ifndef __cplusplus
_Static_assert(sizeof(icm_dev_t) == 0x5c, "Invalid size of icm_dev_t structure");
_Static_assert(sizeof(axi_icm_dev_t) == 0x5c, "Invalid size of axi_icm_dev_t structure");
#endif
#ifdef __cplusplus

View File

@ -64,6 +64,7 @@
#define DR_REG_RMT_BASE (DR_REG_HPPERIPH0_BASE + 0xA2000)
#define DR_REG_BITSCRAM_BASE (DR_REG_HPPERIPH0_BASE + 0xA3000)
#define DR_REG_AXI_ICM_BASE (DR_REG_HPPERIPH0_BASE + 0xA4000)
#define DR_REG_AXI_ICM_QOS_BASE (DR_REG_AXI_ICM_BASE + 0x400)
#define DR_REG_HP_PERI_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA5000)
#define DR_REG_LP2HP_PERI_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA5800)
#define DR_REG_DMA_PMS_BASE (DR_REG_HPPERIPH0_BASE + 0xA6000)

View File

@ -19,6 +19,8 @@ PROVIDE ( I2C1 = 0x500C5000 );
PROVIDE ( UHCI0 = 0x500DF000 );
PROVIDE ( RMT = 0x500A2000 );
PROVIDE ( RMTMEM = 0x500A2800 );
PROVIDE ( AXI_ICM = 0x500A4000 );
PROVIDE ( AXI_ICM_QOS = 0x500A4400 );
PROVIDE ( HP_PERI_PMS = 0x500A5000 );
PROVIDE ( LP2HP_PERI_PMS = 0x500A5800 );
PROVIDE ( DMA_PMS = 0x500A6000 );