git: 9front

Download patch

ref: cef2fbc971173413b812f53ef9c03cf26ce8adc2
parent: 1c298f2d742bb17c5617d7623e23536622811799
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jul 2 17:04:01 EDT 2020

bcm64: fix usb xhci controller on pi4 8GB variant (thanks richard miller)

On the 8GB variant of the raspberry pi 4,
the eeprom chip for the xhci controller is missing and
instead loaded from sdram (by the gpu firmware).

for this, the gpu firmware needs to be notified of
the xhci controllers pci bus address (after reset)
that was assigned by our pci enumeration code.

--- a/sys/src/9/bcm/vcore.c
+++ b/sys/src/9/bcm/vcore.c
@@ -53,6 +53,7 @@
 	TagSetEgpioConf	= 0x00038043,
 
 	TagGettemp	= 0x00030006,
+	TagXhciReset	= 0x00030058,
 	TagFballoc	= 0x00040001,
 	TagFbfree	= 0x00048001,
 	TagFbblank	= 0x00040002,
@@ -412,4 +413,20 @@
 	buf[0] = 128 + port;
 	buf[1] = on;
 	vcreq(TagSetEgpioState, buf, sizeof(buf), sizeof(buf));
+}
+
+/*
+ * Notify gpu that xhci firmware might need loading. This is for some
+ * pi4 board versions which are missing the eeprom chip for the vl805,
+ * requiring its firmware to come from the boot eeprom instead.
+ */
+int
+xhcireset(int devaddr)
+{
+	u32int buf[1];
+
+	buf[0] = devaddr;
+	if(vcreq(TagXhciReset, buf, sizeof(buf), sizeof(buf[0])) == sizeof(buf[0]))
+		return buf[0];
+	return -1;
 }
--- a/sys/src/9/bcm64/archbcm4.c
+++ b/sys/src/9/bcm64/archbcm4.c
@@ -172,5 +172,18 @@
 void
 archbcm4link(void)
 {
+	Pcidev *p;
+
+	/*
+	 * The firmware resets PCI before starting the host OS because
+	 * without SDRAM the VL805 makes inbound requests to page-in firmware
+	 * from SDRAM. If the OS has a different PCI mapping that would all break.
+	 * There's no way to pause and move the mappings and it's not really desirable
+	 * for the firmware to dictate the PCI configuration. Consequently, the mailbox
+	 * is required so that the OS can reset the VLI after asserting PCI chip reset.
+	 */
+	if((p = pcimatch(nil, 0x1106, 0x3483)) != nil)
+		xhcireset(BUSBNO(p->tbdf)<<20 | BUSDNO(p->tbdf)<<15 | BUSFNO(p->tbdf)<<12);
+
 	// addclock0link(wdogfeed, HZ);
 }
--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -170,6 +170,7 @@
 extern void vgpinit(void);
 extern void vgpset(uint port, int on);
 extern void egpset(uint port, int on);
+extern int xhcireset(int devaddr);
 
 /* bootargs */
 extern void bootargsinit(uintptr);
--- a/sys/src/9/bcm64/pi4
+++ b/sys/src/9/bcm64/pi4
@@ -27,11 +27,11 @@
 link
 	gisb
 	pci
-	archbcm4
+	archbcm4	pci
+	usbxhci		pci archbcm4
 	ethergenet	ethermii
 	ethermedium
 	loopbackmedium
-	usbxhci		pci
 
 ip
 	tcp
--