[LEDE-DEV] [PATCH v2] imx6: fix pcie scanning on boot
Tim Harvey
tharvey at gateworks.com
Fri Jan 19 15:18:44 PST 2018
On Thu, Jan 4, 2018 at 8:23 AM, Koen Vandeputte
<koen.vandeputte at ncentric.com> wrote:
> By default, when the imx6 PCIe RC boots up, the subordinate is set
> equally to the secondary bus (1), and does not alter afterwards.
>
> This means that theoretically, the highest bus reachable downstream is
> bus 1.
>
> Before upstream commit a20c7f36bd3d ("PCI: Do not allocate more buses
> than available in parent"), the driver ignored the subord value and just
> allowed up to 0xff on each device downstream.
>
> This caused a lot of errors to be printed, as this is not logical
> according to spec. (but it worked ..)
>
> After this commit, the driver stopped scanning deeper when the last
> allocated busnr equals the subordinate of it's master, causing devices
> to be undiscovered (especially behind bridges), uncovering the impact of
> this bug.
>
> Before:
>
> 00:00.0 PCI bridge: Synopsys, Inc. Device abcd (rev 01) (prog-if 00 ...
> Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
>
> 00:00.0 0604: 16c3:abcd (rev 01)
> 01:00.0 0604: 10b5:8604 (rev ba)
> ... stops after bus 1 ...
>
> After:
>
> 00:00.0 PCI bridge: Synopsys, Inc. Device abcd (rev 01) (prog-if 00
> ...
> Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
>
> 00:00.0 0604: 16c3:abcd (rev 01)
> 01:00.0 0604: 10b5:8604 (rev ba)
> 02:01.0 0604: 10b5:8604 (rev ba)
> 02:04.0 0604: 10b5:8604 (rev ba)
> 02:05.0 0604: 10b5:8604 (rev ba)
> 03:00.0 0280: 168c:0033 (rev 01)
> 05:00.0 0280: 168c:0033 (rev 01)
>
> This upstream commit was introduced in kernel 4.9.71
>
> Signed-off-by: Koen Vandeputte <koen.vandeputte at ncentric.com>
> ---
>
> V2:
>
> Proper fix for the real rootcause
> kernel 4.4 is not affected
>
>
> .../patches-4.9/230-fix-pcie-enumeration.patch | 73 ++++++++++++++++++++++
> 1 file changed, 73 insertions(+)
> create mode 100644 target/linux/imx6/patches-4.9/230-fix-pcie-enumeration.patch
>
> diff --git a/target/linux/imx6/patches-4.9/230-fix-pcie-enumeration.patch b/target/linux/imx6/patches-4.9/230-fix-pcie-enumeration.patch
> new file mode 100644
> index 000000000000..18f22347172b
> --- /dev/null
> +++ b/target/linux/imx6/patches-4.9/230-fix-pcie-enumeration.patch
> @@ -0,0 +1,73 @@
> +By default, when the imx6 PCIe RC boots up, the subordinate is set
> +equally to the secondary bus (1), and does not alter afterwards.
> +
> +This means that theoretically, the highest bus reachable downstream is
> +bus 1.
> +
> +Before commit a20c7f36bd3d ("PCI: Do not allocate more buses than
> +available in parent"), the driver ignored the subord value and just
> +allowed up to 0xff on each device downstream.
> +
> +This caused a lot of errors to be printed, as this is not logical
> +according to spec. (but it worked ..)
> +
> +After this commit, the driver stopped scanning deeper when the last
> +allocated busnr equals the subordinate of it's master, causing devices
> +to be undiscovered (especially behind bridges), uncovering the impact of
> +this bug.
> +
> +Before:
> +
> +00:00.0 PCI bridge: Synopsys, Inc. Device abcd (rev 01) (prog-if 00 ...
> + Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
> +
> +00:00.0 0604: 16c3:abcd (rev 01)
> +01:00.0 0604: 10b5:8604 (rev ba)
> +... stops after bus 1 ...
> +
> +After:
> +
> +00:00.0 PCI bridge: Synopsys, Inc. Device abcd (rev 01) (prog-if 00
> +...
> + Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
> +
> +00:00.0 0604: 16c3:abcd (rev 01)
> +01:00.0 0604: 10b5:8604 (rev ba)
> +02:01.0 0604: 10b5:8604 (rev ba)
> +02:04.0 0604: 10b5:8604 (rev ba)
> +02:05.0 0604: 10b5:8604 (rev ba)
> +03:00.0 0280: 168c:0033 (rev 01)
> +05:00.0 0280: 168c:0033 (rev 01)
> +
> +Signed-off-by: Koen Vandeputte <koen.vandeputte at ncentric.com>
> +
> +--- a/drivers/pci/host/pci-imx6.c
> ++++ b/drivers/pci/host/pci-imx6.c
> +@@ -64,6 +64,9 @@ struct imx6_pcie {
> +
> + #define PCIE_RC_LCSR 0x80
> +
> ++#define PCIE_RC_BNR 0x18
> ++#define PCIE_RC_BNR_MAX_SUBORDINATE (0xff << 16)
> ++
> + /* PCIe Port Logic registers (memory-mapped) */
> + #define PL_OFFSET 0x700
> + #define PCIE_PL_PFLR (PL_OFFSET + 0x08)
> +@@ -488,6 +491,17 @@ static int imx6_pcie_establish_link(stru
> + int ret;
> +
> + /*
> ++ * By default, the subordinate is set equally to the secondary
> ++ * bus (0x01) when the RC boots.
> ++ * This means that theoretically, only bus 1 is reachable from the RC.
> ++ * Force the PCIe RC subordinate to 0xff, otherwise no downstream
> ++ * devices will be detected behind bus 1.
> ++ */
> ++ tmp = dw_pcie_readl_rc(pp, PCIE_RC_BNR);
> ++ tmp |= PCIE_RC_BNR_MAX_SUBORDINATE;
> ++ dw_pcie_writel_rc(pp, PCIE_RC_BNR, tmp);
> ++
> ++ /*
> + * Force Gen1 operation when starting the link. In case the link is
> + * started in Gen2 mode, there is a possibility the devices on the
> + * bus will not be detected at all. This happens with PCIe switches.
> --
> 2.7.4
>
Hi Koen,
Thanks for this info!
Have you asked the linux-pci group about this? I'm curious what the
patch to 4.9.71 was trying to do and if this is the proper place to
fix this. I assume if we set that value in the bootloader it would get
reset when the kernel does a PCI reset.
It seems like every couple of months there is some upstream breakage
dealing with the i.MX6 and a PCIe switch :(
Regards,
Tim
More information about the Lede-dev
mailing list