Selaa lähdekoodia

qcacmn: Add support configure EP vote feature based on pm states

Add support to configure EP vote feature based on pm states

Change-Id: Ia424d364248283da8e978f924fd421c1b5f4b888
CRs-Fixed: 2939884
Karthik Kantamneni 4 vuotta sitten
vanhempi
sitoutus
841fa1bd6a
3 muutettua tiedostoa jossa 122 lisäystä ja 0 poistoa
  1. 57 0
      hif/inc/hif.h
  2. 61 0
      hif/src/hif_main.c
  3. 4 0
      hif/src/hif_main.h

+ 57 - 0
hif/inc/hif.h

@@ -45,6 +45,10 @@ extern "C" {
 typedef void __iomem *A_target_id_t;
 typedef void *hif_handle_t;
 
+#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
+#define HIF_WORK_DRAIN_WAIT_CNT 10
+#endif
+
 #define HIF_TYPE_AR6002   2
 #define HIF_TYPE_AR6003   3
 #define HIF_TYPE_AR6004   5
@@ -1064,6 +1068,26 @@ static inline char *rtpm_string_from_dbgid(wlan_rtpm_dbgid id)
 	return (char *)strings[id];
 }
 
+/**
+ * enum hif_ep_vote_type - hif ep vote type
+ * HIF_EP_VOTE_DP_ACCESS: vote type is specific DP
+ * HIF_EP_VOTE_NONDP_ACCESS: ep vote for over all access
+ */
+enum hif_ep_vote_type {
+	HIF_EP_VOTE_DP_ACCESS,
+	HIF_EP_VOTE_NONDP_ACCESS
+};
+
+/**
+ * enum hif_ep_vote_access - hif ep vote access
+ * HIF_EP_VOTE_ACCESS_ENABLE: Enable ep voting
+ * HIF_EP_VOTE_ACCESS_DISABLE: disable ep voting
+ */
+enum hif_ep_vote_access {
+	HIF_EP_VOTE_ACCESS_ENABLE,
+	HIF_EP_VOTE_ACCESS_DISABLE
+};
+
 /**
  * enum hif_pm_link_state - hif link state
  * HIF_PM_LINK_STATE_DOWN: hif link state is down
@@ -1677,6 +1701,39 @@ hif_softc_to_hif_opaque_softc(struct hif_softc *hif_handle)
 	return (struct hif_opaque_softc *)hif_handle;
 }
 
+#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
+QDF_STATUS hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx);
+void hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx);
+void hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+			    uint8_t type, uint8_t access);
+uint8_t hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+			       uint8_t type);
+#else
+static inline QDF_STATUS
+hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+}
+
+static inline void
+hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+		       uint8_t type, uint8_t access)
+{
+}
+
+static inline uint8_t
+hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+		       uint8_t type)
+{
+	return HIF_EP_VOTE_ACCESS_ENABLE;
+}
+#endif
+
 #ifdef FORCE_WAKE
 /**
  * hif_srng_init_phase(): Indicate srng initialization phase

+ 61 - 0
hif/src/hif_main.c

@@ -904,6 +904,7 @@ struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx,
 	scn->bus_type  = bus_type;
 
 	hif_pm_set_link_state(GET_HIF_OPAQUE_HDL(scn), HIF_PM_LINK_STATE_DOWN);
+	hif_allow_ep_vote_access(GET_HIF_OPAQUE_HDL(scn));
 	hif_get_cfg_from_psoc(scn, psoc);
 
 	hif_set_event_hist_mask(GET_HIF_OPAQUE_HDL(scn));
@@ -1048,6 +1049,66 @@ QDF_STATUS hif_try_complete_tasks(struct hif_softc *scn)
 	return QDF_STATUS_SUCCESS;
 }
 
+#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
+QDF_STATUS hif_try_prevent_ep_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+	uint32_t work_drain_wait_cnt = 0;
+	int work = 0;
+
+	qdf_atomic_set(&scn->dp_ep_vote_access,
+		       HIF_EP_VOTE_ACCESS_DISABLE);
+	qdf_atomic_set(&scn->ep_vote_access,
+		       HIF_EP_VOTE_ACCESS_DISABLE);
+
+	while ((work = hif_get_num_pending_work(scn))) {
+		if (++work_drain_wait_cnt > HIF_WORK_DRAIN_WAIT_CNT) {
+			qdf_atomic_set(&scn->dp_ep_vote_access,
+				       HIF_EP_VOTE_ACCESS_ENABLE);
+			qdf_atomic_set(&scn->ep_vote_access,
+				       HIF_EP_VOTE_ACCESS_ENABLE);
+			hif_err("timeout wait for pending work %d ", work);
+			return QDF_STATUS_E_FAULT;
+		}
+		qdf_sleep(5);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void hif_allow_ep_vote_access(struct hif_opaque_softc *hif_ctx)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	qdf_atomic_set(&scn->dp_ep_vote_access,
+		       HIF_EP_VOTE_ACCESS_ENABLE);
+	qdf_atomic_set(&scn->ep_vote_access,
+		       HIF_EP_VOTE_ACCESS_ENABLE);
+}
+
+void hif_set_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+			    uint8_t type, uint8_t access)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	if (type == HIF_EP_VOTE_DP_ACCESS)
+		qdf_atomic_set(&scn->dp_ep_vote_access, access);
+	else
+		qdf_atomic_set(&scn->ep_vote_access, access);
+}
+
+uint8_t hif_get_ep_vote_access(struct hif_opaque_softc *hif_ctx,
+			       uint8_t type)
+{
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	if (type == HIF_EP_VOTE_DP_ACCESS)
+		return qdf_atomic_read(&scn->dp_ep_vote_access);
+	else
+		return qdf_atomic_read(&scn->ep_vote_access);
+}
+#endif
+
 #if (defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \
 	defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390) || \
 	defined(QCA_WIFI_QCN9000) || defined(QCA_WIFI_QCA6490) || \

+ 4 - 0
hif/src/hif_main.h

@@ -296,6 +296,10 @@ struct hif_softc {
 #ifdef SYSTEM_PM_CHECK
 	qdf_atomic_t sys_pm_state;
 #endif
+#if defined(HIF_IPCI) && defined(FEATURE_HAL_DELAYED_REG_WRITE)
+	qdf_atomic_t dp_ep_vote_access;
+	qdf_atomic_t ep_vote_access;
+#endif
 };
 
 static inline