qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Beniamino Galvani <b.galvani@gmail.com>,
	Strahinja Jankovic <strahinja.p.jankovic@gmail.com>,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH 1/3] hw/arm: Add EHCI/OHCI controllers to Allwinner R40 and Bananapi board
Date: Sat, 13 Jan 2024 11:16:49 -0800	[thread overview]
Message-ID: <20240113191651.1313226-2-linux@roeck-us.net> (raw)
In-Reply-To: <20240113191651.1313226-1-linux@roeck-us.net>

Allwinner R40 supports two USB host ports shared between a USB 2.0 EHCI
host controller and a USB 1.1 OHCI host controller. Add support for both
of them.

If machine USB support is not enabled, create unimplemented devices
for the USB memory ranges to avoid crashes when booting Linux.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 docs/system/arm/bananapi_m2u.rst |  2 +-
 hw/arm/Kconfig                   |  2 +
 hw/arm/allwinner-r40.c           | 70 +++++++++++++++++++++++++++++++-
 include/hw/arm/allwinner-r40.h   |  9 ++++
 4 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/bananapi_m2u.rst b/docs/system/arm/bananapi_m2u.rst
index b09ba5c548..e77c425e2c 100644
--- a/docs/system/arm/bananapi_m2u.rst
+++ b/docs/system/arm/bananapi_m2u.rst
@@ -23,6 +23,7 @@ The Banana Pi M2U machine supports the following devices:
  * GMAC ethernet
  * Clock Control Unit
  * TWI (I2C)
+ * USB 2.0
 
 Limitations
 """""""""""
@@ -33,7 +34,6 @@ Currently, Banana Pi M2U does *not* support the following features:
 - Audio output
 - Hardware Watchdog
 - Real Time Clock
-- USB 2.0 interfaces
 
 Also see the 'unimplemented' array in the Allwinner R40 SoC module
 for a complete list of unimplemented I/O devices: ``./hw/arm/allwinner-r40.c``
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 39d255425b..6b508780d3 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -415,6 +415,8 @@ config ALLWINNER_R40
     select ARM_TIMER
     select ARM_GIC
     select UNIMP
+    select USB_OHCI
+    select USB_EHCI_SYSBUS
     select SD
 
 config RASPI
diff --git a/hw/arm/allwinner-r40.c b/hw/arm/allwinner-r40.c
index a0d367c60d..f42b0fa0ce 100644
--- a/hw/arm/allwinner-r40.c
+++ b/hw/arm/allwinner-r40.c
@@ -23,6 +23,7 @@
 #include "qemu/bswap.h"
 #include "qemu/module.h"
 #include "qemu/units.h"
+#include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "hw/sysbus.h"
 #include "hw/char/serial.h"
@@ -45,6 +46,10 @@ const hwaddr allwinner_r40_memmap[] = {
     [AW_R40_DEV_MMC1]       = 0x01c10000,
     [AW_R40_DEV_MMC2]       = 0x01c11000,
     [AW_R40_DEV_MMC3]       = 0x01c12000,
+    [AW_R40_DEV_EHCI1]      = 0x01c19000,
+    [AW_R40_DEV_OHCI1]      = 0x01c19400,
+    [AW_R40_DEV_EHCI2]      = 0x01c1c000,
+    [AW_R40_DEV_OHCI2]      = 0x01c1c400,
     [AW_R40_DEV_CCU]        = 0x01c20000,
     [AW_R40_DEV_PIT]        = 0x01c20c00,
     [AW_R40_DEV_UART0]      = 0x01c28000,
@@ -89,9 +94,9 @@ static struct AwR40Unimplemented r40_unimplemented[] = {
     { "crypto",     0x01c15000, 4 * KiB },
     { "spi2",       0x01c17000, 4 * KiB },
     { "sata",       0x01c18000, 4 * KiB },
-    { "usb1-host",  0x01c19000, 4 * KiB },
+    { "usb1-phy",   0x01c19800, 2 * KiB },
     { "sid",        0x01c1b000, 4 * KiB },
-    { "usb2-host",  0x01c1c000, 4 * KiB },
+    { "usb2-phy",   0x01c1c800, 2 * KiB },
     { "cs1",        0x01c1d000, 4 * KiB },
     { "spi3",       0x01c1f000, 4 * KiB },
     { "rtc",        0x01c20400, 1 * KiB },
@@ -181,6 +186,10 @@ enum {
     AW_R40_GIC_SPI_MMC2      = 34,
     AW_R40_GIC_SPI_MMC3      = 35,
     AW_R40_GIC_SPI_EMAC      = 55,
+    AW_R40_GIC_SPI_OHCI1     = 64,
+    AW_R40_GIC_SPI_OHCI2     = 65,
+    AW_R40_GIC_SPI_EHCI1     = 76,
+    AW_R40_GIC_SPI_EHCI2     = 78,
     AW_R40_GIC_SPI_GMAC      = 85,
 };
 
@@ -276,6 +285,17 @@ static void allwinner_r40_init(Object *obj)
                                 TYPE_AW_SDHOST_SUN50I_A64);
     }
 
+    if (machine_usb(current_machine)) {
+        int i;
+
+        for (i = 0; i < AW_R40_NUM_USB; i++) {
+            object_initialize_child(obj, "ehci[*]", &s->ehci[i],
+                                    TYPE_PLATFORM_EHCI);
+            object_initialize_child(obj, "ohci[*]", &s->ohci[i],
+                                    TYPE_SYSBUS_OHCI);
+        }
+    }
+
     object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C_SUN6I);
 
     object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
@@ -407,6 +427,37 @@ static void allwinner_r40_realize(DeviceState *dev, Error **errp)
     sysbus_realize(SYS_BUS_DEVICE(&s->ccu), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccu), 0, s->memmap[AW_R40_DEV_CCU]);
 
+    /* USB */
+    if (machine_usb(current_machine)) {
+        int i;
+
+        for (i = 0; i < AW_R40_NUM_USB; i++) {
+            g_autofree char *bus = g_strdup_printf("usb-bus.%d", i);
+
+            object_property_set_bool(OBJECT(&s->ehci[i]), "companion-enable",
+                                     true, &error_fatal);
+            sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), &error_fatal);
+            sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+                            allwinner_r40_memmap[i ? AW_R40_DEV_EHCI2
+                                                   : AW_R40_DEV_EHCI1]);
+            sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+                               qdev_get_gpio_in(DEVICE(&s->gic),
+                                                i ? AW_R40_GIC_SPI_EHCI2
+                                                  : AW_R40_GIC_SPI_EHCI1));
+
+            object_property_set_str(OBJECT(&s->ohci[i]), "masterbus", bus,
+                                    &error_fatal);
+            sysbus_realize(SYS_BUS_DEVICE(&s->ohci[i]), &error_fatal);
+            sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0,
+                            allwinner_r40_memmap[i ? AW_R40_DEV_OHCI2
+                                                   : AW_R40_DEV_OHCI1]);
+            sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
+                               qdev_get_gpio_in(DEVICE(&s->gic),
+                                                i ? AW_R40_GIC_SPI_OHCI2
+                                                  : AW_R40_GIC_SPI_OHCI1));
+        }
+    }
+
     /* SD/MMC */
     for (int i = 0; i < AW_R40_NUM_MMCS; i++) {
         qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->gic),
@@ -498,6 +549,21 @@ static void allwinner_r40_realize(DeviceState *dev, Error **errp)
                                     r40_unimplemented[i].base,
                                     r40_unimplemented[i].size);
     }
+    if (!machine_usb(current_machine)) {
+        /* unimplemented if USB is not enabled */
+        create_unimplemented_device("usb-ehci1",
+                                    allwinner_r40_memmap[AW_R40_DEV_EHCI1],
+                                    0x800);
+        create_unimplemented_device("usb-ehci2",
+                                    allwinner_r40_memmap[AW_R40_DEV_EHCI2],
+                                    0x800);
+        create_unimplemented_device("usb-ohci1",
+                                    allwinner_r40_memmap[AW_R40_DEV_OHCI1],
+                                    0x800);
+        create_unimplemented_device("usb-ohci2",
+                                    allwinner_r40_memmap[AW_R40_DEV_OHCI2],
+                                    0x800);
+    }
 }
 
 static void allwinner_r40_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/arm/allwinner-r40.h b/include/hw/arm/allwinner-r40.h
index 6e1ac9d4c1..ae82822d42 100644
--- a/include/hw/arm/allwinner-r40.h
+++ b/include/hw/arm/allwinner-r40.h
@@ -30,6 +30,8 @@
 #include "hw/i2c/allwinner-i2c.h"
 #include "hw/net/allwinner_emac.h"
 #include "hw/net/allwinner-sun8i-emac.h"
+#include "hw/usb/hcd-ohci.h"
+#include "hw/usb/hcd-ehci.h"
 #include "target/arm/cpu.h"
 #include "sysemu/block-backend.h"
 
@@ -44,6 +46,10 @@ enum {
     AW_R40_DEV_MMC1,
     AW_R40_DEV_MMC2,
     AW_R40_DEV_MMC3,
+    AW_R40_DEV_EHCI1,
+    AW_R40_DEV_OHCI1,
+    AW_R40_DEV_EHCI2,
+    AW_R40_DEV_OHCI2,
     AW_R40_DEV_CCU,
     AW_R40_DEV_PIT,
     AW_R40_DEV_UART0,
@@ -88,6 +94,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AwR40State, AW_R40)
  * which are currently emulated by the R40 SoC code.
  */
 #define AW_R40_NUM_MMCS         4
+#define AW_R40_NUM_USB          2
 #define AW_R40_NUM_UARTS        8
 
 struct AwR40State {
@@ -106,6 +113,8 @@ struct AwR40State {
     AwSRAMCState sramc;
     AwA10PITState timer;
     AwSdHostState mmc[AW_R40_NUM_MMCS];
+    EHCISysBusState ehci[AW_R40_NUM_USB];
+    OHCISysBusState ohci[AW_R40_NUM_USB];
     AwR40ClockCtlState ccu;
     AwR40DramCtlState dramc;
     AWI2CState i2c0;
-- 
2.39.2



  reply	other threads:[~2024-01-13 19:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-13 19:16 [PATCH 0/3] hw/arm: Add support for USB, SATA, and watchdog to Allwinner R40 Guenter Roeck
2024-01-13 19:16 ` Guenter Roeck [this message]
2024-01-15 11:02   ` [PATCH 1/3] hw/arm: Add EHCI/OHCI controllers to Allwinner R40 and Bananapi board Philippe Mathieu-Daudé
2024-01-15 16:12     ` Guenter Roeck
2024-01-15 16:30       ` Philippe Mathieu-Daudé
2024-01-15 17:17         ` Guenter Roeck
2024-01-16 10:13       ` Gerd Hoffmann
2024-01-17 11:05         ` Bernhard Beschow
2024-01-17 14:51           ` Gerd Hoffmann
2024-01-13 19:16 ` [PATCH 2/3] hw/arm: Add AHCI/SATA controller " Guenter Roeck
2024-01-15 11:04   ` Philippe Mathieu-Daudé
2024-01-13 19:16 ` [PATCH 3/3] hw/arm: Add watchdog timer to Allwinner H40 " Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240113191651.1313226-2-linux@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=b.galvani@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=strahinja.p.jankovic@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).