Kaynağa Gözat

qcacld-3.0: Fix WLAN IPA perf profile initialization

With IPA WDI unified API, IPA PM is initialized after WLAN IPA pipes
are connected. Initializing IPA perf profile will fail if IPA pipes
are not yet connected.

Fix is to
1. Initialize perf perofile only after IPA pipes are connected
successfully.
2. If clk scaling is disabled, initialize perf level to maximum.
3. Allow driver to proceed if perf profile initialization fails.

Change-Id: I3a63e0f1decec10440467da62cb6ccf740eda318
CRs-Fixed: 2258682
jiad 6 yıl önce
ebeveyn
işleme
f9771185c2

+ 11 - 0
components/ipa/core/inc/wlan_ipa_core.h

@@ -136,6 +136,17 @@ QDF_STATUS wlan_ipa_uc_disable_pipes(struct wlan_ipa_priv *ipa_ctx);
 QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
 				   uint64_t tx_packets, uint64_t rx_packets);
 
+/**
+ * wlan_ipa_init_perf_level() - Initialize IPA performance level
+ * @ipa_ctx: IPA context
+ *
+ * If IPA clock scaling is disabled, initialize perf level to maximum.
+ * Else set the lowest level to start with.
+ *
+ * Return: QDF STATUS
+ */
+QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx);
+
 /**
  * wlan_ipa_get_iface() - Get IPA interface
  * @ipa_ctx: IPA context

+ 3 - 9
components/ipa/core/src/wlan_ipa_core.c

@@ -2668,15 +2668,6 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
 		ipa_ctx->vdev_offload_enabled[i] = false;
 	}
 
-	/* Set the lowest bandwidth to start with */
-	status = wlan_ipa_set_perf_level(ipa_ctx, 0, 0);
-	if (status != QDF_STATUS_SUCCESS) {
-		ipa_err("Set perf level failed: %d", status);
-		wlan_ipa_wdi_rm_inactivity_timer_destroy(
-					QDF_IPA_RM_RESOURCE_WLAN_PROD);
-		goto fail_return;
-	}
-
 	if (cdp_ipa_get_resource(ipa_ctx->dp_soc, ipa_ctx->dp_pdev)) {
 		ipa_err("IPA UC resource alloc fail");
 		status = QDF_STATUS_E_FAILURE;
@@ -2694,6 +2685,9 @@ QDF_STATUS wlan_ipa_uc_ol_init(struct wlan_ipa_priv *ipa_ctx,
 
 		cdp_ipa_set_doorbell_paddr(ipa_ctx->dp_soc, ipa_ctx->dp_pdev);
 		wlan_ipa_init_metering(ipa_ctx);
+
+		if (wlan_ipa_init_perf_level(ipa_ctx) != QDF_STATUS_SUCCESS)
+			ipa_err("Failed to init perf level");
 	}
 
 	cdp_ipa_register_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev,

+ 31 - 4
components/ipa/core/src/wlan_ipa_rm.c

@@ -27,15 +27,12 @@ QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
 				    uint64_t rx_packets)
 {
 	uint32_t next_cons_bw, next_prod_bw;
-	qdf_ipa_rm_perf_profile_t profile;
 	int ret;
 
 	if ((!wlan_ipa_is_enabled(ipa_ctx->config)) ||
 		(!wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config)))
 		return 0;
 
-	qdf_mem_set(&profile, 0, sizeof(profile));
-
 	if (tx_packets > (ipa_ctx->config->bus_bw_high / 2))
 		next_cons_bw = ipa_ctx->config->ipa_bw_high;
 	else if (tx_packets > (ipa_ctx->config->bus_bw_medium / 2))
@@ -87,6 +84,36 @@ QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx)
+{
+	int ret;
+
+	/* Set lowest bandwidth to start with */
+	if (wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config))
+		return wlan_ipa_set_perf_level(ipa_ctx, 0, 0);
+
+	ipa_debug("IPA clk scaling disabled. Set perf level to maximum %d",
+		  WLAN_IPA_MAX_BANDWIDTH);
+
+	ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				     QDF_IPA_CLIENT_WLAN1_CONS,
+				     WLAN_IPA_MAX_BANDWIDTH);
+	if (ret) {
+		ipa_err("CONS set perf profile failed: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc,
+				     QDF_IPA_CLIENT_WLAN1_PROD,
+				     WLAN_IPA_MAX_BANDWIDTH);
+	if (ret) {
+		ipa_err("PROD set perf profile failed: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #ifdef FEATURE_METERING
 void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx)
 {
@@ -463,7 +490,7 @@ void wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx)
 	qdf_cancel_work(&ipa_ctx->uc_rm_work.work);
 	qdf_spinlock_destroy(&ipa_ctx->rm_lock);
 
-	ipa_rm_inactivity_timer_destroy(QDF_IPA_RM_RESOURCE_WLAN_PROD);
+	qdf_ipa_rm_inactivity_timer_destroy(QDF_IPA_RM_RESOURCE_WLAN_PROD);
 
 	ret = qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_CONS);
 	if (ret)