mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 17:48:58 +00:00
72 lines
2.7 KiB
Diff
72 lines
2.7 KiB
Diff
|
From 4b0c6453808a662869a43c504913f3b7ed64486a Mon Sep 17 00:00:00 2001
|
||
|
From: Jonathan Bell <jonathan@raspberrypi.com>
|
||
|
Date: Wed, 20 Sep 2023 13:01:11 +0100
|
||
|
Subject: [PATCH] drivers: pci: brcmstb: optionally extend Tperst_clk time
|
||
|
during link-up
|
||
|
|
||
|
The RC has a feature that allows for manual control over the deassertion
|
||
|
of the PERST# output pin, which allows the time between refclk active
|
||
|
and reset deassert at the EP to be increased.
|
||
|
|
||
|
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
|
||
|
---
|
||
|
drivers/pci/controller/pcie-brcmstb.c | 24 +++++++++++++++++++++++-
|
||
|
1 file changed, 23 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/drivers/pci/controller/pcie-brcmstb.c
|
||
|
+++ b/drivers/pci/controller/pcie-brcmstb.c
|
||
|
@@ -138,6 +138,7 @@
|
||
|
|
||
|
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG pcie->reg_offsets[PCIE_HARD_DEBUG]
|
||
|
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
|
||
|
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK 0x8
|
||
|
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
|
||
|
#define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
|
||
|
#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK 0x00200000
|
||
|
@@ -352,6 +353,7 @@ struct brcm_pcie {
|
||
|
bool (*rc_mode)(struct brcm_pcie *pcie);
|
||
|
struct subdev_regulators *sr;
|
||
|
bool ep_wakeup_capable;
|
||
|
+ u32 tperst_clk_ms;
|
||
|
};
|
||
|
|
||
|
static inline bool is_bmips(const struct brcm_pcie *pcie)
|
||
|
@@ -1388,9 +1390,28 @@ static int brcm_pcie_start_link(struct b
|
||
|
u16 nlw, cls, lnksta;
|
||
|
bool ssc_good = false;
|
||
|
int ret, i;
|
||
|
+ u32 tmp;
|
||
|
|
||
|
/* Unassert the fundamental reset */
|
||
|
- pcie->perst_set(pcie, 0);
|
||
|
+ if (pcie->tperst_clk_ms) {
|
||
|
+ /*
|
||
|
+ * Increase Tperst_clk time by forcing PERST# output low while
|
||
|
+ * the internal reset is released, so the PLL generates stable
|
||
|
+ * refclk output further in advance of PERST# deassertion.
|
||
|
+ */
|
||
|
+ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
|
||
|
+ u32p_replace_bits(&tmp, 1, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK);
|
||
|
+ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
|
||
|
+
|
||
|
+ pcie->perst_set(pcie, 0);
|
||
|
+ msleep(pcie->tperst_clk_ms);
|
||
|
+
|
||
|
+ tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
|
||
|
+ u32p_replace_bits(&tmp, 0, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK);
|
||
|
+ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
|
||
|
+ } else {
|
||
|
+ pcie->perst_set(pcie, 0);
|
||
|
+ }
|
||
|
|
||
|
/*
|
||
|
* Wait for 100ms after PERST# deassertion; see PCIe CEM specification
|
||
|
@@ -1923,6 +1944,7 @@ static int brcm_pcie_probe(struct platfo
|
||
|
pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
|
||
|
pcie->l1ss = of_property_read_bool(np, "brcm,enable-l1ss");
|
||
|
pcie->rcb_mps_mode = of_property_read_bool(np, "brcm,enable-mps-rcb");
|
||
|
+ of_property_read_u32(np, "brcm,tperst-clk-ms", &pcie->tperst_clk_ms);
|
||
|
|
||
|
ret = clk_prepare_enable(pcie->clk);
|
||
|
if (ret) {
|