PR 60404: Beaglebone Black: nonfunctional usb wifi
Brook Milligan <[email protected]> Thu, 9 Jul 2026 21:23:55 -0600
| Newsgroups | gmane.os.netbsd.current |
|---|---|
| Message-ID | <[email protected]> |
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=3D60404
Index: ti_motg.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 @@
=20
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
=20
+/*
+ * 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=20
+
+/*
+ * 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 =3D strcmp(faa->faa_name, USB0_BASE) =3D=3D 0 ? 0
+ : strcmp(faa->faa_name, USB1_BASE) =3D=3D 0 ? 1
+ : -1;
+ if (usb_index < 0) {
+ return;
+ }
+
+ aprint_normal("\n");
+ aprint_normal("=3D=3D=3D> ti_motg::attach(): %s (usb%d)\n", =
faa->faa_name, usb_index);
+
+ bus_space_handle_t handle;
+ bus_addr_t ctrl_base_addr =3D CTRL_MODULE_BASE + =
USB_CTRL_MOD_PHY_CTRL_BASE; /* control registers base address */
+ bus_size_t ctrl_size =3D USB_CTRL_MOD_PHY_CTRL_SIZE; =
/* control registers size */
+ bus_size_t ctrl_offset =3D 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) !=3D 0) {
+ aprint_error(": couldn't map USB control registers\n");
+ return;
+ }
+
+ uint32_t usb_ctrl =3D 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=3D0x3c)\n", (uint32_t)ctrl_offset, usb_index, usb_ctrl);
+ aprint_normal(" 0: %x (0?)\n", (usb_ctrl & USBPHY_CM_PWRDN) =
!=3D 0);
+ aprint_normal(" 1: %x (0?)\n", (usb_ctrl & USBPHY_OTG_PWRDN) =
!=3D 0);
+ aprint_normal(" 19: %x (1?)\n", (usb_ctrl & =
USBPHY_OTG_VDET_EN) !=3D 0);
+ aprint_normal(" 20: %x (1?)\n", (usb_ctrl & =
USBPHY_OTG_SESSENDEN) !=3D 0);
+
+ aprint_normal("=3D=3D=3D> ti_motg::attach(): writing =
usb_ctrl%d\n", usb_index);
+ usb_ctrl &=3D ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
+ usb_ctrl |=3D (USBPHY_OTG_VDET_EN | USBPHY_OTG_SESSENDEN);
+ bus_space_write_4(faa->faa_bst, handle, ctrl_offset - =
ctrl_base_addr, usb_ctrl);
+
+ usb_ctrl =3D 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=3D0x3c)\n", (uint32_t)ctrl_offset, usb_index, usb_ctrl);
+ aprint_normal(" 0: %x (0?)\n", (usb_ctrl & USBPHY_CM_PWRDN) =
!=3D 0);
+ aprint_normal(" 1: %x (0?)\n", (usb_ctrl & USBPHY_OTG_PWRDN) =
!=3D 0);
+ aprint_normal(" 19: %x (1?)\n", (usb_ctrl & =
USBPHY_OTG_VDET_EN) !=3D 0);
+ aprint_normal(" 20: %x (1?)\n", (usb_ctrl & =
USBPHY_OTG_SESSENDEN) !=3D 0);
+ aprint_normal("\n");
+
sc->sc_motg.sc_iot =3D faa->faa_bst;
if (bus_space_map(sc->sc_motg.sc_iot, addr[0], size[0], 0,
&sc->sc_motg.sc_ioh) !=3D 0) {