Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

PR 60404: Beaglebone Black: nonfunctional usb wifi



The attached patch (see below) fixes the non-functional USB controller on the Beaglebone Black.  With this patch, mass storage devices seem to work fine, and wifi devices are detected by both the run and urtwn drivers.

At the moment, this patch is really verbose, because I am reporting various bits along the way.  Thus, there are obvious cleanups to be made.

More importantly, however, I would very much appreciate feedback on how to improve the functional code parts.  For example, it seems that it should be possible to access some of the relevant contants from the device tree, but I am not seeing how that can be done.  The BBB memory map separates control registers from the main device registers, so the same mapped memory cannot be used for both, and the device tree seems not to have a way to extract the base address of the control module.  I may, however, be not understanding or there may be other ways to access these registers or to differentiate between the instances of the driver attachments.  All code improvements welcome.

Thank you very much for any feedback you can offer.

Cheers,
Brook

P.S. While mass storage devices seem to work fine with this patch, none of the wifi adapters do.  They still exhibit the problems reported in PR 60404 [1].

[1] https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=60404


Index: ti_motg.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/ti/ti_motg.c,v
retrieving revision 1.5
diff -u -r1.5 ti_motg.c
--- ti_motg.c	2 Feb 2024 22:14:04 -0000	1.5
+++ ti_motg.c	10 Jul 2026 02:36:15 -0000
@@ -165,6 +165,79 @@
 
 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
+/*
+ * XXX - some of these constants should be read from the device tree
+ */
+
+/*
+ * control module
+ *
+ * see Spruh TRM Table 2-2. L4_WKUP Peripheral Memory Map, page 180 and
+ *     sys/external/gpl2/dts/dist/arch/arm/boot/dts/am33xx-l4.dtsi, line 281
+ *     segment@200000:target-module@10000
+ */
+#define CTRL_MODULE_BASE		0x44e10000
+
+/* see sys/external/gpl2/dts/dist/arch/arm/boot/dts/am33xx-l4.dtsi, line 327: usb_ctrl_mod:control@620 */
+#define USB_CTRL_MOD_PHY_CTRL_BASE	0x620
+#define USB_CTRL_MOD_PHY_CTRL_SIZE	0x10 
+
+/*
+ * control register bits
+ * see Spruh TRM section 9.3.1.20, pages 1483-1484 and section 9.3.1.22, pages 1486-1487
+ */
+#define USBPHY_CM_PWRDN			(1 << 0)
+#define USBPHY_OTG_PWRDN		(1 << 1)
+#define USBPHY_OTG_VDET_EN		(1 << 19)
+#define USBPHY_OTG_SESSENDEN		(1 << 20)
+
+/*
+ * names based on USB control registers
+ * see Spruh TRM Table 2-1, page 178
+ */
+#define USB0_BASE			"usb@47401000"
+#define USB1_BASE			"usb@47401800"
+
+	int usb_index = strcmp(faa->faa_name, USB0_BASE) == 0 ? 0
+	  : strcmp(faa->faa_name, USB1_BASE) == 0 ? 1
+	  : -1;
+	if (usb_index < 0) {
+		return;
+	}
+
+	aprint_normal("\n");
+	aprint_normal("===> ti_motg::attach(): %s (usb%d)\n", faa->faa_name, usb_index);
+
+	bus_space_handle_t handle;
+	bus_addr_t ctrl_base_addr = CTRL_MODULE_BASE + USB_CTRL_MOD_PHY_CTRL_BASE;	/* control registers base address */
+	bus_size_t ctrl_size = USB_CTRL_MOD_PHY_CTRL_SIZE;				/* control registers size */
+	bus_size_t ctrl_offset = ctrl_base_addr + usb_index * 2 * sizeof(uint32_t);	/* control register offset */
+
+	if (bus_space_map(faa->faa_bst, ctrl_base_addr, ctrl_size, 0, &handle) != 0) {
+		aprint_error(": couldn't map USB control registers\n");
+		return;
+	}
+
+	uint32_t usb_ctrl = bus_space_read_4(faa->faa_bst, handle, ctrl_offset - ctrl_base_addr);
+	aprint_normal("0x%08x: usb_ctrl%d: 0x%08x (upper 8 bits=0x3c)\n", (uint32_t)ctrl_offset, usb_index, usb_ctrl);
+	aprint_normal("    0: %x (0?)\n", (usb_ctrl & USBPHY_CM_PWRDN) != 0);
+	aprint_normal("    1: %x (0?)\n", (usb_ctrl & USBPHY_OTG_PWRDN) != 0);
+	aprint_normal("   19: %x (1?)\n", (usb_ctrl & USBPHY_OTG_VDET_EN) != 0);
+	aprint_normal("   20: %x (1?)\n", (usb_ctrl & USBPHY_OTG_SESSENDEN) != 0);
+
+	aprint_normal("===> ti_motg::attach(): writing usb_ctrl%d\n", usb_index);
+	usb_ctrl &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
+	usb_ctrl |= (USBPHY_OTG_VDET_EN | USBPHY_OTG_SESSENDEN);
+	bus_space_write_4(faa->faa_bst, handle, ctrl_offset - ctrl_base_addr, usb_ctrl);
+
+	usb_ctrl = bus_space_read_4(faa->faa_bst, handle, ctrl_offset - ctrl_base_addr);
+	aprint_normal("0x%08x: usb_ctrl%d: 0x%08x (upper 8 bits=0x3c)\n", (uint32_t)ctrl_offset, usb_index, usb_ctrl);
+	aprint_normal("    0: %x (0?)\n", (usb_ctrl & USBPHY_CM_PWRDN) != 0);
+	aprint_normal("    1: %x (0?)\n", (usb_ctrl & USBPHY_OTG_PWRDN) != 0);
+	aprint_normal("   19: %x (1?)\n", (usb_ctrl & USBPHY_OTG_VDET_EN) != 0);
+	aprint_normal("   20: %x (1?)\n", (usb_ctrl & USBPHY_OTG_SESSENDEN) != 0);
+	aprint_normal("\n");
+
 	sc->sc_motg.sc_iot = faa->faa_bst;
 	if (bus_space_map(sc->sc_motg.sc_iot, addr[0], size[0], 0,
 	    &sc->sc_motg.sc_ioh) != 0) {



Home | Main Index | Thread Index | Old Index