[PATCH v2 15/18] hw/arm/fsl-imx8mp: Add USB support

2025-02-23 Thread Bernhard Beschow
Split the USB MMIO regions to better keep track of the implemented vs.
unimplemented regions.

Reviewed-by: Peter Maydell 
Signed-off-by: Bernhard Beschow 
---
 docs/system/arm/imx8mp-evk.rst |  1 +
 include/hw/arm/fsl-imx8mp.h| 12 +++
 hw/arm/fsl-imx8mp.c| 37 --
 hw/arm/Kconfig |  1 +
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst
index 917c1d5176..00527b0cbe 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8mp-evk.rst
@@ -15,6 +15,7 @@ The ``imx8mp-evk`` machine implements the following devices:
  * 3 USDHC Storage Controllers
  * 1 Designware PCI Express Controller
  * 1 Ethernet Controller
+ * 2 Designware USB 3 Controllers
  * 5 GPIO Controllers
  * 6 I2C Controllers
  * 3 SPI Controllers
diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index e292c31a3d..5247e972b8 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -24,6 +24,7 @@
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/imx_spi.h"
 #include "hw/timer/imx_gpt.h"
+#include "hw/usb/hcd-dwc3.h"
 #include "hw/watchdog/wdt_imx2.h"
 #include "qom/object.h"
 #include "qemu/units.h"
@@ -42,6 +43,7 @@ enum FslImx8mpConfiguration {
 FSL_IMX8MP_NUM_I2CS = 6,
 FSL_IMX8MP_NUM_IRQS = 160,
 FSL_IMX8MP_NUM_UARTS= 4,
+FSL_IMX8MP_NUM_USBS = 2,
 FSL_IMX8MP_NUM_USDHCS   = 3,
 FSL_IMX8MP_NUM_WDTS = 3,
 };
@@ -62,6 +64,7 @@ struct FslImx8mpState {
 IMXFECStateenet;
 SDHCIState usdhc[FSL_IMX8MP_NUM_USDHCS];
 IMX2WdtState   wdt[FSL_IMX8MP_NUM_WDTS];
+USBDWC3usb[FSL_IMX8MP_NUM_USBS];
 DesignwarePCIEHost pcie;
 FslImx8mPciePhyState   pcie_phy;
 OrIRQState gpt5_gpt6_irq;
@@ -199,6 +202,12 @@ enum FslImx8mpMemoryRegions {
 FSL_IMX8MP_UART4,
 FSL_IMX8MP_USB1,
 FSL_IMX8MP_USB2,
+FSL_IMX8MP_USB1_DEV,
+FSL_IMX8MP_USB2_DEV,
+FSL_IMX8MP_USB1_OTG,
+FSL_IMX8MP_USB2_OTG,
+FSL_IMX8MP_USB1_GLUE,
+FSL_IMX8MP_USB2_GLUE,
 FSL_IMX8MP_USDHC1,
 FSL_IMX8MP_USDHC2,
 FSL_IMX8MP_USDHC3,
@@ -234,6 +243,9 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_I2C3_IRQ = 37,
 FSL_IMX8MP_I2C4_IRQ = 38,
 
+FSL_IMX8MP_USB1_IRQ = 40,
+FSL_IMX8MP_USB2_IRQ = 41,
+
 FSL_IMX8MP_GPT1_IRQ  = 55,
 FSL_IMX8MP_GPT2_IRQ  = 54,
 FSL_IMX8MP_GPT3_IRQ  = 53,
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 935279ee68..f0d5980300 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -40,8 +40,14 @@ static const struct {
 [FSL_IMX8MP_VPU_VC8000E_ENCODER] = { 0x3832, 2 * MiB, 
"vpu_vc8000e_encoder" },
 [FSL_IMX8MP_VPU_G2_DECODER] = { 0x3831, 2 * MiB, "vpu_g2_decoder" },
 [FSL_IMX8MP_VPU_G1_DECODER] = { 0x3830, 2 * MiB, "vpu_g1_decoder" },
-[FSL_IMX8MP_USB2] = { 0x3820, 1 * MiB, "usb2" },
-[FSL_IMX8MP_USB1] = { 0x3810, 1 * MiB, "usb1" },
+[FSL_IMX8MP_USB2_GLUE] = { 0x382f, 0x100, "usb2_glue" },
+[FSL_IMX8MP_USB2_OTG] = { 0x3820cc00, 0x100, "usb2_otg" },
+[FSL_IMX8MP_USB2_DEV] = { 0x3820c700, 0x500, "usb2_dev" },
+[FSL_IMX8MP_USB2] = { 0x3820, 0xc700, "usb2" },
+[FSL_IMX8MP_USB1_GLUE] = { 0x381f, 0x100, "usb1_glue" },
+[FSL_IMX8MP_USB1_OTG] = { 0x3810cc00, 0x100, "usb1_otg" },
+[FSL_IMX8MP_USB1_DEV] = { 0x3810c700, 0x500, "usb1_dev" },
+[FSL_IMX8MP_USB1] = { 0x3810, 0xc700, "usb1" },
 [FSL_IMX8MP_GPU2D] = { 0x38008000, 32 * KiB, "gpu2d" },
 [FSL_IMX8MP_GPU3D] = { 0x3800, 32 * KiB, "gpu3d" },
 [FSL_IMX8MP_QSPI1_RX_BUFFER] = { 0x3400, 32 * MiB, "qspi1_rx_buffer" },
@@ -230,6 +236,11 @@ static void fsl_imx8mp_init(Object *obj)
 object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
 }
 
+for (i = 0; i < FSL_IMX8MP_NUM_USBS; i++) {
+g_autofree char *name = g_strdup_printf("usb%d", i);
+object_initialize_child(obj, name, &s->usb[i], TYPE_USB_DWC3);
+}
+
 for (i = 0; i < FSL_IMX8MP_NUM_ECSPIS; i++) {
 g_autofree char *name = g_strdup_printf("spi%d", i + 1);
 object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
@@ -524,6 +535,27 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
 }
 
+/* USBs */
+for (i = 0; i < FSL_IMX8MP_NUM_USBS; i++) {
+static const struct {
+hwaddr addr;
+unsigned int irq;
+} usb_table[FSL_IMX8MP_NUM_USBS] = {
+{ fsl_imx8mp_memmap[FSL_IMX8MP_USB1].addr, FSL_IMX8MP_USB1_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_USB2].addr, FSL_IMX8MP_USB2_IRQ },
+};
+
+qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p2", 1);
+qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p3", 1);
+qde

Re: [PATCH v2 15/18] hw/arm/fsl-imx8mp: Add USB support

2025-02-06 Thread Peter Maydell
On Tue, 4 Feb 2025 at 09:21, Bernhard Beschow  wrote:
>
> Split the USB MMIO regions to better keep track of the implemented vs.
> unimplemented regions.
>
> Signed-off-by: Bernhard Beschow 
> ---
>  docs/system/arm/imx8mp-evk.rst |  1 +
>  include/hw/arm/fsl-imx8mp.h| 12 +++
>  hw/arm/fsl-imx8mp.c| 37 --
>  hw/arm/Kconfig |  1 +
>  4 files changed, 49 insertions(+), 2 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v2 15/18] hw/arm/fsl-imx8mp: Add USB support

2025-02-04 Thread Bernhard Beschow
Split the USB MMIO regions to better keep track of the implemented vs.
unimplemented regions.

Signed-off-by: Bernhard Beschow 
---
 docs/system/arm/imx8mp-evk.rst |  1 +
 include/hw/arm/fsl-imx8mp.h| 12 +++
 hw/arm/fsl-imx8mp.c| 37 --
 hw/arm/Kconfig |  1 +
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst
index 4109387b6e..b3d657be10 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8mp-evk.rst
@@ -16,6 +16,7 @@ The ``imx8mp-evk`` machine implements the following devices:
  * 3 USDHC Storage Controllers
  * 1 Designware PCI Express Controller
  * 1 Ethernet Controller
+ * 2 Designware USB 3 Controllers
  * 5 GPIO Controllers
  * 6 I2C Controllers
  * 3 SPI Controllers
diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index e292c31a3d..5247e972b8 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -24,6 +24,7 @@
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/imx_spi.h"
 #include "hw/timer/imx_gpt.h"
+#include "hw/usb/hcd-dwc3.h"
 #include "hw/watchdog/wdt_imx2.h"
 #include "qom/object.h"
 #include "qemu/units.h"
@@ -42,6 +43,7 @@ enum FslImx8mpConfiguration {
 FSL_IMX8MP_NUM_I2CS = 6,
 FSL_IMX8MP_NUM_IRQS = 160,
 FSL_IMX8MP_NUM_UARTS= 4,
+FSL_IMX8MP_NUM_USBS = 2,
 FSL_IMX8MP_NUM_USDHCS   = 3,
 FSL_IMX8MP_NUM_WDTS = 3,
 };
@@ -62,6 +64,7 @@ struct FslImx8mpState {
 IMXFECStateenet;
 SDHCIState usdhc[FSL_IMX8MP_NUM_USDHCS];
 IMX2WdtState   wdt[FSL_IMX8MP_NUM_WDTS];
+USBDWC3usb[FSL_IMX8MP_NUM_USBS];
 DesignwarePCIEHost pcie;
 FslImx8mPciePhyState   pcie_phy;
 OrIRQState gpt5_gpt6_irq;
@@ -199,6 +202,12 @@ enum FslImx8mpMemoryRegions {
 FSL_IMX8MP_UART4,
 FSL_IMX8MP_USB1,
 FSL_IMX8MP_USB2,
+FSL_IMX8MP_USB1_DEV,
+FSL_IMX8MP_USB2_DEV,
+FSL_IMX8MP_USB1_OTG,
+FSL_IMX8MP_USB2_OTG,
+FSL_IMX8MP_USB1_GLUE,
+FSL_IMX8MP_USB2_GLUE,
 FSL_IMX8MP_USDHC1,
 FSL_IMX8MP_USDHC2,
 FSL_IMX8MP_USDHC3,
@@ -234,6 +243,9 @@ enum FslImx8mpIrqs {
 FSL_IMX8MP_I2C3_IRQ = 37,
 FSL_IMX8MP_I2C4_IRQ = 38,
 
+FSL_IMX8MP_USB1_IRQ = 40,
+FSL_IMX8MP_USB2_IRQ = 41,
+
 FSL_IMX8MP_GPT1_IRQ  = 55,
 FSL_IMX8MP_GPT2_IRQ  = 54,
 FSL_IMX8MP_GPT3_IRQ  = 53,
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 665123cf9c..14d696957a 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -40,8 +40,14 @@ static const struct {
 [FSL_IMX8MP_VPU_VC8000E_ENCODER] = { 0x3832, 2 * MiB, 
"vpu_vc8000e_encoder" },
 [FSL_IMX8MP_VPU_G2_DECODER] = { 0x3831, 2 * MiB, "vpu_g2_decoder" },
 [FSL_IMX8MP_VPU_G1_DECODER] = { 0x3830, 2 * MiB, "vpu_g1_decoder" },
-[FSL_IMX8MP_USB2] = { 0x3820, 1 * MiB, "usb2" },
-[FSL_IMX8MP_USB1] = { 0x3810, 1 * MiB, "usb1" },
+[FSL_IMX8MP_USB2_GLUE] = { 0x382f, 0x100, "usb2_glue" },
+[FSL_IMX8MP_USB2_OTG] = { 0x3820cc00, 0x100, "usb2_otg" },
+[FSL_IMX8MP_USB2_DEV] = { 0x3820c700, 0x500, "usb2_dev" },
+[FSL_IMX8MP_USB2] = { 0x3820, 0xc700, "usb2" },
+[FSL_IMX8MP_USB1_GLUE] = { 0x381f, 0x100, "usb1_glue" },
+[FSL_IMX8MP_USB1_OTG] = { 0x3810cc00, 0x100, "usb1_otg" },
+[FSL_IMX8MP_USB1_DEV] = { 0x3810c700, 0x500, "usb1_dev" },
+[FSL_IMX8MP_USB1] = { 0x3810, 0xc700, "usb1" },
 [FSL_IMX8MP_GPU2D] = { 0x38008000, 32 * KiB, "gpu2d" },
 [FSL_IMX8MP_GPU3D] = { 0x3800, 32 * KiB, "gpu3d" },
 [FSL_IMX8MP_QSPI1_RX_BUFFER] = { 0x3400, 32 * MiB, "qspi1_rx_buffer" },
@@ -233,6 +239,11 @@ static void fsl_imx8mp_init(Object *obj)
 object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
 }
 
+for (i = 0; i < FSL_IMX8MP_NUM_USBS; i++) {
+snprintf(name, NAME_SIZE, "usb%d", i);
+object_initialize_child(obj, name, &s->usb[i], TYPE_USB_DWC3);
+}
+
 for (i = 0; i < FSL_IMX8MP_NUM_ECSPIS; i++) {
 snprintf(name, NAME_SIZE, "spi%d", i + 1);
 object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
@@ -528,6 +539,27 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
 }
 
+/* USBs */
+for (i = 0; i < FSL_IMX8MP_NUM_USBS; i++) {
+static const struct {
+hwaddr addr;
+unsigned int irq;
+} usb_table[FSL_IMX8MP_NUM_USBS] = {
+{ fsl_imx8mp_memmap[FSL_IMX8MP_USB1].addr, FSL_IMX8MP_USB1_IRQ },
+{ fsl_imx8mp_memmap[FSL_IMX8MP_USB2].addr, FSL_IMX8MP_USB2_IRQ },
+};
+
+qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p2", 1);
+qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "p3", 1);
+qdev_prop_set_uint32(DEVICE(&s->usb[i].sysbus_xhci), "slots