hw/arm/fsl-imx8mm: Adding support for USB controller
It enables emulation of USB on iMX8MM Enables testing and debugging of USB drivers Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Bernhard Beschow <shentey@gmail.com> Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Gaurav Sharma committed
Apr 21, 2026 at 12:22 UTC
d1139f2cc3e788835cae485b78eb98ec81291926
3 files changed
+34
hw/arm/Kconfig
+1
@@ -631,6 +631,7 @@ config FSL_IMX8MM
631
select SDHCI
632
select PCI_EXPRESS_DESIGNWARE
633
select PCI_EXPRESS_FSL_IMX8M_PHY
634
+ select USB_DWC3
635
select WDT_IMX2
636
637
config FSL_IMX8MM_EVK
hw/arm/fsl-imx8mm.c
+27
@@ -202,6 +202,11 @@ static void fsl_imx8mm_init(Object *obj)
202
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
203
}
204
205
+ for (i = 0; i < FSL_IMX8MM_NUM_USBS; i++) {
206
+ g_autofree char *name = g_strdup_printf("usb%d", i);
207
+ object_initialize_child(obj, name, &s->usb[i], TYPE_USB_DWC3);
208
+ }
209
+
210
for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
211
g_autofree char *name = g_strdup_printf("spi%d", i + 1);
212
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
@@ -529,6 +534,27 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
534
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
535
}
536
537
+ /* USBs */
538
+ for (i = 0; i < FSL_IMX8MM_NUM_USBS; i++) {
539
+ static const struct {
540
+ hwaddr addr;
541
+ unsigned int irq;
542
+ } usb_table[FSL_IMX8MM_NUM_USBS] = {
543
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB1].addr, FSL_IMX8MM_USB1_IRQ },
544
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB2].addr, FSL_IMX8MM_USB2_IRQ },
545
+ };
546
+
547
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p2", 1);
548
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p3", 1);
549
+ qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "slots", 2);
550
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), errp)) {
551
+ return;
552
+ }
553
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr);
554
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i].sysbus_xhci), 0,
555
+ qdev_get_gpio_in(gicdev, usb_table[i].irq));
556
+ }
557
+
558
/* ECSPIs */
559
for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
560
static const struct {
@@ -635,6 +661,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
661
case FSL_IMX8MM_OCRAM:
662
case FSL_IMX8MM_SNVS_HP:
663
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
664
+ case FSL_IMX8MM_USB1 ... FSL_IMX8MM_USB2:
665
case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
666
case FSL_IMX8MM_WDOG1 ... FSL_IMX8MM_WDOG3:
667
/* device implemented and treated above */
include/hw/arm/fsl-imx8mm.h
+6
@@ -25,6 +25,7 @@
25
#include "hw/sd/sdhci.h"
26
#include "hw/ssi/imx_spi.h"
27
#include "hw/timer/imx_gpt.h"
28
+#include "hw/usb/hcd-dwc3.h"
29
#include "hw/watchdog/wdt_imx2.h"
30
#include "qom/object.h"
31
#include "qemu/units.h"
@@ -43,6 +44,7 @@ enum FslImx8mmConfiguration {
44
FSL_IMX8MM_NUM_I2CS = 4,
45
FSL_IMX8MM_NUM_IRQS = 128,
46
FSL_IMX8MM_NUM_UARTS = 4,
47
+ FSL_IMX8MM_NUM_USBS = 2,
48
FSL_IMX8MM_NUM_USDHCS = 3,
49
FSL_IMX8MM_NUM_WDTS = 3,
50
};
@@ -64,6 +66,7 @@ struct FslImx8mmState {
66
IMXFECState enet;
67
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
68
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
69
+ USBDWC3 usb[FSL_IMX8MM_NUM_USBS];
70
DesignwarePCIEHost pcie;
71
FslImx8mPciePhyState pcie_phy;
72
OrIRQState gpt5_gpt6_irq;
@@ -202,6 +205,9 @@ enum FslImx8mmIrqs {
205
FSL_IMX8MM_I2C3_IRQ = 37,
206
FSL_IMX8MM_I2C4_IRQ = 38,
207
208
+ FSL_IMX8MM_USB1_IRQ = 40,
209
+ FSL_IMX8MM_USB2_IRQ = 41,
210
+
211
FSL_IMX8MM_GPT1_IRQ = 55,
212
FSL_IMX8MM_GPT2_IRQ = 54,
213
FSL_IMX8MM_GPT3_IRQ = 53,