diff mbox series

[3/3] arm: allwinner: Wire up USB EHCI

Message ID 20200214062109.24494-3-linux@roeck-us.net (mailing list archive)
State New, archived
Headers show
Series [1/3] hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file | expand

Commit Message

Guenter Roeck Feb. 14, 2020, 6:21 a.m. UTC
Initialize EHCI controllers on Allwinner A10. With this patch applied,
USB EHCI ports are discovered when booting the cubieboard machine with
a recent Linux kernel.

ehci-platform 1c14000.usb: EHCI Host Controller
ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1
ehci-platform 1c14000.usb: irq 26, io mem 0x01c14000
ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00
ehci-platform 1c1c000.usb: EHCI Host Controller
ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 hw/arm/allwinner-a10.c         | 17 +++++++++++++++++
 include/hw/arm/allwinner-a10.h |  2 ++
 2 files changed, 19 insertions(+)

Comments

Gerd Hoffmann Feb. 14, 2020, 10:08 a.m. UTC | #1
> ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
> ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
> ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00

> +        for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
> +            object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
> +                                     &err);

I suspect the ohci controllers are ehci companions, i.e. they handle a
single usb bus, with ehci handling usb2 and ohci handling usb1 devices?

If so then you should initialize ehci first, explicitly assign bus
names and set the masterbus property for the ohci controllers.

See also docs/usb2.txt

cheers,
  Gerd
Guenter Roeck Feb. 14, 2020, 2:26 p.m. UTC | #2
On 2/14/20 2:08 AM, Gerd Hoffmann wrote:
>> ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2
>> ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
>> ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
> 
>> +        for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
>> +            object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
>> +                                     &err);
> 
> I suspect the ohci controllers are ehci companions, i.e. they handle a
> single usb bus, with ehci handling usb2 and ohci handling usb1 devices?
> 
> If so then you should initialize ehci first, explicitly assign bus
> names and set the masterbus property for the ohci controllers.
> 
> See also docs/usb2.txt
> 

Thanks for the references. Makes sense; I'll give it a try.

Guenter
diff mbox series

Patch

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 818145428c..f8b963b5c3 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -32,6 +32,7 @@ 
 #define AW_A10_PIT_REG_BASE     0x01c20c00
 #define AW_A10_UART0_REG_BASE   0x01c28000
 #define AW_A10_EMAC_BASE        0x01c0b000
+#define AW_A10_EHCI_BASE        0x01c14000
 #define AW_A10_OHCI_BASE        0x01c14400
 #define AW_A10_SATA_BASE        0x01c18000
 
@@ -64,6 +65,10 @@  static void aw_a10_init(Object *obj)
             sysbus_init_child_obj(obj, "ohci[*]", OBJECT(&s->ohci[i]),
                                   sizeof(s->ohci[i]), TYPE_SYSBUS_OHCI);
         }
+        for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
+            sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
+                                  sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
+        }
     }
 }
 
@@ -162,6 +167,18 @@  static void aw_a10_realize(DeviceState *dev, Error **errp)
             sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
                                qdev_get_gpio_in(dev, 64 + i));
         }
+        for (i = 0; i < ARRAY_SIZE(s->ehci); i++) {
+            object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
+                                     &err);
+            if (err) {
+                error_propagate(errp, err);
+                return;
+            }
+            sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+                            AW_A10_EHCI_BASE + i * 0x8000);
+            sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+                               qdev_get_gpio_in(dev, 39 + i));
+        }
     }
 }
 
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index 4864adbec3..17e1ee92e2 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -10,6 +10,7 @@ 
 #include "hw/net/allwinner_emac.h"
 #include "hw/ide/ahci.h"
 #include "hw/usb/hcd-ohci.h"
+#include "hw/usb/hcd-ehci.h"
 
 #include "target/arm/cpu.h"
 
@@ -31,6 +32,7 @@  typedef struct AwA10State {
     AllwinnerAHCIState sata;
     MemoryRegion sram_a;
     OHCISysBusState ohci[2];
+    EHCISysBusState ehci[2];
 } AwA10State;
 
 #endif