@@ -83,6 +84,7 @@ static void __iomem * __init xdbc_map_pci_mmio(u32 bus, u32 dev, u32 func)
write_pci_config_byte(bus, dev, func, PCI_COMMAND, byte);
}
+ sz64 = min(sz64, 64ULL * 1024);
xdbc.xhci_start = val64;
xdbc.xhci_length = sz64;
base = early_ioremap(val64, sz64);
---8<---
Then, it fails with:
waiting for connection timed out
xhci_dbc:early_xdbc_setup_hardware: failed to setup the connection to host
On the other hand, enabling it later via sysfs works:
[root@test-1 ~]# cat /sys/bus/pci/devices/0000\:04\:00.3/dbc
disabled
[root@test-1 ~]# echo enable > /sys/bus/pci/devices/0000\:04\:00.3/dbc
[root@test-1 ~]# cat /sys/bus/pci/devices/0000\:04\:00.3/dbc
configured
[root@test-1 ~]# dmesg|tail
[ 365.992308] usb usb3-port2: config error
[ 370.042302] usb usb3-port2: Cannot enable. Maybe the USB cable is bad?
[ 370.042333] usb usb3-port2: config error
[ 370.837429] usb usb3-port2: config error
[ 371.667309] usb usb3-port2: config error
[ 372.499309] usb usb3-port2: config error
[ 373.331309] usb usb3-port2: config error
[ 374.315309] usb usb3-port2: config error
[ 375.003453] xhci_hcd 0000:04:00.3: DbC connected
[ 375.459336] xhci_hcd 0000:04:00.3: DbC configured
The obvious difference is that later the full xhci driver is loaded and
the main controller is initialized. I've tried the simple thing: setting
Run/Stop bit to 1 with this hacky patch:
---8<---
@@ -420,6 +422,22 @@ static int xdbc_start(void)
u32 ctrl, status;
int ret;
+ if (xdbc.vendor == PCI_VENDOR_ID_AMD) {
+ u8 caplen = readb(xdbc.xhci_base);
+ u32 usbcmd = readl(xdbc.xhci_base + caplen);
+ xdbc_trace("USBCMD before: %#x\n", usbcmd);
+ xdbc_trace("USBSTS before: %#x\n", readl(xdbc.xhci_base + caplen + 4));
+ writel(usbcmd | 1, xdbc.xhci_base + caplen);
+ /* wait for HCH to clear */
+ ret = handshake(xdbc.xhci_base + caplen + 4, 1, 0, 100000, 100);
+ if (ret) {
+ xdbc_trace("failed to enable XHCI\n");
+ return ret;
+ }
+ xdbc_trace("USBCMD after: %#x\n", readl(xdbc.xhci_base + caplen));
+ xdbc_trace("USBSTS after: %#x\n", readl(xdbc.xhci_base + caplen + 4));
+ }
+
ctrl = readl(&xdbc.xdbc_reg->control);
writel(ctrl | CTRL_DBC_ENABLE | CTRL_PORT_ENABLE, &xdbc.xdbc_reg->control);
ret = handshake(&xdbc.xdbc_reg->control, CTRL_DBC_ENABLE, CTRL_DBC_ENABLE, 100000, 100);