From: Kalle Valo <kvalo@codeaurora.org>
To: ath11k@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 3/6] ath11k: pci: fix hot reset stability issues
Date: Thu, 10 Dec 2020 16:05:21 +0200 [thread overview]
Message-ID: <1607609124-17250-4-git-send-email-kvalo@codeaurora.org> (raw)
In-Reply-To: <1607609124-17250-1-git-send-email-kvalo@codeaurora.org>
From: Carl Huang <cjhuang@codeaurora.org>
For QCA6390, host needs to reset some registers before MHI power up to fix PCI
link unstable issue if hot reset happened. Also clear all pending interrupts
during power up.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/pci.c | 52 +++++++++++++++++++++++++++++++----
drivers/net/wireless/ath/ath11k/pci.h | 10 +++++++
2 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index c9ab1e9fc0fa..9b6d4bb40e6c 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -239,15 +239,57 @@ static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab)
ath11k_dbg(ab, ATH11K_DBG_PCI, "soc reset cause:%d\n", val);
}
+static void ath11k_pci_enable_ltssm(struct ath11k_base *ab)
+{
+ u32 val;
+ int i;
+
+ val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM);
+
+ /* PCIE link seems very unstable after the Hot Reset*/
+ for (i = 0; val != PARM_LTSSM_VALUE && i < 5; i++) {
+ if (val == 0xffffffff)
+ mdelay(5);
+
+ ath11k_pci_write32(ab, PCIE_PCIE_PARF_LTSSM, PARM_LTSSM_VALUE);
+ val = ath11k_pci_read32(ab, PCIE_PCIE_PARF_LTSSM);
+ }
+
+ ath11k_dbg(ab, ATH11K_DBG_PCI, "pci ltssm 0x%x\n", val);
+
+ val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST);
+ val |= GCC_GCC_PCIE_HOT_RST_VAL | 0x10;
+ ath11k_pci_write32(ab, GCC_GCC_PCIE_HOT_RST, val);
+ val = ath11k_pci_read32(ab, GCC_GCC_PCIE_HOT_RST);
+
+ ath11k_dbg(ab, ATH11K_DBG_PCI, "pci pcie_hot_rst 0x%x\n", val);
+
+ mdelay(5);
+}
+
+static void ath11k_pci_clear_all_intrs(struct ath11k_base *ab)
+{
+ /* This is a WAR for PCIE Hotreset.
+ * When target receive Hotreset, but will set the interrupt.
+ * So when download SBL again, SBL will open Interrupt and
+ * receive it, and crash immediately.
+ */
+ ath11k_pci_write32(ab, PCIE_PCIE_INT_ALL_CLEAR, PCIE_INT_CLEAR_ALL);
+}
+
static void ath11k_pci_force_wake(struct ath11k_base *ab)
{
ath11k_pci_write32(ab, PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1);
mdelay(5);
}
-static void ath11k_pci_sw_reset(struct ath11k_base *ab)
+static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
{
- ath11k_pci_soc_global_reset(ab);
+ if (power_on) {
+ ath11k_pci_enable_ltssm(ab);
+ ath11k_pci_clear_all_intrs(ab);
+ }
+
ath11k_mhi_clear_vector(ab);
ath11k_pci_soc_global_reset(ab);
ath11k_mhi_set_mhictrl_reset(ab);
@@ -770,7 +812,7 @@ static int ath11k_pci_power_up(struct ath11k_base *ab)
ab_pci->register_window = 0;
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
- ath11k_pci_sw_reset(ab_pci->ab);
+ ath11k_pci_sw_reset(ab_pci->ab, true);
ret = ath11k_mhi_start(ab_pci);
if (ret) {
@@ -785,10 +827,10 @@ static void ath11k_pci_power_down(struct ath11k_base *ab)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+ ath11k_pci_force_wake(ab_pci->ab);
ath11k_mhi_stop(ab_pci);
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
- ath11k_pci_force_wake(ab_pci->ab);
- ath11k_pci_sw_reset(ab_pci->ab);
+ ath11k_pci_sw_reset(ab_pci->ab, false);
}
static void ath11k_pci_kill_tasklets(struct ath11k_base *ab)
diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
index 9c503a17c237..296f1ca6b3ec 100644
--- a/drivers/net/wireless/ath/ath11k/pci.h
+++ b/drivers/net/wireless/ath/ath11k/pci.h
@@ -24,6 +24,16 @@
/* register used for handshake mechanism to validate UMAC is awake */
#define PCIE_SOC_WAKE_PCIE_LOCAL_REG 0x3004
+#define PCIE_PCIE_PARF_LTSSM 0x1e081b0
+#define PARM_LTSSM_VALUE 0x111
+
+#define GCC_GCC_PCIE_HOT_RST 0x1e402bc
+#define GCC_GCC_PCIE_HOT_RST_VAL 0x10
+
+#define PCIE_PCIE_INT_ALL_CLEAR 0x1e08228
+#define PCIE_SMLH_REQ_RST_LINK_DOWN 0x2
+#define PCIE_INT_CLEAR_ALL 0xffffffff
+
struct ath11k_msi_user {
char *name;
int num_vectors;
--
2.7.4
next prev parent reply other threads:[~2020-12-10 14:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-10 14:05 [PATCH 0/6] ath11k: QCA6390 stability fixes Kalle Valo
2020-12-10 14:05 ` [PATCH 1/6] ath11k: mhi: print a warning if firmware crashed Kalle Valo
2020-12-12 4:40 ` Kalle Valo
2020-12-10 14:05 ` [PATCH 2/6] ath11k: put hw to DBS using WMI_PDEV_SET_HW_MODE_CMDID Kalle Valo
2020-12-10 14:05 ` Kalle Valo [this message]
2020-12-10 14:05 ` [PATCH 4/6] ath11k: pci: fix L1ss clock unstable problem Kalle Valo
2020-12-10 14:05 ` [PATCH 5/6] ath11k: pci: disable VDD4BLOW Kalle Valo
2020-12-10 22:04 ` Peter Oh
2020-12-11 6:31 ` Kalle Valo
2020-12-10 14:05 ` [PATCH 6/6] ath11k: Fix incorrect tlvs in scan start command Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1607609124-17250-4-git-send-email-kvalo@codeaurora.org \
--to=kvalo@codeaurora.org \
--cc=ath11k@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).