Prechádzať zdrojové kódy

cnss2: Support enable 32k sleep clk from cnss2

Add one new device tree config item "qcom,sleep-clk-supported"
to support enable 32k internal sleep clock in case it has no
external 32k clk attached in wlan chipset HW. Like qca6390
on some auto platform, host need explicitly tell firmware
to use internal sleep clock, otherwise it will cause LMAC
ps failure.

Change-Id: I52f5d332a912235596eb127ab8e4660355988038
CRs-Fixed: 3448595
Chaoli Zhou 2 rokov pred
rodič
commit
03a337ba78
4 zmenil súbory, kde vykonal 25 pridanie a 0 odobranie
  1. 8 0
      cnss2/main.c
  2. 2 0
      cnss2/main.h
  3. 2 0
      cnss2/pci.c
  4. 13 0
      cnss2/qmi.c

+ 8 - 0
cnss2/main.c

@@ -288,6 +288,14 @@ cnss_get_pld_bus_ops_name(struct cnss_plat_data *plat_priv)
 }
 #endif
 
+void cnss_get_sleep_clk_supported(struct cnss_plat_data *plat_priv)
+{
+	plat_priv->sleep_clk = of_property_read_bool(plat_priv->dev_node,
+						     "qcom,sleep-clk-support");
+	cnss_pr_dbg("qcom,sleep-clk-support is %d\n",
+		    plat_priv->sleep_clk);
+}
+
 void cnss_get_bwscal_info(struct cnss_plat_data *plat_priv)
 {
 	plat_priv->no_bwscale = of_property_read_bool(plat_priv->dev_node,

+ 2 - 0
cnss2/main.h

@@ -610,6 +610,7 @@ struct cnss_plat_data {
 	u32 on_chip_pmic_devices_count;
 	u32 *on_chip_pmic_board_ids;
 	bool no_bwscale;
+	bool sleep_clk;
 };
 
 #if IS_ENABLED(CONFIG_ARCH_QCOM)
@@ -642,6 +643,7 @@ struct cnss_plat_data *cnss_get_plat_priv_by_rc_num(int rc_num);
 int cnss_get_plat_env_count(void);
 struct cnss_plat_data *cnss_get_plat_env(int index);
 void cnss_get_qrtr_info(struct cnss_plat_data *plat_priv);
+void cnss_get_sleep_clk_supported(struct cnss_plat_data *plat_priv);
 void cnss_get_bwscal_info(struct cnss_plat_data *plat_priv);
 bool cnss_is_dual_wlan_enabled(void);
 int cnss_driver_event_post(struct cnss_plat_data *plat_priv,

+ 2 - 0
cnss2/pci.c

@@ -6762,6 +6762,8 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
 		goto reset_ctx;
 	}
 
+	cnss_get_sleep_clk_supported(plat_priv);
+
 	ret = cnss_dev_specific_power_on(plat_priv);
 	if (ret < 0)
 		goto reset_ctx;

+ 13 - 0
cnss2/qmi.c

@@ -57,6 +57,11 @@
 #define QMI_WLFW_MAC_READY_TIMEOUT_MS	50
 #define QMI_WLFW_MAC_READY_MAX_RETRY	200
 
+enum nm_modem_bit {
+	SLEEP_CLOCK_SELECT_INTERNAL_BIT = BIT(1),
+	HOST_CSTATE_BIT = BIT(2),
+};
+
 #ifdef CONFIG_CNSS2_DEBUG
 static bool ignore_qmi_failure;
 #define CNSS_QMI_ASSERT() CNSS_ASSERT(ignore_qmi_failure)
@@ -309,6 +314,14 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv)
 	req->cal_done = plat_priv->cal_done;
 	cnss_pr_dbg("Calibration done is %d\n", plat_priv->cal_done);
 
+	if (plat_priv->sleep_clk) {
+		req->nm_modem_valid = 1;
+		/* Notify firmware about the sleep clock selection,
+		 * nm_modem_bit[1] is used for this purpose.
+		 */
+		req->nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
+	}
+
 	if (cnss_bus_is_smmu_s1_enabled(plat_priv) &&
 	    !cnss_bus_get_iova(plat_priv, &iova_start, &iova_size) &&
 	    !cnss_bus_get_iova_ipa(plat_priv, &iova_ipa_start,