1 From 4b0c6453808a662869a43c504913f3b7ed64486a Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Wed, 20 Sep 2023 13:01:11 +0100
4 Subject: [PATCH] drivers: pci: brcmstb: optionally extend Tperst_clk time
7 The RC has a feature that allows for manual control over the deassertion
8 of the PERST# output pin, which allows the time between refclk active
9 and reset deassert at the EP to be increased.
11 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
13 drivers/pci/controller/pcie-brcmstb.c | 24 +++++++++++++++++++++++-
14 1 file changed, 23 insertions(+), 1 deletion(-)
16 --- a/drivers/pci/controller/pcie-brcmstb.c
17 +++ b/drivers/pci/controller/pcie-brcmstb.c
20 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG pcie->reg_offsets[PCIE_HARD_DEBUG]
21 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
22 +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK 0x8
23 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
24 #define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
25 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_L1SS_ENABLE_MASK 0x00200000
26 @@ -352,6 +353,7 @@ struct brcm_pcie {
27 bool (*rc_mode)(struct brcm_pcie *pcie);
28 struct subdev_regulators *sr;
29 bool ep_wakeup_capable;
33 static inline bool is_bmips(const struct brcm_pcie *pcie)
34 @@ -1388,9 +1390,28 @@ static int brcm_pcie_start_link(struct b
36 bool ssc_good = false;
40 /* Unassert the fundamental reset */
41 - pcie->perst_set(pcie, 0);
42 + if (pcie->tperst_clk_ms) {
44 + * Increase Tperst_clk time by forcing PERST# output low while
45 + * the internal reset is released, so the PLL generates stable
46 + * refclk output further in advance of PERST# deassertion.
48 + tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
49 + u32p_replace_bits(&tmp, 1, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK);
50 + writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
52 + pcie->perst_set(pcie, 0);
53 + msleep(pcie->tperst_clk_ms);
55 + tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
56 + u32p_replace_bits(&tmp, 0, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK);
57 + writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
59 + pcie->perst_set(pcie, 0);
63 * Wait for 100ms after PERST# deassertion; see PCIe CEM specification
64 @@ -1923,6 +1944,7 @@ static int brcm_pcie_probe(struct platfo
65 pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
66 pcie->l1ss = of_property_read_bool(np, "brcm,enable-l1ss");
67 pcie->rcb_mps_mode = of_property_read_bool(np, "brcm,enable-mps-rcb");
68 + of_property_read_u32(np, "brcm,tperst-clk-ms", &pcie->tperst_clk_ms);
70 ret = clk_prepare_enable(pcie->clk);