Create the USB Device Controller (UDC) at 0x1e6a2000 on the AST2600 SoC and map its registers.
The UDC and the second EHCI host controller (EHCI2) share one SoC interrupt line. Route both through an OR gate whose output drives that GIC input, so either device can raise the interrupt without the other clobbering the line. The gadget USB device is not created by the SoC. It is a separate, user-creatable "aspeed.udc-gadget" USB device that the user plugs onto a USB host controller's bus; it finds its controller through the "udc" link property, e.g. -device aspeed.udc-gadget,udc=/machine/soc/udc Signed-off-by: Jamin Lin <[email protected]> --- include/hw/arm/aspeed_soc.h | 4 ++++ hw/arm/aspeed_ast2600.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index cd68c7f1ca..fe7b31e42c 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -36,6 +36,8 @@ #include "hw/gpio/aspeed_sgpio.h" #include "hw/sd/aspeed_sdhci.h" #include "hw/usb/hcd-ehci.h" +#include "hw/usb/aspeed-udc.h" +#include "hw/core/or-irq.h" #include "qom/object.h" #include "hw/misc/aspeed_lpc.h" #include "hw/misc/unimp.h" @@ -138,6 +140,8 @@ struct Aspeed2600SoCState { A15MPPrivState a7mpcore; ARMCPU cpu[ASPEED_CPUS_NUM]; /* XXX belong to a7mpcore */ + AspeedUDCState udc; + OrIRQState ehci2_udc_orgate; }; #define TYPE_ASPEED2600_SOC "aspeed2600-soc" diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index d1f18e471a..21db95f5ae 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -32,6 +32,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = { [ASPEED_DEV_SPI1] = 0x1E630000, [ASPEED_DEV_SPI2] = 0x1E631000, [ASPEED_DEV_EHCI1] = 0x1E6A1000, + [ASPEED_DEV_UDC] = 0x1E6A2000, [ASPEED_DEV_EHCI2] = 0x1E6A3000, [ASPEED_DEV_MII1] = 0x1E650000, [ASPEED_DEV_MII2] = 0x1E650008, @@ -214,6 +215,10 @@ static void aspeed_soc_ast2600_init(Object *obj) TYPE_PLATFORM_EHCI); } + object_initialize_child(obj, "udc", &a->udc, TYPE_ASPEED_UDC); + object_initialize_child(obj, "ehci2-udc-orgate", &a->ehci2_udc_orgate, + TYPE_OR_IRQ); + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); object_initialize_child(obj, "sdmc", &s->sdmc, typename); object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), @@ -561,6 +566,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_SPI1 + i)); } + /* + * EHCI2 and the UDC share one SoC interrupt line, so OR their outputs + * together and drive that GIC input from the OR gate. + */ + object_property_set_int(OBJECT(&a->ehci2_udc_orgate), "num-lines", 2, + &error_abort); + qdev_realize(DEVICE(&a->ehci2_udc_orgate), NULL, &error_abort); + qdev_connect_gpio_out(DEVICE(&a->ehci2_udc_orgate), 0, + aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_EHCI2)); + /* EHCI */ for (i = 0; i < sc->ehcis_num; i++) { if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) { @@ -568,10 +583,26 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->ehci[i]), 0, sc->memmap[ASPEED_DEV_EHCI1 + i]); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, - aspeed_soc_ast2600_get_irq(s, - ASPEED_DEV_EHCI1 + i)); } + /* + * EHCI1 has its own IRQ; EHCI2 shares the UDC's IRQ, so route it through + * the OR gate. + */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[0]), 0, + aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_EHCI1)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[1]), 0, + qdev_get_gpio_in(DEVICE(&a->ehci2_udc_orgate), 0)); + + /* UDC - USB 2.0 Device Controller */ + object_property_set_link(OBJECT(&a->udc), "dram", OBJECT(s->dram_mr), + &error_abort); + if (!sysbus_realize(SYS_BUS_DEVICE(&a->udc), errp)) { + return; + } + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&a->udc), 0, + sc->memmap[ASPEED_DEV_UDC]); + sysbus_connect_irq(SYS_BUS_DEVICE(&a->udc), 0, + qdev_get_gpio_in(DEVICE(&a->ehci2_udc_orgate), 1)); /* SDMC - SDRAM Memory Controller */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) { -- 2.53.0
