[PATCH 368/379][SRU][OEM-5.6] UBUNTU: SAUCE: ath11k: fix PCI L1ss clock unstable problem

You-Sheng Yang vicamo.yang at canonical.com
Wed Dec 23 08:51:41 UTC 2020


From: Carl Huang <cjhuang at codeaurora.org>

BugLink: https://bugs.launchpad.net/bugs/1879633

For QCA6390, one PCI related clock drifts sometimes, and
it makes PCI link difficult to quit L1ss. Fix it by writing
some registers which are known to fix the problem.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1

Signed-off-by: Carl Huang <cjhuang at codeaurora.org>
Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
(cherry picked from commit 08816aab67540e6babc558dafa973fc905a9afa1
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git)
Signed-off-by: You-Sheng Yang <vicamo.yang at canonical.com>
---
 drivers/net/wireless/ath/ath11k/pci.c | 59 +++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/pci.h | 11 +++++
 2 files changed, 70 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 62bd445549c0..95c4d210edf1 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -241,6 +241,64 @@ static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab)
 	ath11k_dbg(ab, ATH11K_DBG_PCI, "soc reset cause:%d\n", val);
 }
 
+static bool ath11k_pci_set_link_reg(struct ath11k_base *ab,
+				    u32 offset, u32 value, u32 mask)
+{
+	u32 ret;
+	int count = 10;
+
+	ret = ath11k_pci_read32(ab, offset);
+	if ((ret & mask) == value)
+		return true;
+
+	while (count > 0) {
+		ath11k_pci_write32(ab, offset, (ret & ~mask) | value);
+		ret = ath11k_pci_read32(ab, offset);
+		if ((ret & mask) == value)
+			return true;
+
+		mdelay(2);
+		count--;
+	}
+
+	ath11k_err(ab, "%s: Failed to set Pcie Link Register 0x%08x to 0x%08x\n",
+		   __func__, offset, ret);
+	return false;
+}
+
+static void ath11k_pci_fix_l1ss(struct ath11k_base *ab)
+{
+	if (!ath11k_pci_set_link_reg(ab,
+				     PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG,
+				     PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL,
+				     PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK)) {
+		ath11k_err(ab, "%s set sysclk error\n", __func__);
+		return;
+	}
+
+	if (!ath11k_pci_set_link_reg(ab,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK)) {
+		ath11k_err(ab, "%s set dtct_config1 error\n", __func__);
+		return;
+	}
+
+	if (!ath11k_pci_set_link_reg(ab,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK)) {
+		ath11k_err(ab, "%s set dtct_config2 error\n", __func__);
+		return;
+	}
+
+	if (!ath11k_pci_set_link_reg(ab,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL,
+				     PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK))
+		ath11k_err(ab, "%s set dtct_config4 error\n", __func__);
+}
+
 static void ath11k_pci_enable_LTSSM(struct ath11k_base *ab)
 {
 	u32 val;
@@ -300,6 +358,7 @@ static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
 	if (power_on) {
 		ath11k_pci_enable_LTSSM(ab);
 		ath11k_pci_clear_all_intrs(ab);
+		ath11k_pci_fix_l1ss(ab);
 	}
 
 	ath11k_mhi_clear_vector(ab);
diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
index 27124ac92cf7..00a2e9dd2dfc 100644
--- a/drivers/net/wireless/ath/ath11k/pci.h
+++ b/drivers/net/wireless/ath/ath11k/pci.h
@@ -34,6 +34,17 @@
 #define PCIE_SMLH_REQ_RST_LINK_DOWN       0x2
 #define PCIE_INT_CLEAR_ALL                0xFFFFFFFF
 
+#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG      0x01E0C0AC
+#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL      0x10
+#define PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK      0xFFFFFFFF
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_REG 0x01E0C628
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG1_VAL 0x02
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_REG 0x01E0C62C
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG2_VAL 0x52
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_REG 0x01E0C634
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG4_VAL 0xFF
+#define PCIE_USB3_PCS_MISC_OSC_DTCT_CONFIG_MSK  0x000000FF
+
 struct ath11k_msi_user {
 	char *name;
 	int num_vectors;
-- 
2.29.2




More information about the kernel-team mailing list