فهرست منبع

cnss2: Set and retrain PCIe link for PCIe switch

When WLAN is attached to PCIe switch, set and retrain DSP <-> EP link
in BW scale callback function. It avoids touching RC <-> USP link which
may impact other devices.
With this change, it could support Hamilton PCIe Gen3 on PCIe switch
platform.

Change-Id: Id444ac847613971545bf66db9bb1a6e427028802
CRs-Fixed: 3848272
Jiani Liu 7 ماه پیش
والد
کامیت
ae1e042498
4فایلهای تغییر یافته به همراه54 افزوده شده و 0 حذف شده
  1. 5 0
      Kbuild
  2. 6 0
      cnss2/pci.c
  3. 8 0
      cnss2/pci_platform.h
  4. 35 0
      cnss2/pci_qcom.c

+ 5 - 0
Kbuild

@@ -91,6 +91,11 @@ ifeq ($(findstring yes, $(found)), yes)
 KBUILD_CPPFLAGS += -DCONFIG_PCIE_SWITCH_SUPPORT
 endif
 
+found = $(shell if grep -qF "int msm_pcie_retrain_port_link" $(srctree)/include/linux/msm_pcie.h; then echo "yes" ;else echo "no" ;fi;)
+ifeq ($(findstring yes, $(found)), yes)
+KBUILD_CPPFLAGS += -DCONFIG_PCIE_SWITCH_RETRAIN_LINK_SUPPORT
+endif
+
 obj-$(CONFIG_CNSS2) += cnss2/
 obj-$(CONFIG_ICNSS2) += icnss2/
 obj-$(CONFIG_CNSS_GENL) += cnss_genl/

+ 6 - 0
cnss2/pci.c

@@ -6905,6 +6905,12 @@ static int cnss_mhi_bw_scale(struct mhi_controller *mhi_ctrl,
 	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
 	int ret = 0;
 
+	if (plat_priv->pcie_switch_type == PCIE_SWITCH_NTN3) {
+		ret = cnss_pci_dsp_link_retrain(pci_priv,
+						link_info->target_link_speed);
+		return ret;
+	}
+
 	cnss_pr_dbg("Setting link speed:0x%x, width:0x%x\n",
 		    link_info->target_link_speed,
 		    link_info->target_link_width);

+ 8 - 0
cnss2/pci_platform.h

@@ -132,6 +132,8 @@ int cnss_pci_set_dsp_link_status(struct cnss_pci_data *pci_priv,
 				 bool link_enable);
 int cnss_pci_get_dsp_link_status(struct cnss_pci_data *pci_priv);
 int cnss_pci_dsp_link_enable(struct cnss_pci_data *pci_priv);
+int cnss_pci_dsp_link_retrain(struct cnss_pci_data *pci_priv,
+			      u16 target_link_speed);
 #else
 int _cnss_pci_enumerate(struct cnss_plat_data *plat_priv, u32 rc_num)
 {
@@ -230,6 +232,12 @@ int cnss_pci_dsp_link_enable(struct cnss_pci_data *pci_priv)
 {
 	return -EOPNOTSUPP;
 }
+
+int cnss_pci_dsp_link_retrain(struct cnss_pci_data *pci_priv,
+			      u16 target_link_speed)
+{
+	return -EOPNOTSUPP;
+}
 #endif /* CONFIG_PCI_MSM */
 
 static inline bool cnss_pci_get_drv_supported(struct cnss_pci_data *pci_priv)

+ 35 - 0
cnss2/pci_qcom.c

@@ -466,6 +466,35 @@ int cnss_pci_dsp_link_enable(struct cnss_pci_data *pci_priv)
 
 	return ret;
 }
+
+#ifdef CONFIG_PCIE_SWITCH_RETRAIN_LINK_SUPPORT
+int cnss_pci_dsp_link_retrain(struct cnss_pci_data *pci_priv,
+			      u16 target_link_speed)
+{
+	int ret = 0;
+
+	if (!pci_priv)
+		return -ENODEV;
+
+	cnss_pr_dbg("Setting DSP <-> EP link speed:0x%x\n", target_link_speed);
+
+	ret = msm_pcie_retrain_port_link(pci_priv->pci_dev, target_link_speed);
+	if (ret) {
+		cnss_pr_err("Failed to retrain link, err = %d\n", ret);
+		return ret;
+	}
+
+	pci_priv->def_link_speed = target_link_speed;
+
+	return ret;
+}
+#else
+int cnss_pci_dsp_link_retrain(struct cnss_pci_data *pci_priv,
+			      u16 target_link_speed)
+{
+	return -EOPNOTSUPP;
+}
+#endif
 #else
 int cnss_pci_dsp_link_control(struct cnss_pci_data *pci_priv,
 			      bool link_enable)
@@ -488,6 +517,12 @@ int cnss_pci_dsp_link_enable(struct cnss_pci_data *pci_priv)
 {
 	return -EOPNOTSUPP;
 }
+
+int cnss_pci_dsp_link_retrain(struct cnss_pci_data *pci_priv,
+			      u16 target_link_speed)
+{
+	return -EOPNOTSUPP;
+}
 #endif
 
 int cnss_pci_prevent_l1(struct device *dev)