aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/npcm7xx.c
diff options
context:
space:
mode:
authorHavard Skinnemoen <hskinnemoen@google.com>2020-10-23 14:06:36 -0700
committerPeter Maydell <peter.maydell@linaro.org>2020-10-27 11:10:21 +0000
commite23e7b12594ec0804c2d9f509f71841c82a62d1c (patch)
tree19a127eff01d60860447911f76dd747cf059d5b2 /hw/arm/npcm7xx.c
parent326ccfe240ca9ef4f659a241b39390fa956e999b (diff)
downloadqemu-e23e7b12594ec0804c2d9f509f71841c82a62d1c.zip
qemu-e23e7b12594ec0804c2d9f509f71841c82a62d1c.tar.gz
qemu-e23e7b12594ec0804c2d9f509f71841c82a62d1c.tar.bz2
hw/arm/npcm7xx: Add EHCI and OHCI controllers
The NPCM730 and NPCM750 chips have a single USB host port shared between a USB 2.0 EHCI host controller and a USB 1.1 OHCI host controller. This adds support for both of them. Testing notes: * With -device usb-kbd, qemu will automatically insert a full-speed hub, and the keyboard becomes controlled by the OHCI controller. * With -device usb-kbd,bus=usb-bus.0,port=1, the keyboard is directly attached to the port without any hubs, and the device becomes controlled by the EHCI controller since it's high speed capable. * With -device usb-kbd,bus=usb-bus.0,port=1,usb_version=1, the keyboard is directly attached to the port, but it only advertises itself as full-speed capable, so it becomes controlled by the OHCI controller. In all cases, the keyboard device enumerates correctly. Reviewed-by: Tyrone Ting <kfting@nuvoton.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm/npcm7xx.c')
-rw-r--r--hw/arm/npcm7xx.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index cb4db41..c1d1225 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -46,6 +46,10 @@
#define NPCM7XX_MC_BA (0xf0824000)
#define NPCM7XX_RNG_BA (0xf000b000)
+/* USB Host modules */
+#define NPCM7XX_EHCI_BA (0xf0806000)
+#define NPCM7XX_OHCI_BA (0xf0807000)
+
/* Internal AHB SRAM */
#define NPCM7XX_RAM3_BA (0xc0008000)
#define NPCM7XX_RAM3_SZ (4 * KiB)
@@ -90,6 +94,8 @@ enum NPCM7xxInterrupt {
NPCM7XX_WDG0_IRQ = 47, /* Timer Module 0 Watchdog */
NPCM7XX_WDG1_IRQ, /* Timer Module 1 Watchdog */
NPCM7XX_WDG2_IRQ, /* Timer Module 2 Watchdog */
+ NPCM7XX_EHCI_IRQ = 61,
+ NPCM7XX_OHCI_IRQ = 62,
};
/* Total number of GIC interrupts, including internal Cortex-A9 interrupts. */
@@ -263,6 +269,9 @@ static void npcm7xx_init(Object *obj)
object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
}
+ object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI);
+ object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI);
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
@@ -380,6 +389,22 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->rng), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rng), 0, NPCM7XX_RNG_BA);
+ /* USB Host */
+ object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true,
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ehci), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci), 0, NPCM7XX_EHCI_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci), 0,
+ npcm7xx_irq(s, NPCM7XX_EHCI_IRQ));
+
+ object_property_set_str(OBJECT(&s->ohci), "masterbus", "usb-bus.0",
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->ohci), "num-ports", 1, &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ohci), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci), 0, NPCM7XX_OHCI_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci), 0,
+ npcm7xx_irq(s, NPCM7XX_OHCI_IRQ));
+
/*
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
* specified, but this is a programming error.
@@ -464,8 +489,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
create_unimplemented_device("npcm7xx.gmac2", 0xf0804000, 8 * KiB);
- create_unimplemented_device("npcm7xx.ehci", 0xf0806000, 4 * KiB);
- create_unimplemented_device("npcm7xx.ohci", 0xf0807000, 4 * KiB);
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);