Tue Jul 27 19:23:43 2021 UTC ()
u-boot-rockpro64: fix broken PCI config space handling:

- Program bus number into the ECAM decoder for each access
- Use type 1 PCI config cycles for config spaces behind bridge
- Add a platform specific hack to the synchronous exception handler
  to deal with PCI-e subsystem triggering data aborts when probing
  nonexistent PCI devices.
- properly delay after deasserting reset for downstream devices to
  have time to initialize.

Allows booting from PCI devices behind bridges and probing
devices other than 0:0:0 and 1:0:0.


(tnn)
diff -r1.1 -r1.2 pkgsrc/sysutils/u-boot/distinfo-2021.07
diff -r1.13 -r1.14 pkgsrc/sysutils/u-boot-rockpro64/Makefile
diff -r0 -r1.1 pkgsrc/sysutils/u-boot/patches-2021.07/patch-arch_arm_lib_interrupts__64.c
diff -r0 -r1.1 pkgsrc/sysutils/u-boot/patches-2021.07/patch-drivers_pci_pcie__rockchip.c

cvs diff -r1.1 -r1.2 pkgsrc/sysutils/u-boot/distinfo-2021.07 (expand / switch to unified diff)

--- pkgsrc/sysutils/u-boot/distinfo-2021.07 2021/07/26 06:36:41 1.1
+++ pkgsrc/sysutils/u-boot/distinfo-2021.07 2021/07/27 19:23:43 1.2
@@ -1,14 +1,16 @@ @@ -1,14 +1,16 @@
1$NetBSD: distinfo-2021.07,v 1.1 2021/07/26 06:36:41 mrg Exp $ 1$NetBSD: distinfo-2021.07,v 1.2 2021/07/27 19:23:43 tnn Exp $
2 2
3SHA1 (u-boot-2021.07.tar.bz2) = fc997c4efbb93df340c41e0c7b8a4137ab8b6ee3 3SHA1 (u-boot-2021.07.tar.bz2) = fc997c4efbb93df340c41e0c7b8a4137ab8b6ee3
4RMD160 (u-boot-2021.07.tar.bz2) = cffcaf0b1600b76da8176c2f7495ee8a15c86c6e 4RMD160 (u-boot-2021.07.tar.bz2) = cffcaf0b1600b76da8176c2f7495ee8a15c86c6e
5SHA512 (u-boot-2021.07.tar.bz2) = 210b206a4626feb0985580d9448a97b499b09bf9b9313ca847a66624785e9e9b0fae8f2e329acd344f5f75cb722d2093dd0ee394311ddd1fde05e400ee71a24d 5SHA512 (u-boot-2021.07.tar.bz2) = 210b206a4626feb0985580d9448a97b499b09bf9b9313ca847a66624785e9e9b0fae8f2e329acd344f5f75cb722d2093dd0ee394311ddd1fde05e400ee71a24d
6Size (u-boot-2021.07.tar.bz2) = 17275746 bytes 6Size (u-boot-2021.07.tar.bz2) = 17275746 bytes
 7SHA1 (patch-arch_arm_lib_interrupts__64.c) = 708be481a01b84c6c69d88465adf898b659dbeab
7SHA1 (patch-arch_arm_mach-rockchip_rk3399_rk3399.c) = caa4068c635eaef5997501e154ec5cb11dcbf490 8SHA1 (patch-arch_arm_mach-rockchip_rk3399_rk3399.c) = caa4068c635eaef5997501e154ec5cb11dcbf490
8SHA1 (patch-board_pine64_pinebook-pro-rk3399_pinebook-pro-rk3399.c) = 49954716240e93b33e13288f92b14f527ba15bdf 9SHA1 (patch-board_pine64_pinebook-pro-rk3399_pinebook-pro-rk3399.c) = 49954716240e93b33e13288f92b14f527ba15bdf
9SHA1 (patch-configs_pinebook-pro-rk3399_defconfig) = 6f9ddd87ef1486fa0785b2f00c6819ace1436853 10SHA1 (patch-configs_pinebook-pro-rk3399_defconfig) = 6f9ddd87ef1486fa0785b2f00c6819ace1436853
10SHA1 (patch-configs_rock64-rk3328_defconfig) = 59076a9934c1ec0a492d600b3179209769753fd1 11SHA1 (patch-configs_rock64-rk3328_defconfig) = 59076a9934c1ec0a492d600b3179209769753fd1
11SHA1 (patch-configs_rockpro64-rk3399_defconfig) = 4d355140bc2b70667827fde7165ce2541612572c 12SHA1 (patch-configs_rockpro64-rk3399_defconfig) = 4d355140bc2b70667827fde7165ce2541612572c
 13SHA1 (patch-drivers_pci_pcie__rockchip.c) = 1a6da6cfced2485c1f2147eccc8a1678a1bf26bb
12SHA1 (patch-drivers_usb_host_usb-uclass.c) = 0e90ccfbc908d0bd1d35eff31c2d1a2ed52e9dd0 14SHA1 (patch-drivers_usb_host_usb-uclass.c) = 0e90ccfbc908d0bd1d35eff31c2d1a2ed52e9dd0
13SHA1 (patch-include_configs_rockchip-common.h) = 8d2fcde173fd6f5c2b27c8fe6eb9994b2b40e099 15SHA1 (patch-include_configs_rockchip-common.h) = 8d2fcde173fd6f5c2b27c8fe6eb9994b2b40e099
14SHA1 (patch-include_configs_rockpro64_rk3399.h) = 7efd0b09cbf627dc59d2a23a76dd6506c9efc4c9 16SHA1 (patch-include_configs_rockpro64_rk3399.h) = 7efd0b09cbf627dc59d2a23a76dd6506c9efc4c9

cvs diff -r1.13 -r1.14 pkgsrc/sysutils/u-boot-rockpro64/Makefile (expand / switch to unified diff)

--- pkgsrc/sysutils/u-boot-rockpro64/Makefile 2021/07/26 06:36:41 1.13
+++ pkgsrc/sysutils/u-boot-rockpro64/Makefile 2021/07/27 19:23:43 1.14
@@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
1# $NetBSD: Makefile,v 1.13 2021/07/26 06:36:41 mrg Exp $ 1# $NetBSD: Makefile,v 1.14 2021/07/27 19:23:43 tnn Exp $
2 2
3UBOOT_TARGET= rockpro64 3UBOOT_TARGET= rockpro64
4UBOOT_CONFIG= rockpro64-rk3399_defconfig 4UBOOT_CONFIG= rockpro64-rk3399_defconfig
5UBOOT_BIN= idbloader.img rksd_loader.img rkspi_loader.img u-boot.itb 5UBOOT_BIN= idbloader.img rksd_loader.img rkspi_loader.img u-boot.itb
6UBOOT_IMAGE_TYPE= rk3399 6UBOOT_IMAGE_TYPE= rk3399
7UBOOT_VERSION?= 2021.07 7UBOOT_VERSION?= 2021.07
 8PKGREVISION= 1
8 9
9UBOOT_INSTALLBOOT_PLIST= installboot.plist 10UBOOT_INSTALLBOOT_PLIST= installboot.plist
10 11
11.include "../../sysutils/u-boot/u-boot-rockchip.mk" 12.include "../../sysutils/u-boot/u-boot-rockchip.mk"

File Added: pkgsrc/sysutils/u-boot/patches-2021.07/patch-arch_arm_lib_interrupts__64.c
$NetBSD: patch-arch_arm_lib_interrupts__64.c,v 1.1 2021/07/27 19:23:43 tnn Exp $

u-boot-rockpro64: fix broken PCI config space handling:

- Program bus number into the ECAM decoder for each access
- Use type 1 PCI config cycles for config spaces behind bridge
- Add a platform specific hack to the synchronous exception handler
  to deal with PCI-e subsystem triggering data aborts when probing
  nonexistent PCI devices.
- properly delay after deasserting reset for downstream devices to
  have time to initialize.

Allows booting from PCI devices behind bridges and probing
devices other than 0:0:0 and 1:0:0.

--- arch/arm/lib/interrupts_64.c.orig	2021-07-05 15:11:28.000000000 +0000
+++ arch/arm/lib/interrupts_64.c
@@ -111,11 +111,26 @@ void do_bad_error(struct pt_regs *pt_reg
 	panic("Resetting CPU ...\n");
 }
 
+#ifdef CONFIG_ROCKCHIP_RK3399
+extern volatile int rockchip_pcie_expect_data_abort;
+extern volatile int rockchip_pcie_got_data_abort;
+#endif
 /*
  * do_sync handles the Synchronous Abort exception.
  */
 void do_sync(struct pt_regs *pt_regs, unsigned int esr)
 {
+#ifdef CONFIG_ROCKCHIP_RK3399
+	if ((esr >> 26) == 0x25 && rockchip_pcie_expect_data_abort) {
+		/*
+		 * Data Abort taken without a change in Exception level.
+		 * This happens when probing nonexistent PCI-e devices.
+		 */
+		rockchip_pcie_got_data_abort = 1;
+		pt_regs->elr += 4; /* skip faulting insn */
+		return;
+	}
+#endif
 	efi_restore_gd();
 	printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr);
 	show_regs(pt_regs);

File Added: pkgsrc/sysutils/u-boot/patches-2021.07/patch-drivers_pci_pcie__rockchip.c
$NetBSD: patch-drivers_pci_pcie__rockchip.c,v 1.1 2021/07/27 19:23:43 tnn Exp $

u-boot-rockpro64: fix broken PCI config space handling

- Program bus number into the ECAM decoder for each access
- Use type 1 PCI config cycles for config spaces behind bridge
- Add a platform specific hack to the synchronous exception handler
  to deal with PCI-e subsystem triggering data aborts when probing
  nonexistent PCI devices.

Allows booting from PCI devices behind bridges and probing
devices other than 0:0:0 and 0:1:0.

--- drivers/pci/pcie_rockchip.c.orig	2021-07-05 15:11:28.000000000 +0000
+++ drivers/pci/pcie_rockchip.c
@@ -73,6 +73,8 @@ DECLARE_GLOBAL_DATA_PTR;
 #define PCIE_ATR_OB_REGION0_SIZE	(32 * 1024 * 1024)
 #define PCIE_ATR_OB_REGION_SIZE		(1 * 1024 * 1024)
 
+#define PCIE_ATR_REGION0_PASS_BITS (20 - 1)
+
 struct rockchip_pcie {
 	fdt_addr_t axi_base;
 	fdt_addr_t apb_base;
@@ -103,13 +105,15 @@ struct rockchip_pcie {
 
 static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset)
 {
-	unsigned int bus = PCI_BUS(bdf);
 	unsigned int dev = PCI_DEV(bdf);
 	unsigned int func = PCI_FUNC(bdf);
 
-	return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3);
+	return (dev << 15) | (func << 12) | (offset & ~0x3);
 }
 
+volatile int rockchip_pcie_expect_data_abort;
+volatile int rockchip_pcie_got_data_abort;
+
 static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
 				 uint offset, ulong *valuep,
 				 enum pci_size_t size)
@@ -127,8 +131,33 @@ static int rockchip_pcie_rd_conf(const s
 	}
 
 	if ((bus == priv->first_busno + 1) && dev == 0) {
+		writel((bus << 20) | PCIE_ATR_REGION0_PASS_BITS,
+		       priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+		writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
+		       priv->apb_base + PCIE_ATR_OB_DESC0(0));
+		dsb();
 		value = readl(priv->axi_base + where);
 		*valuep = pci_conv_32_to_size(value, offset, size);
+		dsb();
+		return 0;
+	}
+
+	if (bus > priv->first_busno + 1) {
+		writel((bus << 20) | PCIE_ATR_REGION0_PASS_BITS,
+		       priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+		writel(PCIE_ATR_HDR_CFG_TYPE1 | PCIE_ATR_HDR_RID,
+		       priv->apb_base + PCIE_ATR_OB_DESC0(0));
+		dsb();
+		rockchip_pcie_got_data_abort = 0;
+		rockchip_pcie_expect_data_abort = 1;
+		value = readl(priv->axi_base + where);
+		rockchip_pcie_expect_data_abort = 0;
+		if (rockchip_pcie_got_data_abort) {
+			*valuep = pci_get_ff(size);
+			return 0;
+		}
+		*valuep = pci_conv_32_to_size(value, offset, size);
+		dsb();
 		return 0;
 	}
 
@@ -155,9 +184,28 @@ static int rockchip_pcie_wr_conf(struct 
 	}
 
 	if ((bus == priv->first_busno + 1) && dev == 0) {
+		writel((bus << 20) | PCIE_ATR_REGION0_PASS_BITS,
+		       priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+		writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
+		       priv->apb_base + PCIE_ATR_OB_DESC0(0));
+		dsb();
 		old = readl(priv->axi_base + where);
 		value = pci_conv_size_to_32(old, value, offset, size);
 		writel(value, priv->axi_base + where);
+		dsb();
+		return 0;
+	}
+
+	if (bus > priv->first_busno + 1) {
+		writel((bus << 20) | PCIE_ATR_REGION0_PASS_BITS,
+		       priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+		writel(PCIE_ATR_HDR_CFG_TYPE1 | PCIE_ATR_HDR_RID,
+		       priv->apb_base + PCIE_ATR_OB_DESC0(0));
+		dsb();
+		old = readl(priv->axi_base + where);
+		value = pci_conv_size_to_32(old, value, offset, size);
+		writel(value, priv->axi_base + where);
+		dsb();
 		return 0;
 	}
 
@@ -173,7 +221,7 @@ static int rockchip_pcie_atr_init(struct
 	int i, region;
 
 	/* Use region 0 to map PCI configuration space. */
-	writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
+	writel(PCIE_ATR_REGION0_PASS_BITS, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
 	writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0));
 	writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
 	       priv->apb_base + PCIE_ATR_OB_DESC0(0));
@@ -343,6 +391,8 @@ static int rockchip_pcie_init_port(struc
 		goto err_power_off_phy;
 	}
 
+	mdelay(20);	/* 20 ms according to PCI-e BS "Conventional Reset" */
+
 	/* Enable Gen1 training */
 	writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
 	       priv->apb_base + PCIE_CLIENT_CONFIG);
@@ -378,6 +428,8 @@ static int rockchip_pcie_init_port(struc
 		goto err_power_off_phy;
 	}
 
+	mdelay(80);   /* wait 100 ms before CSR accesses. Already waited 20. */
+
 	return 0;
 
 err_power_off_phy: