From 9043089a402d8b33b036b408b0bbc7976e623c42 Mon Sep 17 00:00:00 2001 From: Vevek Venkatesan Date: Tue, 21 Apr 2020 15:13:49 +0530 Subject: [PATCH] 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 --- hal/wifi3.0/hal_api.h | 8 ++++++++ hal/wifi3.0/hal_hw_headers.h | 1 + hal/wifi3.0/hal_internal.h | 3 +++ hal/wifi3.0/hal_srng.c | 15 ++++++++++++++- hif/src/ce/ce_service_srng.c | 18 +++++++++++------- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 85a11dfbcdbf..dad28b6d1edb 100644 --- a/hal/wifi3.0/hal_api.h +++ b/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 diff --git a/hal/wifi3.0/hal_hw_headers.h b/hal/wifi3.0/hal_hw_headers.h index 20b359e6484e..43cb81841905 100644 --- a/hal/wifi3.0/hal_hw_headers.h +++ b/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 */ diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 60fc3f4e5a37..ee7cb8be9bb1 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/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; diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index efe96d73d439..69ca137ccfd8 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/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++) { diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 7ba93309b30f..6a97a7228bab 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/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*/