Эх сурвалжийг харах

qcacmn: Add prefetch_timer config for CE rings

Add prefetch_timer configuration for CE rings.
Set prefetch_timer=1 configuration for qca6490 destination CEs,
prefetch_timer=0 configuration for other targets CEs.

Basically setting to 1us asking CE hw to update ring tail pointer to
update within 1us. FW side CE SW sets all rings to 1us already.
Idea behind this change  is, we have seen pre-silicon issue where SRC
ring TP read by SW was not seen updated value when prefetch was set
to 8us. Changing prefetch timer value to 1us helps to resolve
pre-silicon issue.
So host side rings need to update the prefetch timer to 1us.

Change-Id: I0830c73517c29cf39e6b2974bf3faa44e5673741
CRs-Fixed: 2669762
Vevek Venkatesan 5 жил өмнө
parent
commit
9043089a40

+ 8 - 0
hal/wifi3.0/hal_api.h

@@ -643,6 +643,12 @@ enum hal_ring_type {
 #define HAL_SRNG_MSI_INTR				0x00020000
 #define HAL_SRNG_CACHED_DESC		0x00040000
 
+#ifdef QCA_WIFI_QCA6490
+#define HAL_SRNG_PREFETCH_TIMER 1
+#else
+#define HAL_SRNG_PREFETCH_TIMER 0
+#endif
+
 #define PN_SIZE_24 0
 #define PN_SIZE_48 1
 #define PN_SIZE_128 2
@@ -748,6 +754,8 @@ struct hal_srng_params {
 	uint32_t entry_size;
 	/* hw register base address */
 	void *hwreg_base[MAX_SRNG_REG_GROUPS];
+	/* prefetch timer config - in micro seconds */
+	uint32_t prefetch_timer;
 };
 
 /* hal_construct_shadow_config() - initialize the shadow registers for dp rings

+ 1 - 0
hal/wifi3.0/hal_hw_headers.h

@@ -40,6 +40,7 @@
 #include "ce_stat_desc.h"
 #ifdef QCA_WIFI_QCA6490
 #include "wfss_ce_channel_dst_reg_seq_hwioreg.h"
+#include "wfss_ce_channel_src_reg_seq_hwioreg.h"
 #else
 #include "wfss_ce_reg_seq_hwioreg.h"
 #endif /* QCA_WIFI_QCA6490 */

+ 3 - 0
hal/wifi3.0/hal_internal.h

@@ -337,6 +337,9 @@ struct hal_srng {
 	/* Interrupt batch counter threshold – in number of ring entries */
 	uint32_t intr_batch_cntr_thres_entries;
 
+	/* Applicable only for CE dest ring */
+	uint32_t prefetch_timer;
+
 	/* MSI Address */
 	qdf_dma_addr_t msi_addr;
 

+ 14 - 1
hal/wifi3.0/hal_srng.c

@@ -835,7 +835,6 @@ extern void hal_detach(void *hal_soc)
 }
 qdf_export_symbol(hal_detach);
 
-
 /**
  * hal_ce_dst_setup - Initialize CE destination ring registers
  * @hal_soc: HAL SOC handle
@@ -859,6 +858,19 @@ static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng,
 	reg_val |= srng->u.dst_ring.max_buffer_length &
 		HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK;
 	HAL_REG_WRITE(hal, reg_addr, reg_val);
+
+	if (srng->prefetch_timer) {
+		reg_addr = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_CONSUMER_PREFETCH_TIMER_ADDR(
+				ring_config->reg_start[R0_INDEX] +
+				(ring_num * ring_config->reg_size[R0_INDEX]));
+
+		reg_val = HAL_REG_READ(hal, reg_addr);
+		reg_val &= ~HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_CONSUMER_PREFETCH_TIMER_RMSK;
+		reg_val |= srng->prefetch_timer;
+		HAL_REG_WRITE(hal, reg_addr, reg_val);
+		reg_val = HAL_REG_READ(hal, reg_addr);
+	}
+
 }
 
 /**
@@ -1053,6 +1065,7 @@ void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num,
 	srng->intr_timer_thres_us = ring_params->intr_timer_thres_us;
 	srng->intr_batch_cntr_thres_entries =
 		ring_params->intr_batch_cntr_thres_entries;
+	srng->prefetch_timer = ring_params->prefetch_timer;
 	srng->hal_soc = hal_soc;
 
 	for (i = 0 ; i < MAX_SRNG_REG_GROUPS; i++) {

+ 11 - 7
hif/src/ce/ce_service_srng.c

@@ -739,8 +739,8 @@ static void ce_srng_msi_ring_params_setup(struct hif_softc *scn, uint32_t ce_id,
 }
 
 static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
-			struct CE_ring_state *src_ring,
-			struct CE_attr *attr)
+				   struct CE_ring_state *src_ring,
+				   struct CE_attr *attr)
 {
 	struct hal_srng_params ring_params = {0};
 
@@ -761,6 +761,7 @@ static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 
 		ring_params.intr_timer_thres_us = 0;
 		ring_params.intr_batch_cntr_thres_entries = 1;
+		ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER;
 	}
 
 	src_ring->srng_ctx = hal_srng_setup(scn->hal_soc, CE_SRC, ce_id, 0,
@@ -786,8 +787,9 @@ static void ce_srng_src_ring_setup(struct hif_softc *scn, uint32_t ce_id,
  * fails to post the last entry due to the race condition.
  */
 static void ce_srng_initialize_dest_timer_interrupt_war(
-		struct CE_ring_state *dest_ring,
-		struct hal_srng_params *ring_params) {
+					struct CE_ring_state *dest_ring,
+					struct hal_srng_params *ring_params)
+{
 	int num_buffers_when_fully_posted = dest_ring->nentries - 2;
 
 	ring_params->low_threshold = num_buffers_when_fully_posted - 1;
@@ -796,9 +798,10 @@ static void ce_srng_initialize_dest_timer_interrupt_war(
 	ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
 }
 
-static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
-				struct CE_ring_state *dest_ring,
-				struct CE_attr *attr)
+static void ce_srng_dest_ring_setup(struct hif_softc *scn,
+				    uint32_t ce_id,
+				    struct CE_ring_state *dest_ring,
+				    struct CE_attr *attr)
 {
 	struct hal_srng_params ring_params = {0};
 	bool status_ring_timer_thresh_work_arround = true;
@@ -822,6 +825,7 @@ static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 			ring_params.intr_batch_cntr_thres_entries = 0;
 			ring_params.flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
 		}
+		ring_params.prefetch_timer = HAL_SRNG_PREFETCH_TIMER;
 	}
 
 	/*Dest ring is also source ring*/