From 22e21e51ce755399fd42055a3f668ee4af370881 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Thu, 7 May 2020 19:20:20 +0200 Subject: PCI: brcmstb: Assert fundamental reset on initialization While preparing the driver for upstream this detail was missed. If not asserted during the initialization process, devices connected on the bus will not be made aware of the internal reset happening. This, potentially resulting in unexpected behavior. Link: https://lore.kernel.org/r/20200507172020.18000-1-nsaenzjulienne@suse.de Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver") Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Lorenzo Pieralisi Acked-by: Florian Fainelli --- drivers/pci/controller/pcie-brcmstb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 6d79d14527a6..9aa4cdc7557e 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -697,6 +697,7 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) /* Reset the bridge */ brcm_pcie_bridge_sw_init_set(pcie, 1); + brcm_pcie_perst_set(pcie, 1); usleep_range(100, 200); -- cgit v1.2.3 From b382e4a0a18f4abfd4d53f32a03dd6bb60df758a Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 7 May 2020 16:15:40 -0400 Subject: PCI: brcmstb: Don't clk_put() a managed clock clk_put() was being invoked on a clock obtained by devm_clk_get_optional(). Link: https://lore.kernel.org/r/20200507201544.43432-2-james.quinlan@broadcom.com Signed-off-by: Jim Quinlan Signed-off-by: Lorenzo Pieralisi Acked-by: Florian Fainelli Acked-by: Nicolas Saenz Julienne --- drivers/pci/controller/pcie-brcmstb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 9aa4cdc7557e..e847528c072f 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -900,7 +900,6 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) brcm_msi_remove(pcie); brcm_pcie_turn_off(pcie); clk_disable_unprepare(pcie->clk); - clk_put(pcie->clk); } static int brcm_pcie_remove(struct platform_device *pdev) -- cgit v1.2.3 From 077a4fa92a615a4d0f86eae68d777b9dd5e5a95b Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 7 May 2020 16:15:41 -0400 Subject: PCI: brcmstb: Fix window register offset from 4 to 8 The outbound memory window registers were being referenced with an incorrect stride offset. This probably wasn't noticed previously as there was likely only one such window employed. Link: https://lore.kernel.org/r/20200507201544.43432-3-james.quinlan@broadcom.com Fixes: c0452137034b ("PCI: brcmstb: Add Broadcom STB PCIe host controller driver") Signed-off-by: Jim Quinlan Signed-off-by: Lorenzo Pieralisi Acked-by: Florian Fainelli Acked-by: Nicolas Saenz Julienne --- drivers/pci/controller/pcie-brcmstb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index e847528c072f..a4a70532a658 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -54,11 +54,11 @@ #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c #define PCIE_MEM_WIN0_LO(win) \ - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4) + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8) #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 #define PCIE_MEM_WIN0_HI(win) \ - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4) + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8) #define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c #define PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f -- cgit v1.2.3 From caab002d5069f8610a6ec1d2addeef21f4f96909 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 7 May 2020 16:15:43 -0400 Subject: PCI: brcmstb: Disable L0s component of ASPM if requested Some informal internal experiments has shown that the BrcmSTB ASPM L0s savings may introduce an undesirable noise signal on some customers' boards. In addition, L0s was found lacking in realized power savings, especially relative to the L1 ASPM component. This is BrcmSTB's experience and may not hold for others. At any rate, if the 'aspm-no-l0s' property is present L0s will be disabled. Link: https://lore.kernel.org/r/20200507201544.43432-5-james.quinlan@broadcom.com Signed-off-by: Jim Quinlan Signed-off-by: Lorenzo Pieralisi Acked-by: Florian Fainelli Acked-by: Nicolas Saenz Julienne --- drivers/pci/controller/pcie-brcmstb.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index a4a70532a658..752f5b331579 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -41,6 +41,9 @@ #define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c #define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff +#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc +#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 + #define PCIE_RC_DL_MDIO_ADDR 0x1100 #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 #define PCIE_RC_DL_MDIO_RD_DATA 0x1108 @@ -693,7 +696,7 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) int num_out_wins = 0; u16 nlw, cls, lnksta; int i, ret; - u32 tmp; + u32 tmp, aspm_support; /* Reset the bridge */ brcm_pcie_bridge_sw_init_set(pcie, 1); @@ -804,6 +807,15 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie) num_out_wins++; } + /* Don't advertise L0s capability if 'aspm-no-l0s' */ + aspm_support = PCIE_LINK_STATE_L1; + if (!of_property_read_bool(pcie->np, "aspm-no-l0s")) + aspm_support |= PCIE_LINK_STATE_L0S; + tmp = readl(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); + u32p_replace_bits(&tmp, aspm_support, + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK); + writel(tmp, base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); + /* * For config space accesses on the RC, show the right class for * a PCIe-PCIe bridge (the default setting is to be EP mode). -- cgit v1.2.3 From 44331189f9082c7e659697bbac1747db3def73e7 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Tue, 5 May 2020 18:13:16 +0200 Subject: PCI: brcmstb: Wait for Raspberry Pi's firmware when present xHCI's PCI fixup, run at the end of pcie-brcmstb's probe, depends on RPi4's VideoCore firmware interface to be up and running. It's possible for both initializations to race, so make sure it's available prior to starting. Link: https://lore.kernel.org/r/20200505161318.26200-4-nsaenzjulienne@suse.de Signed-off-by: Nicolas Saenz Julienne Signed-off-by: Lorenzo Pieralisi Reviewed-by: Florian Fainelli Reviewed-by: Rob Herring --- drivers/pci/controller/pcie-brcmstb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/pci') diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 752f5b331579..7730ea845ff2 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -28,6 +28,8 @@ #include #include +#include + #include "../pci.h" /* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ @@ -929,11 +931,26 @@ static int brcm_pcie_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node, *msi_np; struct pci_host_bridge *bridge; + struct device_node *fw_np; struct brcm_pcie *pcie; struct pci_bus *child; struct resource *res; int ret; + /* + * We have to wait for Raspberry Pi's firmware interface to be up as a + * PCI fixup, rpi_firmware_init_vl805(), depends on it. This driver's + * probe can race with the firmware interface's (see + * drivers/firmware/raspberrypi.c) and potentially break the PCI fixup. + */ + fw_np = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-firmware"); + if (fw_np && !rpi_firmware_get(fw_np)) { + of_node_put(fw_np); + return -EPROBE_DEFER; + } + of_node_put(fw_np); + bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); if (!bridge) return -ENOMEM; -- cgit v1.2.3