diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index 79872d2f1b..ef79f33028 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -1277,6 +1277,44 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, #else #ifdef FEATURE_HAL_DELAYED_REG_WRITE +#ifdef QCA_WIFI_QCA6750 +void hal_delayed_reg_write(struct hal_soc *hal_soc, + struct hal_srng *srng, + void __iomem *addr, + uint32_t value) +{ + switch (srng->ring_type) { + case CE_SRC: + case CE_DST: + case CE_DST_STATUS: + if (hif_get_ep_vote_access(hal_soc->hif_handle, + HIF_EP_VOTE_NONDP_ACCESS) == + HIF_EP_VOTE_ACCESS_DISABLE) { + hal_write_address_32_mb(hal_soc, addr, value, false); + qdf_atomic_inc(&hal_soc->stats.wstats.direct); + srng->wstats.direct++; + } else { + hal_reg_write_enqueue(hal_soc, srng, addr, value); + } + break; + default: + if (hif_get_ep_vote_access(hal_soc->hif_handle, + HIF_EP_VOTE_DP_ACCESS) == + HIF_EP_VOTE_ACCESS_DISABLE || + hal_is_reg_write_tput_level_high(hal_soc) || + PLD_MHI_STATE_L0 == + pld_get_mhi_state(hal_soc->qdf_dev->dev)) { + hal_write_address_32_mb(hal_soc, addr, value, false); + qdf_atomic_inc(&hal_soc->stats.wstats.direct); + srng->wstats.direct++; + } else { + hal_reg_write_enqueue(hal_soc, srng, addr, value); + } + + break; + } +} +#else void hal_delayed_reg_write(struct hal_soc *hal_soc, struct hal_srng *srng, void __iomem *addr, @@ -1293,6 +1331,7 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc, } #endif #endif +#endif /** * hal_attach - Initialize HAL layer diff --git a/hif/src/ipcie/if_ipci.c b/hif/src/ipcie/if_ipci.c index dfc12f6346..3c557eb788 100644 --- a/hif/src/ipcie/if_ipci.c +++ b/hif/src/ipcie/if_ipci.c @@ -878,11 +878,54 @@ void hif_print_ipci_stats(struct hif_ipci_softc *ipci_handle) #ifdef FEATURE_HAL_DELAYED_REG_WRITE int hif_prevent_link_low_power_states(struct hif_opaque_softc *hif) { + struct hif_softc *scn = HIF_GET_SOFTC(hif); + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + uint32_t timeout = 0; + + while (pld_is_pci_ep_awake(scn->qdf_dev->dev) && + timeout <= EP_WAKE_RESET_DELAY_TIMEOUT_US) { + qdf_sleep_us(EP_WAKE_RESET_DELAY_US); + timeout += EP_WAKE_RESET_DELAY_US; + } + + if (pld_is_pci_ep_awake(scn->qdf_dev->dev)) { + hif_err_rl(" EP state reset is not done to prevent l1"); + ipci_scn->ep_awake_reset_fail++; + return 0; + } + + if (pld_prevent_l1(scn->qdf_dev->dev)) { + hif_err_rl("pld prevent l1 failed"); + ipci_scn->prevent_l1_fail++; + return 0; + } + + ipci_scn->prevent_l1 = true; + timeout = 0; + while (!pld_is_pci_ep_awake(scn->qdf_dev->dev) && + timeout <= EP_WAKE_DELAY_TIMEOUT_US) { + qdf_sleep_us(EP_WAKE_DELAY_US); + timeout += EP_WAKE_DELAY_US; + } + + if (pld_is_pci_ep_awake(scn->qdf_dev->dev) <= 0) { + hif_err_rl("Unable to wakeup pci ep"); + ipci_scn->ep_awake_set_fail++; + return 0; + } + return 0; } void hif_allow_link_low_power_states(struct hif_opaque_softc *hif) { + struct hif_softc *scn = HIF_GET_SOFTC(hif); + struct hif_ipci_softc *ipci_scn = HIF_GET_IPCI_SOFTC(scn); + + if (qdf_likely(ipci_scn->prevent_l1)) { + pld_allow_l1(scn->qdf_dev->dev); + ipci_scn->prevent_l1 = false; + } } #endif diff --git a/hif/src/ipcie/if_ipci.h b/hif/src/ipcie/if_ipci.h index 7779eaf3dd..afbd9a1646 100644 --- a/hif/src/ipcie/if_ipci.h +++ b/hif/src/ipcie/if_ipci.h @@ -66,6 +66,18 @@ struct hif_ipci_stats { #define FORCE_WAKE_DELAY_MS 5 #endif /* FORCE_WAKE */ +#ifdef FEATURE_HAL_DELAYED_REG_WRITE +#ifdef HAL_CONFIG_SLUB_DEBUG_ON +#define EP_WAKE_RESET_DELAY_TIMEOUT_US 3000 +#define EP_WAKE_DELAY_TIMEOUT_US 7000 +#else +#define EP_WAKE_RESET_DELAY_TIMEOUT_US 10000 +#define EP_WAKE_DELAY_TIMEOUT_US 10000 +#endif +#define EP_WAKE_RESET_DELAY_US 50 +#define EP_WAKE_DELAY_US 200 +#endif + struct hif_ipci_softc { struct HIF_CE_state ce_sc; void __iomem *mem; /* PCI address. */ @@ -83,6 +95,12 @@ struct hif_ipci_softc { void (*hif_ipci_get_soc_info)(struct hif_ipci_softc *sc, struct device *dev); +#ifdef FEATURE_HAL_DELAYED_REG_WRITE + uint32_t ep_awake_reset_fail; + uint32_t prevent_l1_fail; + uint32_t ep_awake_set_fail; + bool prevent_l1; +#endif #ifdef FORCE_WAKE struct hif_ipci_stats stats; #endif