qcacmn: Register IRQ for near full irq

WCN7850 has support for near full indication for
the consumer srngs. This interrupt is used to take
preventive actions to avoid ring full watchdog irq
trigger.

Register for the near full irq and add the necessary
ext groups for these near-full irqs.

Change-Id: Ic16381fceabc54e6c52b34dd13abea74cad4d38c
CRs-Fixed: 2965081
This commit is contained in:
Rakesh Pillai
2021-03-23 05:32:56 -07:00
committed by Madan Koyyalamudi
parent cebffa806d
commit 37e2c6d9ed
11 changed files with 836 additions and 105 deletions

View File

@@ -989,6 +989,20 @@ struct hal_srng_params {
void *hwreg_base[MAX_SRNG_REG_GROUPS];
/* prefetch timer config - in micro seconds */
uint32_t prefetch_timer;
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/* Near full IRQ support flag */
uint32_t nf_irq_support;
/* MSI2 Address */
qdf_dma_addr_t msi2_addr;
/* MSI2 data */
uint32_t msi2_data;
/* Critical threshold */
uint16_t crit_thresh;
/* High threshold */
uint16_t high_thresh;
/* Safe threshold */
uint16_t safe_thresh;
#endif
};
/* hal_construct_srng_shadow_regs() - initialize the shadow
@@ -1025,6 +1039,28 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc, int ring_type,
extern void hal_get_shadow_config(void *hal_soc,
struct pld_shadow_reg_v2_cfg **shadow_config,
int *num_shadow_registers_configured);
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/**
* hal_srng_is_near_full_irq_supported() - Check if srng supports near full irq
* @hal_soc: HAL SoC handle [To be validated by caller]
* @ring_type: srng type
* @ring_num: The index of the srng (of the same type)
*
* Return: true, if srng support near full irq trigger
* false, if the srng does not support near full irq support.
*/
bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc,
int ring_type, int ring_num);
#else
static inline
bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc,
int ring_type, int ring_num)
{
return false;
}
#endif
/**
* hal_srng_setup - Initialize HW SRNG ring.
*

View File

@@ -292,6 +292,65 @@ void hal_srng_src_hw_init_generic(struct hal_soc *hal,
SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
}
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/**
* hal_srng_dst_msi2_setup() - Configure MSI2 register for a SRNG
* @srng: SRNG handle
*
* Return: None
*/
static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
{
uint32_t reg_val = 0;
if (srng->u.dst_ring.nf_irq_support) {
SRNG_DST_REG_WRITE(srng, MSI2_BASE_LSB,
srng->msi2_addr & 0xffffffff);
reg_val = SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB, ADDR),
(uint64_t)(srng->msi2_addr) >> 32) |
SRNG_SM(SRNG_DST_FLD(MSI2_BASE_MSB,
MSI2_ENABLE), 1);
SRNG_DST_REG_WRITE(srng, MSI2_BASE_MSB, reg_val);
SRNG_DST_REG_WRITE(srng, MSI2_DATA,
qdf_cpu_to_le32(srng->msi2_data));
}
}
/**
* hal_srng_dst_near_full_int_setup() - Configure near-full params for SRNG
* @srng: SRNG handle
*
* Return: None
*/
static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
{
uint32_t reg_val = 0;
if (srng->u.dst_ring.nf_irq_support) {
if (srng->intr_timer_thres_us) {
reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
INTERRUPT2_TIMER_THRESHOLD),
srng->intr_timer_thres_us >> 3);
}
reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT2_SETUP,
HIGH_THRESHOLD),
srng->u.dst_ring.high_thresh *
srng->entry_size);
}
SRNG_DST_REG_WRITE(srng, PRODUCER_INT2_SETUP, reg_val);
}
#else
static inline void hal_srng_dst_msi2_setup(struct hal_srng *srng)
{
}
static inline void hal_srng_dst_near_full_int_setup(struct hal_srng *srng)
{
}
#endif
/**
* hal_srng_dst_hw_init - Private function to initialize SRNG
* destination ring HW
@@ -317,6 +376,8 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
SRNG_DST_REG_WRITE(srng, MSI1_DATA,
qdf_cpu_to_le32(srng->msi_data));
hal_srng_dst_msi2_setup(srng);
}
SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
@@ -351,6 +412,14 @@ void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
}
SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
/**
* Near-Full Interrupt setup:
* Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
* if level mode is required
*/
hal_srng_dst_near_full_int_setup(srng);
hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
((unsigned long)(srng->u.dst_ring.hp_addr) -
(unsigned long)(hal->shadow_rdptr_mem_vaddr)));

View File

@@ -86,6 +86,12 @@
#define HAL_REO_R0_REO2SW1_RING_MSI1_BASE_MSB_MSI1_ENABLE_SHFT 0x8
#define HAL_REO_R0_REO2SW1_RING_MSI1_BASE_MSB_MSI1_ENABLE_BMSK 0x100
#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_ADDR_SHFT 0x0
#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_ADDR_BMSK 0xff
#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_MSI2_ENABLE_SHFT 0x8
#define HAL_REO_R0_REO2SW1_RING_MSI2_BASE_MSB_MSI2_ENABLE_BMSK 0x100
#define HAL_REO_R0_REO2SW1_RING_BASE_MSB_RING_BASE_ADDR_MSB_SHFT 0x0
#define HAL_REO_R0_REO2SW1_RING_BASE_MSB_RING_BASE_ADDR_MSB_BMSK 0xff
@@ -104,6 +110,12 @@
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT_SETUP_BATCH_COUNTER_THRESHOLD_SHFT 0x0
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT_SETUP_BATCH_COUNTER_THRESHOLD_BMSK 0x00007fff
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_INTERRUPT2_TIMER_THRESHOLD_SHFT 24
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_INTERRUPT2_TIMER_THRESHOLD_BMSK 0xff000000
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_HIGH_THRESHOLD_SHFT 0
#define HAL_REO_R0_REO2SW1_RING_PRODUCER_INT2_SETUP_HIGH_THRESHOLD_BMSK 0xfffff
#define HAL_REO_R0_REO2SW1_RING_MISC_DATA_TLV_SWAP_BIT_SHFT 0x5
#define HAL_REO_R0_REO2SW1_RING_MISC_DATA_TLV_SWAP_BIT_BMSK 0x20
@@ -183,11 +195,15 @@
#define HP_ADDR_LSB_GROUP R0
#define HP_ADDR_MSB_GROUP R0
#define PRODUCER_INT_SETUP_GROUP R0
#define PRODUCER_INT2_SETUP_GROUP R0
#define PRODUCER_INT_STATUS_GROUP R0
#define PRODUCER_FULL_COUNTER_GROUP R0
#define MSI1_BASE_LSB_GROUP R0
#define MSI1_BASE_MSB_GROUP R0
#define MSI1_DATA_GROUP R0
#define MSI2_BASE_LSB_GROUP R0
#define MSI2_BASE_MSB_GROUP R0
#define MSI2_DATA_GROUP R0
#define HP_TP_SW_OFFSET_GROUP R0
#define TP_ADDR_LSB_GROUP R0
#define TP_ADDR_MSB_GROUP R0
@@ -314,35 +330,6 @@
#define HAL_SRNG_CONFIG(_hal_soc, _ring_type) \
(&_hal_soc->hw_srng_table[_ring_type])
enum SRNG_REGISTERS {
DST_HP = 0,
DST_TP,
DST_ID,
DST_MISC,
DST_HP_ADDR_LSB,
DST_HP_ADDR_MSB,
DST_MSI1_BASE_LSB,
DST_MSI1_BASE_MSB,
DST_MSI1_DATA,
DST_BASE_LSB,
DST_BASE_MSB,
DST_PRODUCER_INT_SETUP,
SRC_HP,
SRC_TP,
SRC_ID,
SRC_MISC,
SRC_TP_ADDR_LSB,
SRC_TP_ADDR_MSB,
SRC_MSI1_BASE_LSB,
SRC_MSI1_BASE_MSB,
SRC_MSI1_DATA,
SRC_BASE_LSB,
SRC_BASE_MSB,
SRC_CONSUMER_INT_SETUP_IX0,
SRC_CONSUMER_INT_SETUP_IX1,
};
/**
* hal_set_link_desc_addr - Setup link descriptor in a buffer_addr_info
* HW structure

View File

@@ -272,6 +272,44 @@ enum hal_ring_type {
MAX_RING_TYPES
};
enum SRNG_REGISTERS {
DST_HP = 0,
DST_TP,
DST_ID,
DST_MISC,
DST_HP_ADDR_LSB,
DST_HP_ADDR_MSB,
DST_MSI1_BASE_LSB,
DST_MSI1_BASE_MSB,
DST_MSI1_DATA,
#ifdef CONFIG_BERYLLIUM
DST_MSI2_BASE_LSB,
DST_MSI2_BASE_MSB,
DST_MSI2_DATA,
#endif
DST_BASE_LSB,
DST_BASE_MSB,
DST_PRODUCER_INT_SETUP,
#ifdef CONFIG_BERYLLIUM
DST_PRODUCER_INT2_SETUP,
#endif
SRC_HP,
SRC_TP,
SRC_ID,
SRC_MISC,
SRC_TP_ADDR_LSB,
SRC_TP_ADDR_MSB,
SRC_MSI1_BASE_LSB,
SRC_MSI1_BASE_MSB,
SRC_MSI1_DATA,
SRC_BASE_LSB,
SRC_BASE_MSB,
SRC_CONSUMER_INT_SETUP_IX0,
SRC_CONSUMER_INT_SETUP_IX1,
SRNG_REGISTER_MAX,
};
#define HAL_RXDMA_MAX_RING_SIZE 0xFFFF
#define HAL_MAX_LMACS 3
#define HAL_MAX_RINGS_PER_LMAC (HAL_SRNG_LMAC1_ID_END - HAL_SRNG_LMAC1_ID_START)
@@ -475,6 +513,14 @@ struct hal_srng {
/* MSI data */
uint32_t msi_data;
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/* MSI2 Address */
qdf_dma_addr_t msi2_addr;
/* MSI2 data */
uint32_t msi2_data;
#endif
/* Misc flags */
uint32_t flags;
@@ -514,6 +560,14 @@ struct hal_srng {
/* max transfer size */
uint16_t max_buffer_length;
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/* near full IRQ supported */
uint16_t nf_irq_support;
/* High threshold for Near full IRQ */
uint16_t high_thresh;
#endif
} dst_ring;
struct {
@@ -571,6 +625,7 @@ struct hal_hw_srng_config {
uint8_t lmac_ring;
enum hal_srng_dir ring_dir;
uint32_t max_size;
bool nf_irq_support;
};
#define MAX_SHADOW_REGISTERS 40

View File

@@ -1767,6 +1767,92 @@ static inline void hal_srng_hw_init(struct hal_soc *hal,
#define CHECK_SHADOW_REGISTERS false
#endif
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/**
* hal_srng_is_near_full_irq_supported() - Check if near full irq is
* supported on this SRNG
* @hal_soc: HAL SoC handle
* @ring_type: SRNG type
* @ring_num: ring number
*
* Return: true, if near full irq is supported for this SRNG
* false, if near full irq is not supported for this SRNG
*/
bool hal_srng_is_near_full_irq_supported(hal_soc_handle_t hal_soc,
int ring_type, int ring_num)
{
struct hal_soc *hal = (struct hal_soc *)hal_soc;
struct hal_hw_srng_config *ring_config =
HAL_SRNG_CONFIG(hal, ring_type);
return ring_config->nf_irq_support;
}
/**
* hal_srng_set_msi2_params() - Set MSI2 params to SRNG data structure from
* ring params
* @srng: SRNG handle
* @ring_params: ring params for this SRNG
*
* Return: None
*/
static inline void
hal_srng_set_msi2_params(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
srng->msi2_addr = ring_params->msi2_addr;
srng->msi2_data = ring_params->msi2_data;
}
/**
* hal_srng_get_nf_params() - Get the near full MSI2 params from srng
* @srng: SRNG handle
* @ring_params: ring params for this SRNG
*
* Return: None
*/
static inline void
hal_srng_get_nf_params(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
ring_params->msi2_addr = srng->msi2_addr;
ring_params->msi2_data = srng->msi2_data;
}
/**
* hal_srng_set_nf_thresholds() - Set the near full thresholds in SRNG
* @srng: SRNG handle where the params are to be set
* @ring_params: ring params, from where threshold is to be fetched
*
* Return: None
*/
static inline void
hal_srng_set_nf_thresholds(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
srng->u.dst_ring.nf_irq_support = ring_params->nf_irq_support;
srng->u.dst_ring.high_thresh = ring_params->high_thresh;
}
#else
static inline void
hal_srng_set_msi2_params(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
}
static inline void
hal_srng_get_nf_params(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
}
static inline void
hal_srng_set_nf_thresholds(struct hal_srng *srng,
struct hal_srng_params *ring_params)
{
}
#endif
/**
* hal_srng_setup - Initialize HW SRNG ring.
* @hal_soc: Opaque HAL SOC handle
@@ -1827,6 +1913,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
ring_params->intr_batch_cntr_thres_entries;
srng->prefetch_timer = ring_params->prefetch_timer;
srng->hal_soc = hal_soc;
hal_srng_set_msi2_params(srng, ring_params);
for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) {
srng->hwreg_base[i] = dev_base_addr + ring_config->reg_start[i]
@@ -1886,6 +1973,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
* loop count in descriptors updated by HW (to be processed
* by SW).
*/
hal_srng_set_nf_thresholds(srng, ring_params);
srng->u.dst_ring.loop_cnt = 1;
srng->u.dst_ring.tp = 0;
srng->u.dst_ring.hp_addr =
@@ -2042,6 +2130,8 @@ extern void hal_get_srng_params(hal_soc_handle_t hal_soc_hdl,
ring_params->ring_id = srng->ring_id;
for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++)
ring_params->hwreg_base[i] = srng->hwreg_base[i];
hal_srng_get_nf_params(srng, ring_params);
}
qdf_export_symbol(hal_get_srng_params);

View File

@@ -1449,6 +1449,7 @@ struct hal_hw_srng_config hw_srng_table_7850[] = {
.entry_size = sizeof(struct reo_destination_ring) >> 2,
.lmac_ring = FALSE,
.ring_dir = HAL_SRNG_DST_RING,
.nf_irq_support = true,
.reg_start = {
HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(
REO_REG_REG_BASE),
@@ -1716,6 +1717,7 @@ struct hal_hw_srng_config hw_srng_table_7850[] = {
.entry_size = sizeof(struct wbm_release_ring) >> 2,
.lmac_ring = FALSE,
.ring_dir = HAL_SRNG_DST_RING,
.nf_irq_support = true,
.reg_start = {
HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(WBM_REG_REG_BASE),
HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(WBM_REG_REG_BASE),
@@ -1857,9 +1859,13 @@ int32_t hal_hw_reg_offset_wcn7850[] = {
REG_OFFSET(DST, MSI1_BASE_LSB),
REG_OFFSET(DST, MSI1_BASE_MSB),
REG_OFFSET(DST, MSI1_DATA),
REG_OFFSET(DST, MSI2_BASE_LSB),
REG_OFFSET(DST, MSI2_BASE_MSB),
REG_OFFSET(DST, MSI2_DATA),
REG_OFFSET(DST, BASE_LSB),
REG_OFFSET(DST, BASE_MSB),
REG_OFFSET(DST, PRODUCER_INT_SETUP),
REG_OFFSET(DST, PRODUCER_INT2_SETUP),
/* src */
REG_OFFSET(SRC, HP),
REG_OFFSET(SRC, TP),