From ae1e042498b36886dffb40c90d6d6c24790d92bf Mon Sep 17 00:00:00 2001 From: Jiani Liu Date: Mon, 22 Jul 2024 19:22:08 +0800 Subject: [PATCH] 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 --- Kbuild | 5 +++++ cnss2/pci.c | 6 ++++++ cnss2/pci_platform.h | 8 ++++++++ cnss2/pci_qcom.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/Kbuild b/Kbuild index 2e4f8194df..bd3661de60 100644 --- a/Kbuild +++ b/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/ diff --git a/cnss2/pci.c b/cnss2/pci.c index be0bcb009b..8e7cd7175e 100644 --- a/cnss2/pci.c +++ b/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); diff --git a/cnss2/pci_platform.h b/cnss2/pci_platform.h index 05fa9ce54a..57549053de 100644 --- a/cnss2/pci_platform.h +++ b/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) diff --git a/cnss2/pci_qcom.c b/cnss2/pci_qcom.c index 2b28784363..cd5d6f2141 100644 --- a/cnss2/pci_qcom.c +++ b/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)