Browse Source

qcacmn: WAR for CE status ring timer intr issue

Enable timer threshold interrupts for CE destination ring.

Change-Id: I851283a5ae6dc6d0f237aa90fdf401fd52794377
Karunakar Dasineni 7 years ago
parent
commit
7b61c6ca74

+ 5 - 1
hif/inc/reg_struct.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -655,6 +655,10 @@ struct ce_reg_def {
 	uint32_t d_CE1_BASE_ADDRESS;
 	uint32_t d_A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_ENABLES;
 	uint32_t d_A_WIFI_APB_3_A_WCMN_APPS_CE_INTR_STATUS;
+	uint32_t d_HOST_IE_ADDRESS_3;
+	uint32_t d_HOST_IE_REG1_CE_LSB;
+	uint32_t d_HOST_IE_REG2_CE_LSB;
+	uint32_t d_HOST_IE_REG3_CE_LSB;
 };
 
 #endif

+ 16 - 0
hif/inc/target_reg_init.h

@@ -358,6 +358,18 @@ struct targetdef_s *MY_TARGET_DEF = &my_target_def;
 #if !defined(HOST_IE_ADDRESS_2)
 #define HOST_IE_ADDRESS_2 ATH_UNSUPPORTED_REG_OFFSET
 #endif
+#if !defined(HOST_IE_ADDRESS_3)
+#define HOST_IE_ADDRESS_3 ATH_UNSUPPORTED_REG_OFFSET
+#endif
+#if !defined(HOST_IE_REG1_CE_LSB)
+#define HOST_IE_REG1_CE_LSB 0
+#endif
+#if !defined(HOST_IE_REG2_CE_LSB)
+#define HOST_IE_REG2_CE_LSB 0
+#endif
+#if !defined(HOST_IE_REG3_CE_LSB)
+#define HOST_IE_REG3_CE_LSB 0
+#endif
 
 static struct ce_reg_def my_ce_reg_def = {
 	/* copy_engine.c */
@@ -386,7 +398,11 @@ static struct ce_reg_def my_ce_reg_def = {
 	.d_CE_DDR_ADDRESS_FOR_RRI_LOW = CE_DDR_ADDRESS_FOR_RRI_LOW,
 	.d_CE_DDR_ADDRESS_FOR_RRI_HIGH = CE_DDR_ADDRESS_FOR_RRI_HIGH,
 	.d_HOST_IE_ADDRESS = HOST_IE_ADDRESS,
+	.d_HOST_IE_REG1_CE_LSB = HOST_IE_REG1_CE_LSB,
 	.d_HOST_IE_ADDRESS_2 = HOST_IE_ADDRESS_2,
+	.d_HOST_IE_REG2_CE_LSB = HOST_IE_REG2_CE_LSB,
+	.d_HOST_IE_ADDRESS_3 = HOST_IE_ADDRESS_3,
+	.d_HOST_IE_REG3_CE_LSB = HOST_IE_REG3_CE_LSB,
 	.d_HOST_IE_COPY_COMPLETE_MASK = HOST_IE_COPY_COMPLETE_MASK,
 	.d_SR_BA_ADDRESS = SR_BA_ADDRESS,
 	.d_SR_BA_ADDRESS_HIGH = SR_BA_ADDRESS_HIGH,

+ 7 - 0
hif/src/ce/ce_reg.h

@@ -213,7 +213,11 @@
 #define CE_DEBUG_SEL_LSB          (scn->target_ce_def->d_CE_DEBUG_SEL_LSB)
 #define CE_DEBUG_SEL_MASK         (scn->target_ce_def->d_CE_DEBUG_SEL_MASK)
 #define HOST_IE_ADDRESS           (scn->target_ce_def->d_HOST_IE_ADDRESS)
+#define HOST_IE_REG1_CE_LSB       (scn->target_ce_def->d_HOST_IE_REG1_CE_LSB)
 #define HOST_IE_ADDRESS_2         (scn->target_ce_def->d_HOST_IE_ADDRESS_2)
+#define HOST_IE_REG2_CE_LSB       (scn->target_ce_def->d_HOST_IE_REG2_CE_LSB)
+#define HOST_IE_ADDRESS_3         (scn->target_ce_def->d_HOST_IE_ADDRESS_3)
+#define HOST_IE_REG3_CE_LSB       (scn->target_ce_def->d_HOST_IE_REG3_CE_LSB)
 #define HOST_IS_ADDRESS           (scn->target_ce_def->d_HOST_IS_ADDRESS)
 
 #define SRC_WATERMARK_LOW_SET(x) \
@@ -267,6 +271,9 @@
 	(((x) << CE_WRAPPER_DEBUG_SEL_LSB) & CE_WRAPPER_DEBUG_SEL_MASK)
 #define CE_DEBUG_SEL_GET(x) (((x) & CE_DEBUG_SEL_MASK) >> CE_DEBUG_SEL_LSB)
 #define CE_DEBUG_SEL_SET(x) (((x) << CE_DEBUG_SEL_LSB) & CE_DEBUG_SEL_MASK)
+#define HOST_IE_REG1_CE_BIT(_ce_id) (1 << (_ce_id + HOST_IE_REG1_CE_LSB))
+#define HOST_IE_REG2_CE_BIT(_ce_id) (1 << (_ce_id + HOST_IE_REG2_CE_LSB))
+#define HOST_IE_REG3_CE_BIT(_ce_id) (1 << (_ce_id + HOST_IE_REG3_CE_LSB))
 
 uint32_t DEBUG_CE_SRC_RING_READ_IDX_GET(struct hif_softc *scn,
 		uint32_t CE_ctrl_addr);

+ 4 - 2
hif/src/ce/ce_service_srng.c

@@ -643,8 +643,10 @@ static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 	ring_params.ring_base_paddr = dest_ring->base_addr_CE_space;
 	ring_params.ring_base_vaddr = dest_ring->base_addr_owner_space;
 	ring_params.num_entries = dest_ring->nentries;
-	ring_params.intr_timer_thres_us = 0;
-	ring_params.intr_batch_cntr_thres_entries = 1;
+	ring_params.low_threshold = dest_ring->nentries - 1;
+	ring_params.flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
+	ring_params.intr_timer_thres_us = 1024;
+	ring_params.intr_batch_cntr_thres_entries = 0;
 	ring_params.max_buffer_length = attr->src_sz_max;
 
 	/* TODO

+ 8 - 1
hif/src/qca8074def.c

@@ -156,8 +156,15 @@
 #define HOST_IE_ADDRESS \
 	HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_ADDR(\
 		SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_COMMON_REG_OFFSET)
-#define HOST_IE_ADDRESS_2 HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_1_ADDR(\
+#define HOST_IE_REG1_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_SRC_RING_IE_SHFT
+#define HOST_IE_ADDRESS_2 \
+	HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_1_ADDR(\
 		SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_COMMON_REG_OFFSET)
+#define HOST_IE_REG2_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_1_STS_RING_IE_SHFT
+#define HOST_IE_ADDRESS_3 \
+	HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_ADDR(\
+		SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_COMMON_REG_OFFSET)
+#define HOST_IE_REG3_CE_LSB HWIO_WFSS_CE_COMMON_R0_CE_HOST_IE_0_DST_RING_IE_SHFT
 #else
 #define HOST_IE_ADDRESS UMAC_CE_COMMON_CE_HOST_IE_0
 #define HOST_IE_ADDRESS_2 UMAC_CE_COMMON_CE_HOST_IE_1

+ 22 - 4
hif/src/snoc/if_ahb.c

@@ -634,13 +634,14 @@ void hif_ahb_irq_enable(struct hif_softc *scn, int ce_id)
 	uint32_t reg_offset = 0;
 	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
 	struct CE_pipe_config *target_ce_conf = &hif_state->target_ce_config[ce_id];
+	struct hif_target_info *tgt_info = &scn->target_info;
 
 	if (scn->per_ce_irq) {
 		if (target_ce_conf->pipedir & PIPEDIR_OUT) {
 			reg_offset = HOST_IE_ADDRESS;
 			qdf_spin_lock_irqsave(&hif_state->irq_reg_lock);
 			regval = hif_read32_mb(scn->mem + reg_offset);
-			regval |= (1 << ce_id);
+			regval |= HOST_IE_REG1_CE_BIT(ce_id);
 			hif_write32_mb(scn->mem + reg_offset, regval);
 			qdf_spin_unlock_irqrestore(&hif_state->irq_reg_lock);
 		}
@@ -648,8 +649,16 @@ void hif_ahb_irq_enable(struct hif_softc *scn, int ce_id)
 			reg_offset = HOST_IE_ADDRESS_2;
 			qdf_spin_lock_irqsave(&hif_state->irq_reg_lock);
 			regval = hif_read32_mb(scn->mem + reg_offset);
-			regval |= (1 << ce_id);
+			regval |= HOST_IE_REG2_CE_BIT(ce_id);
 			hif_write32_mb(scn->mem + reg_offset, regval);
+			if (tgt_info->target_type == TARGET_TYPE_QCA8074) {
+				/* Enable destination ring interrupts for 8074
+				 * TODO: To be removed in 2.0 HW */
+				regval = hif_read32_mb(scn->mem +
+					HOST_IE_ADDRESS_3);
+				regval |= HOST_IE_REG3_CE_BIT(ce_id);
+			}
+			hif_write32_mb(scn->mem + HOST_IE_ADDRESS_3, regval);
 			qdf_spin_unlock_irqrestore(&hif_state->irq_reg_lock);
 		}
 	} else {
@@ -670,13 +679,14 @@ void hif_ahb_irq_disable(struct hif_softc *scn, int ce_id)
 	uint32_t reg_offset = 0;
 	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
 	struct CE_pipe_config *target_ce_conf = &hif_state->target_ce_config[ce_id];
+	struct hif_target_info *tgt_info = &scn->target_info;
 
 	if (scn->per_ce_irq) {
 		if (target_ce_conf->pipedir & PIPEDIR_OUT) {
 			reg_offset = HOST_IE_ADDRESS;
 			qdf_spin_lock_irqsave(&hif_state->irq_reg_lock);
 			regval = hif_read32_mb(scn->mem + reg_offset);
-			regval &= ~(1 << ce_id);
+			regval &= ~HOST_IE_REG1_CE_BIT(ce_id);
 			hif_write32_mb(scn->mem + reg_offset, regval);
 			qdf_spin_unlock_irqrestore(&hif_state->irq_reg_lock);
 		}
@@ -684,8 +694,16 @@ void hif_ahb_irq_disable(struct hif_softc *scn, int ce_id)
 			reg_offset = HOST_IE_ADDRESS_2;
 			qdf_spin_lock_irqsave(&hif_state->irq_reg_lock);
 			regval = hif_read32_mb(scn->mem + reg_offset);
-			regval &= ~(1 << ce_id);
+			regval &= ~HOST_IE_REG2_CE_BIT(ce_id);
 			hif_write32_mb(scn->mem + reg_offset, regval);
+			if (tgt_info->target_type == TARGET_TYPE_QCA8074) {
+				/* Disable destination ring interrupts for 8074
+				 * TODO: To be removed in 2.0 HW */
+				regval = hif_read32_mb(scn->mem +
+					HOST_IE_ADDRESS_3);
+				regval &= ~HOST_IE_REG3_CE_BIT(ce_id);
+			}
+			hif_write32_mb(scn->mem + HOST_IE_ADDRESS_3, regval);
 			qdf_spin_unlock_irqrestore(&hif_state->irq_reg_lock);
 		}
 	}