From 16d917b130d782b94fa02afc7bdf0d4aae689da4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 8 Nov 2016 14:25:24 -0600 Subject: PCI: Don't attempt to claim shadow copies of ROM If we're using a shadow copy of a PCI device ROM, the shadow copy is in RAM and the device never sees accesses to it and doesn't respond to it. We don't have to route the shadow range to the PCI device, and the device doesn't have to claim the range. Previously we treated the shadow copy as though it were the ROM BAR, and we failed to claim it because the region wasn't routed to the device: pci 0000:01:00.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff] pci_bus 0000:01: Allocating resources pci 0000:01:00.0: can't claim BAR 6 [mem 0x000c0000-0x000dffff]: no compatible bridge window The failure path of pcibios_allocate_dev_rom_resource() cleared out the resource start address, which also caused the following ioremap() warning: WARNING: CPU: 0 PID: 116 at /build/linux-akdJXO/linux-4.8.0/arch/x86/mm/ioremap.c:121 __ioremap_caller+0x1ec/0x370 ioremap on RAM at 0x0000000000000000 - 0x000000000001ffff Handle an option ROM shadow copy as RAM, without trying to insert it into the iomem resource tree. This fixes a regression caused by 0c0e0736acad ("PCI: Set ROM shadow location in arch code, not in PCI core"), which appeared in v4.6. The regression causes video device initialization to fail. This was reported on AMD Turks, but it likely affects others as well. Fixes: 0c0e0736acad ("PCI: Set ROM shadow location in arch code, not in PCI core") Reported-and-tested-by: Vecu Bosseur Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1627496 Link: https://bugzilla.kernel.org/show_bug.cgi?id=175391 Link: https://bugzilla.redhat.com/show_bug.cgi?id=1352272 Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v4.6+ diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 66c4d8f..9526e34 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -121,6 +121,14 @@ int pci_claim_resource(struct pci_dev *dev, int resource) return -EINVAL; } + /* + * If we have a shadow copy in RAM, the PCI device doesn't respond + * to the shadow range, so we don't need to claim it, and upstream + * bridges don't need to route the range to the device. + */ + if (res->flags & IORESOURCE_ROM_SHADOW) + return 0; + root = pci_find_parent_resource(dev, res); if (!root) { dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", -- cgit v0.10.2 From 31a3a7b5b26f75fbe82de10ca99f2b673f6c26b4 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 10 Nov 2016 11:14:37 -0600 Subject: PCI: rockchip: Add three new resets as required properties pm_rst, aclk_rst, pclk_rst was controlled by ROM code so the software wasn't needed to control it again in theory. But it didn't work properly, so we do need to do it again and add enough delay between the assert of pm_rst and the deassert of pm_rst. The Soc intergrated with this controller, rk3399, is still under MP test internally, so the backward compatibility won't be a big deal. Signed-off-by: Shawn Lin Signed-off-by: Bjorn Helgaas Reviewed-by: Heiko Stuebner Acked-by: Rob Herring diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index ba67b39..71aeda1 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt @@ -26,13 +26,16 @@ Required properties: - "sys" - "legacy" - "client" -- resets: Must contain five entries for each entry in reset-names. +- resets: Must contain seven entries for each entry in reset-names. See ../reset/reset.txt for details. - reset-names: Must include the following names - "core" - "mgmt" - "mgmt-sticky" - "pipe" + - "pm" + - "aclk" + - "pclk" - pinctrl-names : The pin control state names - pinctrl-0: The "default" pinctrl state - #interrupt-cells: specifies the number of cells needed to encode an @@ -86,8 +89,10 @@ pcie0: pcie@f8000000 { reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; reg-names = "axi-base", "apb-base"; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, - <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; - reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; + <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> , + <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; + reset-names = "core", "mgmt", "mgmt-sticky", "pipe", + "pm", "pclk", "aclk"; phys = <&pcie_phy>; phy-names = "pcie-phy"; pinctrl-names = "default"; diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index e0b22da..e04f69b 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c @@ -190,6 +190,9 @@ struct rockchip_pcie { struct reset_control *mgmt_rst; struct reset_control *mgmt_sticky_rst; struct reset_control *pipe_rst; + struct reset_control *pm_rst; + struct reset_control *aclk_rst; + struct reset_control *pclk_rst; struct clk *aclk_pcie; struct clk *aclk_perf_pcie; struct clk *hclk_pcie; @@ -408,6 +411,44 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) gpiod_set_value(rockchip->ep_gpio, 0); + err = reset_control_assert(rockchip->aclk_rst); + if (err) { + dev_err(dev, "assert aclk_rst err %d\n", err); + return err; + } + + err = reset_control_assert(rockchip->pclk_rst); + if (err) { + dev_err(dev, "assert pclk_rst err %d\n", err); + return err; + } + + err = reset_control_assert(rockchip->pm_rst); + if (err) { + dev_err(dev, "assert pm_rst err %d\n", err); + return err; + } + + udelay(10); + + err = reset_control_deassert(rockchip->pm_rst); + if (err) { + dev_err(dev, "deassert pm_rst err %d\n", err); + return err; + } + + err = reset_control_deassert(rockchip->aclk_rst); + if (err) { + dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); + return err; + } + + err = reset_control_deassert(rockchip->pclk_rst); + if (err) { + dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); + return err; + } + err = phy_init(rockchip->phy); if (err < 0) { dev_err(dev, "fail to init phy, err %d\n", err); @@ -781,6 +822,27 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) return PTR_ERR(rockchip->pipe_rst); } + rockchip->pm_rst = devm_reset_control_get(dev, "pm"); + if (IS_ERR(rockchip->pm_rst)) { + if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) + dev_err(dev, "missing pm reset property in node\n"); + return PTR_ERR(rockchip->pm_rst); + } + + rockchip->pclk_rst = devm_reset_control_get(dev, "pclk"); + if (IS_ERR(rockchip->pclk_rst)) { + if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) + dev_err(dev, "missing pclk reset property in node\n"); + return PTR_ERR(rockchip->pclk_rst); + } + + rockchip->aclk_rst = devm_reset_control_get(dev, "aclk"); + if (IS_ERR(rockchip->aclk_rst)) { + if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) + dev_err(dev, "missing aclk reset property in node\n"); + return PTR_ERR(rockchip->aclk_rst); + } + rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); if (IS_ERR(rockchip->ep_gpio)) { dev_err(dev, "missing ep-gpios property in node\n"); -- cgit v0.10.2 From 4d3222f7071c01104b43300f1c10b55723df8f68 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 10 Nov 2016 11:14:46 -0600 Subject: arm64: dts: rockchip: add three new resets for rk3399 PCIe controller pm_rst, aclk_rst and pclk_rst should be controlled by driver, so we need to add these three resets for PCIe controller. Signed-off-by: Shawn Lin Signed-off-by: Bjorn Helgaas Acked-by: Heiko Stuebner diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index b65c193..7afbfb0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -300,8 +300,11 @@ ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000 0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, - <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; - reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; + <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>, + <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, + <&cru SRST_A_PCIE>; + reset-names = "core", "mgmt", "mgmt-sticky", "pipe", + "pm", "pclk", "aclk"; status = "disabled"; pcie0_intc: interrupt-controller { -- cgit v0.10.2 From bc79c9851a76d76f269d9ef5150e180825650b67 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 10 Nov 2016 16:10:44 -0500 Subject: PCI: VMD: Update filename to reflect move Updating MAINTAINERS to reflect the new location of the VMD driver. Signed-off-by: Keith Busch Signed-off-by: Bjorn Helgaas diff --git a/MAINTAINERS b/MAINTAINERS index 906e969..aefa6bf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9318,7 +9318,7 @@ PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) M: Keith Busch L: linux-pci@vger.kernel.org S: Supported -F: arch/x86/pci/vmd.c +F: drivers/pci/host/vmd.c PCIE DRIVER FOR ST SPEAR13XX M: Pratyush Anand -- cgit v0.10.2