* [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board
@ 2025-12-05 5:38 Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 01/15] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Gaurav Sharma
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Changes in v4:
- Update Maintainers file
- Re-used iMX8MP CCM and Analog IP for iMX8MM by introducing a variant
specific property
- Split up the patch that enabled CCM and Analog in the previous
revision. Now we have 3 patches to enable CCM and Analog in iMX8MM
- Updated copyrights
- Removed '|| KVM' from hw/arm/Kconfig to prevent 'make check' failures
Changes in v3:
- Minor documentation change - Added KVM Acceleration section in docs/system/arm/imx8mm-evk.rst
Changes in v2:
- Fixed the DTB offset in functional testing script test_imx8mm_evk.py
and preserved alphabetical order of machine names in tests/functional/aarch64/meson.build
- Fixed a typo and updated the documentation
- Modified structures type to static const in fsl-imx8mm.c wherever
applicable.
- Added CSI and DSI nodes to the nodes_to_remove list in imx8mm-evk.c. This
is needed because the default DTB in the iMX LF BSP images have CSI
and DSI enabled. Developers/Hobbyists using these BSP images will
observe CSI and DSI crash logs on the console since these are unimplemented.
With this change, both debian and iMX LF images will boot up without any issues.
Changes in v1:
This patch series adds support for the NXP i.MX8MM EVK (Evaluation Kit)
board to QEMU, enabling emulation of this ARM Cortex-A53 based development
platform.
The series includes:
1. Core peripheral support (CCM clock controller, Analog module)
2. GPT(General Purpose Timer) and WDT(Watchdog Timer) Emulation support
3. GPIO,I2C,SPI,USDHC and USB Emulation support
4. PCIe and ENET Controller Emulation support
5. Documentation and functional test included
Key features ported:
- Basic boot support with Linux
- UART console for serial communication
- Interrupt handling
- Clock and power management infrastructure
Testing:
- Linux kernel boots to console
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
Gaurav Sharma (15):
hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board
hw/misc/imx8mp_analog: Add property to analog device
hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC
hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM
hw/arm/fsl-imx8mm: Implemented support for SNVS
hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers
hw/arm/fsl-imx8mm: Add PCIe support
hw/arm/fsl-imx8mm: Add GPIO controllers
hw/arm/fsl-imx8mm: Adding support for I2C emulation
hw/arm/fsl-imx8mm: Adding support for SPI controller
hw/arm/fsl-imx8mm: Adding support for Watchdog Timers
hw/arm/fsl-imx8mm: Adding support for General Purpose Timers
hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller
hw/arm/fsl-imx8mm: Adding support for USB controller
hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation
MAINTAINERS | 10 +
docs/system/arm/imx8mm-evk.rst | 79 +++
docs/system/target-arm.rst | 1 +
hw/arm/Kconfig | 24 +
hw/arm/fsl-imx8mm.c | 692 ++++++++++++++++++++
hw/arm/imx8mm-evk.c | 128 ++++
hw/arm/meson.build | 2 +
hw/misc/imx8mp_analog.c | 12 +-
hw/timer/imx_gpt.c | 26 +
include/hw/arm/fsl-imx8mm.h | 241 +++++++
include/hw/misc/imx8mp_analog.h | 3 +
include/hw/timer/imx_gpt.h | 2 +
tests/functional/aarch64/meson.build | 2 +
tests/functional/aarch64/test_imx8mm_evk.py | 67 ++
14 files changed, 1288 insertions(+), 1 deletion(-)
create mode 100644 docs/system/arm/imx8mm-evk.rst
create mode 100644 hw/arm/fsl-imx8mm.c
create mode 100644 hw/arm/imx8mm-evk.c
create mode 100644 include/hw/arm/fsl-imx8mm.h
create mode 100755 tests/functional/aarch64/test_imx8mm_evk.py
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCHv4 01/15] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 02/15] hw/misc/imx8mp_analog: Add property to analog device Gaurav Sharma
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Implemented CPUs, RAM, UARTs and Interrupt Controller
Other peripherals are represented as TYPE_UNIMPLEMENTED_DEVICE
Complete memory map of the SoC is provided.
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
MAINTAINERS | 10 +
docs/system/arm/imx8mm-evk.rst | 68 ++++++
docs/system/target-arm.rst | 1 +
hw/arm/Kconfig | 12 ++
hw/arm/fsl-imx8mm.c | 366 +++++++++++++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 110 ++++++++++
hw/arm/meson.build | 2 +
include/hw/arm/fsl-imx8mm.h | 157 ++++++++++++++
8 files changed, 726 insertions(+)
create mode 100644 docs/system/arm/imx8mm-evk.rst
create mode 100644 hw/arm/fsl-imx8mm.c
create mode 100644 hw/arm/imx8mm-evk.c
create mode 100644 include/hw/arm/fsl-imx8mm.h
diff --git a/MAINTAINERS b/MAINTAINERS
index be6efff80c..41f76c5bd0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -884,6 +884,16 @@ F: hw/pci-host/designware.c
F: include/hw/pci-host/designware.h
F: docs/system/arm/mcimx7d-sabre.rst
+MCIMX8MM-EVK / iMX8MM
+M: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/fsl-imx8mm.c
+F: hw/arm/imx8mm-evk.c
+F: include/hw/arm/fsl-imx8mm.h
+F: docs/system/arm/imx8mm-evk.rst
+F: tests/functional/aarch64/test_imx8mm_evk.py
+
MCIMX8MP-EVK / i.MX8MP
M: Bernhard Beschow <shentey@gmail.com>
L: qemu-arm@nongnu.org
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
new file mode 100644
index 0000000000..408253193c
--- /dev/null
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -0,0 +1,68 @@
+NXP i.MX 8MM Evaluation Kit (``imx8mm-evk``)
+================================================
+
+The ``imx8mm-evk`` machine models the i.MX 8M Mini Evaluation Kit, based on an
+i.MX 8MM SoC.
+
+Supported devices
+-----------------
+
+The ``imx8mm-evk`` machine implements the following devices:
+
+ * Up to 4 Cortex-A53 cores
+ * Generic Interrupt Controller (GICv3)
+ * 4 UARTs
+
+Boot options
+------------
+
+The ``imx8mm-evk`` machine can start a Linux kernel directly using the standard
+``-kernel`` functionality.
+
+Direct Linux Kernel Boot
+''''''''''''''''''''''''
+
+Probably the easiest way to get started with a whole Linux system on the machine
+is to generate an image with Buildroot. Version 2024.11.1 is tested at the time
+of writing and involves two steps. First run the following commands in the
+toplevel directory of the Buildroot source tree:
+
+.. code-block:: bash
+
+ $ make freescale_imx8mmevk_defconfig
+ $ make
+
+Once finished successfully there is an ``output/image`` subfolder. Navigate into
+it and resize the SD card image to a power of two:
+
+.. code-block:: bash
+
+ $ qemu-img resize sdcard.img 256M
+
+Now that everything is prepared the machine can be started as follows:
+
+.. code-block:: bash
+
+ $ qemu-system-aarch64 -M imx8mm-evk -smp 4 -m 3G \
+ -display none -serial null -serial stdio \
+ -kernel Image \
+ -dtb imx8mm-evk.dtb \
+ -append "root=/dev/mmcblk2p2" \
+ -drive file=sdcard.img,if=sd,bus=2,format=raw,id=mmcblk2
+
+
+KVM Acceleration
+----------------
+
+Be aware of the following limitations:
+
+* The ``imx8mm-evk`` machine is not included under the "virtualization use case"
+ of :doc:`QEMU's security policy </system/security>`. This means that you
+ should not trust that it can contain malicious guests, whether it is run
+ using TCG or KVM. If you don't trust your guests and you're relying on QEMU to
+ be the security boundary, you want to choose another machine such as ``virt``.
+* Rather than Cortex-A53 CPUs, the same CPU type as the host's will be used.
+ This is a limitation of KVM and may not work with guests with a tight
+ dependency on Cortex-A53.
+* No EL2 and EL3 exception levels are available which is also a KVM limitation.
+ Direct kernel boot should work but running U-Boot, TF-A, etc. won't succeed.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index a96d1867df..d6a4b5bb00 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -97,6 +97,7 @@ Board-specific documentation
arm/mcimx6ul-evk
arm/mcimx7d-sabre
arm/imx8mp-evk
+ arm/imx8mm-evk
arm/orangepi
arm/raspi
arm/collie
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 0cdeb60f1f..be38c67a1c 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -626,6 +626,18 @@ config FSL_IMX8MP_EVK
depends on TCG || KVM
select FSL_IMX8MP
+config FSL_IMX8MM
+ bool
+ select ARM_GIC
+ select IMX
+
+config FSL_IMX8MM_EVK
+ bool
+ default y
+ depends on AARCH64
+ depends on TCG
+ select FSL_IMX8MM
+
config ARM_SMMUV3
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
new file mode 100644
index 0000000000..fb6a78adba
--- /dev/null
+++ b/hw/arm/fsl-imx8mm.c
@@ -0,0 +1,366 @@
+/*
+ * i.MX 8MM SoC Implementation
+ *
+ * Based on hw/arm/fsl-imx6.c
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * iMX8MM Reference Manual - https://www.nxp.com/products/i.MX8MMINI -> Documentation
+ */
+
+#include "qemu/osdep.h"
+#include "system/address-spaces.h"
+#include "hw/arm/bsa.h"
+#include "hw/arm/fsl-imx8mm.h"
+#include "hw/misc/unimp.h"
+#include "hw/boards.h"
+#include "system/kvm.h"
+#include "system/system.h"
+#include "target/arm/cpu.h"
+#include "target/arm/cpu-qom.h"
+#include "target/arm/kvm_arm.h"
+#include "qapi/error.h"
+#include "qobject/qlist.h"
+
+static const struct {
+ hwaddr addr;
+ size_t size;
+ const char *name;
+} fsl_imx8mm_memmap[] = {
+ [FSL_IMX8MM_RAM] = { FSL_IMX8MM_RAM_START, FSL_IMX8MM_RAM_SIZE_MAX, "ram" },
+ [FSL_IMX8MM_DDR_PHY_BROADCAST] = { 0x3dc00000, 4 * MiB, "ddr_phy_broadcast" },
+ [FSL_IMX8MM_DDR_PERF_MON] = { 0x3d800000, 4 * MiB, "ddr_perf_mon" },
+ [FSL_IMX8MM_DDR_CTL] = { 0x3d400000, 4 * MiB, "ddr_ctl" },
+ [FSL_IMX8MM_DDR_PHY] = { 0x3c000000, 16 * MiB, "ddr_phy" },
+ [FSL_IMX8MM_GIC_DIST] = { 0x38800000, 512 * KiB, "gic_dist" },
+ [FSL_IMX8MM_GIC_REDIST] = { 0x38880000, 512 * KiB, "gic_redist" },
+ [FSL_IMX8MM_VPU] = { 0x38340000, 2 * MiB, "vpu" },
+ [FSL_IMX8MM_VPU_BLK_CTRL] = { 0x38330000, 2 * MiB, "vpu_blk_ctrl" },
+ [FSL_IMX8MM_VPU_G2_DECODER] = { 0x38310000, 1 * MiB, "vpu_g2_decoder" },
+ [FSL_IMX8MM_VPU_G1_DECODER] = { 0x38300000, 1 * MiB, "vpu_g1_decoder" },
+ [FSL_IMX8MM_USB2_OTG] = { 0x32e50200, 0x200, "usb2_otg" },
+ [FSL_IMX8MM_USB2] = { 0x32e50000, 0x200, "usb2" },
+ [FSL_IMX8MM_USB1_OTG] = { 0x32e40200, 0x200, "usb1_otg" },
+ [FSL_IMX8MM_USB1] = { 0x32e40000, 0x200, "usb1" },
+ [FSL_IMX8MM_GPU2D] = { 0x38000000, 64 * KiB, "gpu2d" },
+ [FSL_IMX8MM_QSPI1_RX_BUFFER] = { 0x34000000, 32 * MiB, "qspi1_rx_buffer" },
+ [FSL_IMX8MM_PCIE1] = { 0x33800000, 4 * MiB, "pcie1" },
+ [FSL_IMX8MM_QSPI1_TX_BUFFER] = { 0x33008000, 32 * KiB, "qspi1_tx_buffer" },
+ [FSL_IMX8MM_APBH_DMA] = { 0x33000000, 32 * KiB, "apbh_dma" },
+
+ /* AIPS-4 Begin */
+ [FSL_IMX8MM_TZASC] = { 0x32f80000, 64 * KiB, "tzasc" },
+ [FSL_IMX8MM_PCIE_PHY1] = { 0x32f00000, 64 * KiB, "pcie_phy1" },
+ [FSL_IMX8MM_MEDIA_BLK_CTL] = { 0x32e28000, 256, "media_blk_ctl" },
+ [FSL_IMX8MM_LCDIF] = { 0x32e00000, 64 * KiB, "lcdif" },
+ [FSL_IMX8MM_MIPI_DSI] = { 0x32e10000, 64 * KiB, "mipi_dsi" },
+ [FSL_IMX8MM_MIPI_CSI] = { 0x32e30000, 64 * KiB, "mipi_csi" },
+ [FSL_IMX8MM_AIPS4_CONFIGURATION] = { 0x32df0000, 64 * KiB, "aips4_configuration" },
+ /* AIPS-4 End */
+
+ [FSL_IMX8MM_INTERCONNECT] = { 0x32700000, 1 * MiB, "interconnect" },
+
+ /* AIPS-3 Begin */
+ [FSL_IMX8MM_ENET1] = { 0x30be0000, 64 * KiB, "enet1" },
+ [FSL_IMX8MM_SDMA1] = { 0x30bd0000, 64 * KiB, "sdma1" },
+ [FSL_IMX8MM_QSPI] = { 0x30bb0000, 64 * KiB, "qspi" },
+ [FSL_IMX8MM_USDHC3] = { 0x30b60000, 64 * KiB, "usdhc3" },
+ [FSL_IMX8MM_USDHC2] = { 0x30b50000, 64 * KiB, "usdhc2" },
+ [FSL_IMX8MM_USDHC1] = { 0x30b40000, 64 * KiB, "usdhc1" },
+ [FSL_IMX8MM_SEMAPHORE_HS] = { 0x30ac0000, 64 * KiB, "semaphore_hs" },
+ [FSL_IMX8MM_MU_B] = { 0x30ab0000, 64 * KiB, "mu_b" },
+ [FSL_IMX8MM_MU_A] = { 0x30aa0000, 64 * KiB, "mu_a" },
+ [FSL_IMX8MM_UART4] = { 0x30a60000, 64 * KiB, "uart4" },
+ [FSL_IMX8MM_I2C4] = { 0x30a50000, 64 * KiB, "i2c4" },
+ [FSL_IMX8MM_I2C3] = { 0x30a40000, 64 * KiB, "i2c3" },
+ [FSL_IMX8MM_I2C2] = { 0x30a30000, 64 * KiB, "i2c2" },
+ [FSL_IMX8MM_I2C1] = { 0x30a20000, 64 * KiB, "i2c1" },
+ [FSL_IMX8MM_AIPS3_CONFIGURATION] = { 0x309f0000, 64 * KiB, "aips3_configuration" },
+ [FSL_IMX8MM_CAAM] = { 0x30900000, 256 * KiB, "caam" },
+ [FSL_IMX8MM_SPBA1] = { 0x308f0000, 64 * KiB, "spba1" },
+ [FSL_IMX8MM_UART2] = { 0x30890000, 64 * KiB, "uart2" },
+ [FSL_IMX8MM_UART3] = { 0x30880000, 64 * KiB, "uart3" },
+ [FSL_IMX8MM_UART1] = { 0x30860000, 64 * KiB, "uart1" },
+ [FSL_IMX8MM_ECSPI3] = { 0x30840000, 64 * KiB, "ecspi3" },
+ [FSL_IMX8MM_ECSPI2] = { 0x30830000, 64 * KiB, "ecspi2" },
+ [FSL_IMX8MM_ECSPI1] = { 0x30820000, 64 * KiB, "ecspi1" },
+ /* AIPS-3 End */
+
+ /* AIPS-2 Begin */
+ [FSL_IMX8MM_QOSC] = { 0x307f0000, 64 * KiB, "qosc" },
+ [FSL_IMX8MM_PERFMON2] = { 0x307d0000, 64 * KiB, "perfmon2" },
+ [FSL_IMX8MM_PERFMON1] = { 0x307c0000, 64 * KiB, "perfmon1" },
+ [FSL_IMX8MM_GPT4] = { 0x30700000, 64 * KiB, "gpt4" },
+ [FSL_IMX8MM_GPT5] = { 0x306f0000, 64 * KiB, "gpt5" },
+ [FSL_IMX8MM_GPT6] = { 0x306e0000, 64 * KiB, "gpt6" },
+ [FSL_IMX8MM_SYSCNT_CTRL] = { 0x306c0000, 64 * KiB, "syscnt_ctrl" },
+ [FSL_IMX8MM_SYSCNT_CMP] = { 0x306b0000, 64 * KiB, "syscnt_cmp" },
+ [FSL_IMX8MM_SYSCNT_RD] = { 0x306a0000, 64 * KiB, "syscnt_rd" },
+ [FSL_IMX8MM_PWM4] = { 0x30690000, 64 * KiB, "pwm4" },
+ [FSL_IMX8MM_PWM3] = { 0x30680000, 64 * KiB, "pwm3" },
+ [FSL_IMX8MM_PWM2] = { 0x30670000, 64 * KiB, "pwm2" },
+ [FSL_IMX8MM_PWM1] = { 0x30660000, 64 * KiB, "pwm1" },
+ [FSL_IMX8MM_AIPS2_CONFIGURATION] = { 0x305f0000, 64 * KiB, "aips2_configuration" },
+ /* AIPS-2 End */
+
+ /* AIPS-1 Begin */
+ [FSL_IMX8MM_CSU] = { 0x303e0000, 64 * KiB, "csu" },
+ [FSL_IMX8MM_RDC] = { 0x303d0000, 64 * KiB, "rdc" },
+ [FSL_IMX8MM_SEMAPHORE2] = { 0x303c0000, 64 * KiB, "semaphore2" },
+ [FSL_IMX8MM_SEMAPHORE1] = { 0x303b0000, 64 * KiB, "semaphore1" },
+ [FSL_IMX8MM_GPC] = { 0x303a0000, 64 * KiB, "gpc" },
+ [FSL_IMX8MM_SRC] = { 0x30390000, 64 * KiB, "src" },
+ [FSL_IMX8MM_CCM] = { 0x30380000, 64 * KiB, "ccm" },
+ [FSL_IMX8MM_SNVS_HP] = { 0x30370000, 64 * KiB, "snvs_hp" },
+ [FSL_IMX8MM_ANA_PLL] = { 0x30360000, 64 * KiB, "ana_pll" },
+ [FSL_IMX8MM_OCOTP_CTRL] = { 0x30350000, 64 * KiB, "ocotp_ctrl" },
+ [FSL_IMX8MM_IOMUXC_GPR] = { 0x30340000, 64 * KiB, "iomuxc_gpr" },
+ [FSL_IMX8MM_IOMUXC] = { 0x30330000, 64 * KiB, "iomuxc" },
+ [FSL_IMX8MM_GPT3] = { 0x302f0000, 64 * KiB, "gpt3" },
+ [FSL_IMX8MM_GPT2] = { 0x302e0000, 64 * KiB, "gpt2" },
+ [FSL_IMX8MM_GPT1] = { 0x302d0000, 64 * KiB, "gpt1" },
+ [FSL_IMX8MM_SDMA2] = { 0x302c0000, 64 * KiB, "sdma2" },
+ [FSL_IMX8MM_SDMA3] = { 0x302b0000, 64 * KiB, "sdma3" },
+ [FSL_IMX8MM_WDOG3] = { 0x302a0000, 64 * KiB, "wdog3" },
+ [FSL_IMX8MM_WDOG2] = { 0x30290000, 64 * KiB, "wdog2" },
+ [FSL_IMX8MM_WDOG1] = { 0x30280000, 64 * KiB, "wdog1" },
+ [FSL_IMX8MM_ANA_OSC] = { 0x30270000, 64 * KiB, "ana_osc" },
+ [FSL_IMX8MM_ANA_TSENSOR] = { 0x30260000, 64 * KiB, "ana_tsensor" },
+ [FSL_IMX8MM_GPIO5] = { 0x30240000, 64 * KiB, "gpio5" },
+ [FSL_IMX8MM_GPIO4] = { 0x30230000, 64 * KiB, "gpio4" },
+ [FSL_IMX8MM_GPIO3] = { 0x30220000, 64 * KiB, "gpio3" },
+ [FSL_IMX8MM_GPIO2] = { 0x30210000, 64 * KiB, "gpio2" },
+ [FSL_IMX8MM_GPIO1] = { 0x30200000, 64 * KiB, "gpio1" },
+ [FSL_IMX8MM_AIPS1_CONFIGURATION] = { 0x301f0000, 64 * KiB, "aips1_configuration" },
+ [FSL_IMX8MM_SAI6] = { 0x30060000, 64 * KiB, "sai6" },
+ [FSL_IMX8MM_SAI5] = { 0x30050000, 64 * KiB, "sai5" },
+ [FSL_IMX8MM_SAI3] = { 0x30030000, 64 * KiB, "sai3" },
+ [FSL_IMX8MM_SAI2] = { 0x30020000, 64 * KiB, "sai2" },
+ [FSL_IMX8MM_SAI1] = { 0x30010000, 64 * KiB, "sai1" },
+
+ /* AIPS-1 End */
+
+ [FSL_IMX8MM_A53_DAP] = { 0x28000000, 16 * MiB, "a53_dap" },
+ [FSL_IMX8MM_PCIE1_MEM] = { 0x18000000, 128 * MiB, "pcie1_mem" },
+ [FSL_IMX8MM_QSPI_MEM] = { 0x08000000, 256 * MiB, "qspi_mem" },
+ [FSL_IMX8MM_OCRAM] = { 0x00900000, 256 * KiB, "ocram" },
+ [FSL_IMX8MM_TCM_DTCM] = { 0x00800000, 128 * KiB, "tcm_dtcm" },
+ [FSL_IMX8MM_TCM_ITCM] = { 0x007e0000, 128 * KiB, "tcm_itcm" },
+ [FSL_IMX8MM_OCRAM_S] = { 0x00180000, 32 * KiB, "ocram_s" },
+ [FSL_IMX8MM_CAAM_MEM] = { 0x00100000, 32 * KiB, "caam_mem" },
+ [FSL_IMX8MM_BOOT_ROM_PROTECTED] = { 0x0003f000, 4 * KiB, "boot_rom_protected" },
+ [FSL_IMX8MM_BOOT_ROM] = { 0x00000000, 252 * KiB, "boot_rom" },
+};
+
+static void fsl_imx8mm_init(Object *obj)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ FslImx8mmState *s = FSL_IMX8MM(obj);
+ const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53");
+ int i;
+
+ for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX8MM_NUM_CPUS); i++) {
+ g_autofree char *name = g_strdup_printf("cpu%d", i);
+ object_initialize_child(obj, name, &s->cpu[i], cpu_type);
+ }
+
+ object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+
+ for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
+ g_autofree char *name = g_strdup_printf("uart%d", i + 1);
+ object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
+ }
+
+}
+
+static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ FslImx8mmState *s = FSL_IMX8MM(dev);
+ DeviceState *gicdev = DEVICE(&s->gic);
+ int i;
+
+ if (ms->smp.cpus > FSL_IMX8MM_NUM_CPUS) {
+ error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
+ TYPE_FSL_IMX8MM, FSL_IMX8MM_NUM_CPUS, ms->smp.cpus);
+ return;
+ }
+
+ /* CPUs */
+ for (i = 0; i < ms->smp.cpus; i++) {
+ /* On uniprocessor, the CBAR is set to 0 */
+ if (ms->smp.cpus > 1 &&
+ object_property_find(OBJECT(&s->cpu[i]), "reset-cbar")) {
+ object_property_set_int(OBJECT(&s->cpu[i]), "reset-cbar",
+ fsl_imx8mm_memmap[FSL_IMX8MM_GIC_DIST].addr,
+ &error_abort);
+ }
+
+ /*
+ * CNTFID0 base frequency in Hz of system counter
+ */
+ object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 8000000,
+ &error_abort);
+
+ if (object_property_find(OBJECT(&s->cpu[i]), "has_el2")) {
+ object_property_set_bool(OBJECT(&s->cpu[i]), "has_el2",
+ !kvm_enabled(), &error_abort);
+ }
+
+ if (object_property_find(OBJECT(&s->cpu[i]), "has_el3")) {
+ object_property_set_bool(OBJECT(&s->cpu[i]), "has_el3",
+ !kvm_enabled(), &error_abort);
+ }
+
+ if (i) {
+ /*
+ * Secondary CPUs start in powered-down state (and can be
+ * powered up via the SRC system reset controller)
+ */
+ object_property_set_bool(OBJECT(&s->cpu[i]), "start-powered-off",
+ true, &error_abort);
+ }
+
+ if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
+ return;
+ }
+ }
+
+ /* GIC */
+ {
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&s->gic);
+ QList *redist_region_count;
+ bool pmu = object_property_get_bool(OBJECT(first_cpu), "pmu", NULL);
+
+ qdev_prop_set_uint32(gicdev, "num-cpu", ms->smp.cpus);
+ qdev_prop_set_uint32(gicdev, "num-irq",
+ FSL_IMX8MM_NUM_IRQS + GIC_INTERNAL);
+ redist_region_count = qlist_new();
+ qlist_append_int(redist_region_count, ms->smp.cpus);
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
+ object_property_set_link(OBJECT(&s->gic), "sysmem",
+ OBJECT(get_system_memory()), &error_fatal);
+ if (!sysbus_realize(gicsbd, errp)) {
+ return;
+ }
+ sysbus_mmio_map(gicsbd, 0, fsl_imx8mm_memmap[FSL_IMX8MM_GIC_DIST].addr);
+ sysbus_mmio_map(gicsbd, 1, fsl_imx8mm_memmap[FSL_IMX8MM_GIC_REDIST].addr);
+
+ /*
+ * Wire the outputs from each CPU's generic timer and the GICv3
+ * maintenance interrupt signal to the appropriate GIC PPI inputs, and
+ * the GIC's IRQ/FIQ interrupt outputs to the CPU's inputs.
+ */
+ for (i = 0; i < ms->smp.cpus; i++) {
+ DeviceState *cpudev = DEVICE(&s->cpu[i]);
+ int intidbase = FSL_IMX8MM_NUM_IRQS + i * GIC_INTERNAL;
+ qemu_irq irq;
+
+ /*
+ * Mapping from the output timer irq lines from the CPU to the
+ * GIC PPI inputs.
+ */
+ static const int timer_irqs[] = {
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
+ };
+
+ for (int j = 0; j < ARRAY_SIZE(timer_irqs); j++) {
+ irq = qdev_get_gpio_in(gicdev, intidbase + timer_irqs[j]);
+ qdev_connect_gpio_out(cpudev, j, irq);
+ }
+
+ irq = qdev_get_gpio_in(gicdev, intidbase + ARCH_GIC_MAINT_IRQ);
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
+ 0, irq);
+
+ irq = qdev_get_gpio_in(gicdev, intidbase + VIRTUAL_PMU_IRQ);
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, irq);
+
+ sysbus_connect_irq(gicsbd, i,
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+ sysbus_connect_irq(gicsbd, i + ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+ sysbus_connect_irq(gicsbd, i + 2 * ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+ sysbus_connect_irq(gicsbd, i + 3 * ms->smp.cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+
+ if (kvm_enabled()) {
+ if (pmu) {
+ assert(arm_feature(&s->cpu[i].env, ARM_FEATURE_PMU));
+ if (kvm_irqchip_in_kernel()) {
+ kvm_arm_pmu_set_irq(&s->cpu[i], VIRTUAL_PMU_IRQ);
+ }
+ kvm_arm_pmu_init(&s->cpu[i]);
+ }
+ }
+ }
+ }
+
+ /* UARTs */
+ for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } serial_table[FSL_IMX8MM_NUM_UARTS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART1].addr, FSL_IMX8MM_UART1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART2].addr, FSL_IMX8MM_UART2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART3].addr, FSL_IMX8MM_UART3_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_UART4].addr, FSL_IMX8MM_UART4_IRQ },
+ };
+
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+ qdev_get_gpio_in(gicdev, serial_table[i].irq));
+ }
+
+ /* Unimplemented devices */
+ for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
+ switch (i) {
+ case FSL_IMX8MM_GIC_DIST:
+ case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_RAM:
+ case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ /* device implemented and treated above */
+ break;
+
+ default:
+ create_unimplemented_device(fsl_imx8mm_memmap[i].name,
+ fsl_imx8mm_memmap[i].addr,
+ fsl_imx8mm_memmap[i].size);
+ break;
+ }
+ }
+}
+
+static void fsl_imx8mm_class_init(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = fsl_imx8mm_realize;
+
+ dc->desc = "i.MX 8MM SoC";
+}
+
+static const TypeInfo fsl_imx8mm_types[] = {
+ {
+ .name = TYPE_FSL_IMX8MM,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(FslImx8mmState),
+ .instance_init = fsl_imx8mm_init,
+ .class_init = fsl_imx8mm_class_init,
+ },
+};
+
+DEFINE_TYPES(fsl_imx8mm_types)
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
new file mode 100644
index 0000000000..ffc69f1050
--- /dev/null
+++ b/hw/arm/imx8mm-evk.c
@@ -0,0 +1,110 @@
+/*
+ * NXP i.MX 8MM Evaluation Kit System Emulation
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "system/address-spaces.h"
+#include "hw/arm/boot.h"
+#include "hw/arm/fsl-imx8mm.h"
+#include "hw/arm/machines-qom.h"
+#include "hw/boards.h"
+#include "hw/qdev-properties.h"
+#include "system/kvm.h"
+#include "system/qtest.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include <libfdt.h>
+
+static void imx8mm_evk_modify_dtb(const struct arm_boot_info *info, void *fdt)
+{
+ int i, offset;
+
+ /* Temporarily disable following nodes until they are implemented */
+ const char *nodes_to_remove[] = {
+ "nxp,imx8mm-fspi",
+ "fsl,imx8mm-mipi-csi",
+ "fsl,imx8mm-mipi-dsim"
+ };
+
+ for (i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) {
+ const char *dev_str = nodes_to_remove[i];
+
+ offset = fdt_node_offset_by_compatible(fdt, -1, dev_str);
+ while (offset >= 0) {
+ fdt_nop_node(fdt, offset);
+ offset = fdt_node_offset_by_compatible(fdt, offset, dev_str);
+ }
+ }
+
+ /* Remove cpu-idle-states property from CPU nodes */
+ offset = fdt_node_offset_by_compatible(fdt, -1, "arm,cortex-a53");
+ while (offset >= 0) {
+ fdt_nop_property(fdt, offset, "cpu-idle-states");
+ offset = fdt_node_offset_by_compatible(fdt, offset, "arm,cortex-a53");
+ }
+
+ if (kvm_enabled()) {
+ /* Use system counter frequency from host CPU to fix time in guest */
+ offset = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
+ while (offset >= 0) {
+ fdt_nop_property(fdt, offset, "clock-frequency");
+ offset = fdt_node_offset_by_compatible(fdt, offset, "arm,armv8-timer");
+ }
+ }
+}
+
+static void imx8mm_evk_init(MachineState *machine)
+{
+ static struct arm_boot_info boot_info;
+ FslImx8mmState *s;
+
+ if (machine->ram_size > FSL_IMX8MM_RAM_SIZE_MAX) {
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08" PRIx64 ")",
+ machine->ram_size, FSL_IMX8MM_RAM_SIZE_MAX);
+ exit(1);
+ }
+
+ boot_info = (struct arm_boot_info) {
+ .loader_start = FSL_IMX8MM_RAM_START,
+ .board_id = -1,
+ .ram_size = machine->ram_size,
+ .psci_conduit = QEMU_PSCI_CONDUIT_SMC,
+ .modify_dtb = imx8mm_evk_modify_dtb,
+ };
+
+ s = FSL_IMX8MM(object_new(TYPE_FSL_IMX8MM));
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
+
+ memory_region_add_subregion(get_system_memory(), FSL_IMX8MM_RAM_START,
+ machine->ram);
+
+ if (!qtest_enabled()) {
+ arm_load_kernel(&s->cpu[0], machine, &boot_info);
+ }
+}
+
+static const char *imx8mm_evk_get_default_cpu_type(const MachineState *ms)
+{
+ if (kvm_enabled()) {
+ return ARM_CPU_TYPE_NAME("host");
+ }
+
+ return ARM_CPU_TYPE_NAME("cortex-a53");
+}
+
+static void imx8mm_evk_machine_init(MachineClass *mc)
+{
+ mc->desc = "NXP i.MX 8MM EVK Board";
+ mc->init = imx8mm_evk_init;
+ mc->max_cpus = FSL_IMX8MM_NUM_CPUS;
+ mc->default_ram_id = "imx8mm-evk.ram";
+ mc->get_default_cpu_type = imx8mm_evk_get_default_cpu_type;
+}
+
+DEFINE_MACHINE_AARCH64("imx8mm-evk", imx8mm_evk_machine_init)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index aeaf654790..12ecb824cc 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -84,6 +84,8 @@ arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c'))
+arm_common_ss.add(when: 'CONFIG_FSL_IMX8MM', if_true: files('fsl-imx8mm.c'))
+arm_common_ss.add(when: 'CONFIG_FSL_IMX8MM_EVK', if_true: files('imx8mm-evk.c'))
arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c'))
arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
new file mode 100644
index 0000000000..133f519b7c
--- /dev/null
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -0,0 +1,157 @@
+/*
+ * i.MX 8MM SoC Definitions
+ *
+ * Copyright (c) 2025, NXP Semiconductors
+ * Author: Gaurav Sharma <gaurav.sharma_7@nxp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef FSL_IMX8MM_H
+#define FSL_IMX8MM_H
+
+#include "cpu.h"
+#include "hw/char/imx_serial.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "qom/object.h"
+#include "qemu/units.h"
+
+#define TYPE_FSL_IMX8MM "fsl-imx8mm"
+OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
+
+#define FSL_IMX8MM_RAM_START 0x40000000
+#define FSL_IMX8MM_RAM_SIZE_MAX (4 * GiB)
+
+enum FslImx8mmConfiguration {
+ FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_IRQS = 128,
+ FSL_IMX8MM_NUM_UARTS = 4,
+};
+
+struct FslImx8mmState {
+ SysBusDevice parent_obj;
+
+ ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
+ GICv3State gic;
+ IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
+};
+
+enum FslImx8mmMemoryRegions {
+ FSL_IMX8MM_A53_DAP,
+ FSL_IMX8MM_AIPS1_CONFIGURATION,
+ FSL_IMX8MM_AIPS2_CONFIGURATION,
+ FSL_IMX8MM_AIPS3_CONFIGURATION,
+ FSL_IMX8MM_AIPS4_CONFIGURATION,
+ FSL_IMX8MM_ANA_OSC,
+ FSL_IMX8MM_ANA_PLL,
+ FSL_IMX8MM_ANA_TSENSOR,
+ FSL_IMX8MM_APBH_DMA,
+ FSL_IMX8MM_BOOT_ROM,
+ FSL_IMX8MM_BOOT_ROM_PROTECTED,
+ FSL_IMX8MM_CAAM,
+ FSL_IMX8MM_CAAM_MEM,
+ FSL_IMX8MM_CCM,
+ FSL_IMX8MM_CSU,
+ FSL_IMX8MM_DDR_CTL,
+ FSL_IMX8MM_DDR_PERF_MON,
+ FSL_IMX8MM_DDR_PHY,
+ FSL_IMX8MM_DDR_PHY_BROADCAST,
+ FSL_IMX8MM_ECSPI1,
+ FSL_IMX8MM_ECSPI2,
+ FSL_IMX8MM_ECSPI3,
+ FSL_IMX8MM_ENET1,
+ FSL_IMX8MM_GIC_DIST,
+ FSL_IMX8MM_GIC_REDIST,
+ FSL_IMX8MM_GPC,
+ FSL_IMX8MM_GPIO1,
+ FSL_IMX8MM_GPIO2,
+ FSL_IMX8MM_GPIO3,
+ FSL_IMX8MM_GPIO4,
+ FSL_IMX8MM_GPIO5,
+ FSL_IMX8MM_GPT1,
+ FSL_IMX8MM_GPT2,
+ FSL_IMX8MM_GPT3,
+ FSL_IMX8MM_GPT4,
+ FSL_IMX8MM_GPT5,
+ FSL_IMX8MM_GPT6,
+ FSL_IMX8MM_GPU2D,
+ FSL_IMX8MM_I2C1,
+ FSL_IMX8MM_I2C2,
+ FSL_IMX8MM_I2C3,
+ FSL_IMX8MM_I2C4,
+ FSL_IMX8MM_INTERCONNECT,
+ FSL_IMX8MM_IOMUXC,
+ FSL_IMX8MM_IOMUXC_GPR,
+ FSL_IMX8MM_MEDIA_BLK_CTL,
+ FSL_IMX8MM_LCDIF,
+ FSL_IMX8MM_MIPI_CSI,
+ FSL_IMX8MM_MIPI_DSI,
+ FSL_IMX8MM_MU_A,
+ FSL_IMX8MM_MU_B,
+ FSL_IMX8MM_OCOTP_CTRL,
+ FSL_IMX8MM_OCRAM,
+ FSL_IMX8MM_OCRAM_S,
+ FSL_IMX8MM_PCIE1,
+ FSL_IMX8MM_PCIE1_MEM,
+ FSL_IMX8MM_PCIE_PHY1,
+ FSL_IMX8MM_PERFMON1,
+ FSL_IMX8MM_PERFMON2,
+ FSL_IMX8MM_PWM1,
+ FSL_IMX8MM_PWM2,
+ FSL_IMX8MM_PWM3,
+ FSL_IMX8MM_PWM4,
+ FSL_IMX8MM_QOSC,
+ FSL_IMX8MM_QSPI,
+ FSL_IMX8MM_QSPI1_RX_BUFFER,
+ FSL_IMX8MM_QSPI1_TX_BUFFER,
+ FSL_IMX8MM_QSPI_MEM,
+ FSL_IMX8MM_RAM,
+ FSL_IMX8MM_RDC,
+ FSL_IMX8MM_SAI1,
+ FSL_IMX8MM_SAI2,
+ FSL_IMX8MM_SAI3,
+ FSL_IMX8MM_SAI5,
+ FSL_IMX8MM_SAI6,
+ FSL_IMX8MM_SDMA1,
+ FSL_IMX8MM_SDMA2,
+ FSL_IMX8MM_SDMA3,
+ FSL_IMX8MM_SEMAPHORE1,
+ FSL_IMX8MM_SEMAPHORE2,
+ FSL_IMX8MM_SEMAPHORE_HS,
+ FSL_IMX8MM_SNVS_HP,
+ FSL_IMX8MM_SPBA1,
+ FSL_IMX8MM_SRC,
+ FSL_IMX8MM_SYSCNT_CMP,
+ FSL_IMX8MM_SYSCNT_CTRL,
+ FSL_IMX8MM_SYSCNT_RD,
+ FSL_IMX8MM_TCM_DTCM,
+ FSL_IMX8MM_TCM_ITCM,
+ FSL_IMX8MM_TZASC,
+ FSL_IMX8MM_UART1,
+ FSL_IMX8MM_UART2,
+ FSL_IMX8MM_UART3,
+ FSL_IMX8MM_UART4,
+ FSL_IMX8MM_USB1,
+ FSL_IMX8MM_USB2,
+ FSL_IMX8MM_USB1_OTG,
+ FSL_IMX8MM_USB2_OTG,
+ FSL_IMX8MM_USDHC1,
+ FSL_IMX8MM_USDHC2,
+ FSL_IMX8MM_USDHC3,
+ FSL_IMX8MM_VPU,
+ FSL_IMX8MM_VPU_BLK_CTRL,
+ FSL_IMX8MM_VPU_G1_DECODER,
+ FSL_IMX8MM_VPU_G2_DECODER,
+ FSL_IMX8MM_WDOG1,
+ FSL_IMX8MM_WDOG2,
+ FSL_IMX8MM_WDOG3,
+};
+
+enum FslImx8mmIrqs {
+ FSL_IMX8MM_UART1_IRQ = 26,
+ FSL_IMX8MM_UART2_IRQ = 27,
+ FSL_IMX8MM_UART3_IRQ = 28,
+ FSL_IMX8MM_UART4_IRQ = 29,
+};
+
+#endif /* FSL_IMX8MM_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 02/15] hw/misc/imx8mp_analog: Add property to analog device
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 01/15] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 03/15] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Gaurav Sharma
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Add configurable properties for register reset values that differ
between i.MX 8M variants (Plus, Mini, etc.). This allows the same
device implementation to be shared across multiple SoCs.
Properties added:
- arm-pll-fdiv-ctl0-reset: ARM PLL divider control reset value
Default value is set to match i.MX 8MP reset value (0x000FA031).
This can be overridden in the variant like iMX8MM with its own
reset value.
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
hw/misc/imx8mp_analog.c | 12 +++++++++++-
include/hw/misc/imx8mp_analog.h | 3 +++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/hw/misc/imx8mp_analog.c b/hw/misc/imx8mp_analog.c
index 23ffae84f8..7c904d77f4 100644
--- a/hw/misc/imx8mp_analog.c
+++ b/hw/misc/imx8mp_analog.c
@@ -12,6 +12,7 @@
#include "qemu/log.h"
#include "hw/misc/imx8mp_analog.h"
+#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#define ANALOG_PLL_LOCK BIT(31)
@@ -51,7 +52,10 @@ static void imx8mp_analog_reset(DeviceState *dev)
s->analog[ANALOG_VPU_PLL_LOCKD_CTRL] = 0x0010003f;
s->analog[ANALOG_VPU_PLL_MNIT_CTRL] = 0x00280081;
s->analog[ANALOG_ARM_PLL_GEN_CTRL] = 0x00000810;
- s->analog[ANALOG_ARM_PLL_FDIV_CTL0] = 0x000fa031;
+
+ /* Use property value instead of hardcoded */
+ s->analog[ANALOG_ARM_PLL_FDIV_CTL0] = s->arm_pll_fdiv_ctl0_reset;
+
s->analog[ANALOG_ARM_PLL_LOCKD_CTRL] = 0x0010003f;
s->analog[ANALOG_ARM_PLL_MNIT_CTRL] = 0x00280081;
s->analog[ANALOG_SYS_PLL1_GEN_CTRL] = 0x0aaaa810;
@@ -138,11 +142,17 @@ static const VMStateDescription imx8mp_analog_vmstate = {
},
};
+static const Property imx8mp_analog_properties[] = {
+ DEFINE_PROP_UINT32("arm-pll-fdiv-ctl0-reset", IMX8MPAnalogState,
+ arm_pll_fdiv_ctl0_reset, 0x000fa031), /* imx8mp default */
+};
+
static void imx8mp_analog_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_legacy_reset(dc, imx8mp_analog_reset);
+ device_class_set_props(dc, imx8mp_analog_properties);
dc->vmsd = &imx8mp_analog_vmstate;
dc->desc = "i.MX 8M Plus Analog Module";
}
diff --git a/include/hw/misc/imx8mp_analog.h b/include/hw/misc/imx8mp_analog.h
index 955f03215a..b313820392 100644
--- a/include/hw/misc/imx8mp_analog.h
+++ b/include/hw/misc/imx8mp_analog.h
@@ -76,6 +76,9 @@ struct IMX8MPAnalogState {
} mmio;
uint32_t analog[ANALOG_MAX];
+
+ /* Property for variant-specific reset values */
+ uint32_t arm_pll_fdiv_ctl0_reset;
};
#endif /* IMX8MP_ANALOG_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 03/15] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 01/15] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 02/15] hw/misc/imx8mp_analog: Add property to analog device Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 04/15] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Gaurav Sharma
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Add the Analog IP to i.MX8MM SoC. iMX8MM and i.MX8MP uses
the same Analog IP so the analog ip source will be shared.
The ARM PLL divider control register (arm-pll-fdiv-ctl0) has
a different reset value on i.MX8MM (0x000fa030) compared to
i.MX8MP (0x000fa031). So iMX8MM will be overriding this property
with its own reset-value.
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 12 ++++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
3 files changed, 15 insertions(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index be38c67a1c..3737335841 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -629,6 +629,7 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
select ARM_GIC
+ select FSL_IMX8MP_ANALOG
select IMX
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index fb6a78adba..2c84e70c01 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -169,6 +169,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+ object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
+
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
g_autofree char *name = g_strdup_printf("uart%d", i + 1);
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
@@ -303,6 +305,15 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+ /* Analog */
+ object_property_set_uint(OBJECT(&s->analog), "arm-pll-fdiv-ctl0-reset",
+ 0x000fa030, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->analog), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_ANA_PLL].addr);
+
/* UARTs */
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
static const struct {
@@ -328,6 +339,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
+ case FSL_IMX8MM_ANA_PLL:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 133f519b7c..4601f57f2b 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/imx8mp_analog.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -33,6 +34,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMX8MPAnalogState analog;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 04/15] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (2 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 03/15] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 05/15] hw/arm/fsl-imx8mm: Implemented support for SNVS Gaurav Sharma
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Add the Clock Control Module (CCM) device to i.MX8MM SoC.
The CCM implementation is shared with i.MX8MP as the register
layout is identical between the two variants.Hence iMX8MM will
be using the source of iMX8MP CCM.
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 10 ++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
4 files changed, 14 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 408253193c..09aa63240a 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -12,6 +12,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* Up to 4 Cortex-A53 cores
* Generic Interrupt Controller (GICv3)
* 4 UARTs
+ * Clock Tree
Boot options
------------
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 3737335841..758addea22 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -630,6 +630,7 @@ config FSL_IMX8MM
bool
select ARM_GIC
select FSL_IMX8MP_ANALOG
+ select FSL_IMX8MP_CCM
select IMX
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 2c84e70c01..a3eddfe3f6 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -169,6 +169,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "gic", &s->gic, gicv3_class_name());
+ object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX8MP_CCM);
+
object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
@@ -305,6 +307,13 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+ /* CCM */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_CCM].addr);
+
/* Analog */
object_property_set_uint(OBJECT(&s->analog), "arm-pll-fdiv-ctl0-reset",
0x000fa030, &error_abort);
@@ -340,6 +349,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
case FSL_IMX8MM_ANA_PLL:
+ case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 4601f57f2b..03ab45d94e 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -14,6 +14,7 @@
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx8mp_analog.h"
+#include "hw/misc/imx8mp_ccm.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -34,6 +35,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 05/15] hw/arm/fsl-imx8mm: Implemented support for SNVS
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (3 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 04/15] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 06/15] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Gaurav Sharma
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
SNVS contains an RTC which allows Linux to deal correctly with time
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/fsl-imx8mm.c | 10 ++++++++++
include/hw/arm/fsl-imx8mm.h | 2 ++
3 files changed, 13 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 09aa63240a..231dae6624 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -12,6 +12,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* Up to 4 Cortex-A53 cores
* Generic Interrupt Controller (GICv3)
* 4 UARTs
+ * Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
Boot options
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index a3eddfe3f6..fb7df84cef 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -173,6 +173,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, "analog", &s->analog, TYPE_IMX8MP_ANALOG);
+ object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
+
for (i = 0; i < FSL_IMX8MM_NUM_UARTS; i++) {
g_autofree char *name = g_strdup_printf("uart%d", i + 1);
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
@@ -345,6 +347,13 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
}
+ /* SNVS */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
@@ -353,6 +362,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_RAM:
+ case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
/* device implemented and treated above */
break;
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 03ab45d94e..9f4925eb87 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
#include "qom/object.h"
@@ -37,6 +38,7 @@ struct FslImx8mmState {
GICv3State gic;
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
+ IMX7SNVSState snvs;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
};
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 06/15] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (4 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 05/15] hw/arm/fsl-imx8mm: Implemented support for SNVS Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 07/15] hw/arm/fsl-imx8mm: Add PCIe support Gaurav Sharma
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
It enables emulation of SD/MMC cards through a virtual SDHCI interface
The emulated SDHCI controller allows guest OS to use emulated storage as
a standard block device.
This will allow running the images such as those generated
by Buildroot.
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 25 +++++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 17 +++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
5 files changed, 51 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 231dae6624..f379a1cc97 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -12,6 +12,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* Up to 4 Cortex-A53 cores
* Generic Interrupt Controller (GICv3)
* 4 UARTs
+ * 3 USDHC Storage Controllers
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 758addea22..e7fe4af968 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -632,6 +632,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select SDHCI
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index fb7df84cef..e770217017 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,10 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
+ object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
+ }
}
static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
@@ -347,6 +351,26 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
}
+ /* USDHCs */
+ for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } usdhc_table[FSL_IMX8MM_NUM_USDHCS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC1].addr, FSL_IMX8MM_USDHC1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC2].addr, FSL_IMX8MM_USDHC2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USDHC3].addr, FSL_IMX8MM_USDHC3_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, usdhc_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
+ qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
+ }
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -364,6 +388,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_RAM:
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
/* device implemented and treated above */
break;
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
index ffc69f1050..2ecef38210 100644
--- a/hw/arm/imx8mm-evk.c
+++ b/hw/arm/imx8mm-evk.c
@@ -84,6 +84,23 @@ static void imx8mm_evk_init(MachineState *machine)
memory_region_add_subregion(get_system_memory(), FSL_IMX8MM_RAM_START,
machine->ram);
+ for (int i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
+ BusState *bus;
+ DeviceState *carddev;
+ BlockBackend *blk;
+ DriveInfo *di = drive_get(IF_SD, i, 0);
+
+ if (!di) {
+ continue;
+ }
+
+ blk = blk_by_legacy_dinfo(di);
+ bus = qdev_get_child_bus(DEVICE(&s->usdhc[i]), "sd-bus");
+ carddev = qdev_new(TYPE_SD_CARD);
+ qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
+ qdev_realize_and_unref(carddev, bus, &error_fatal);
+ }
+
if (!qtest_enabled()) {
arm_load_kernel(&s->cpu[0], machine, &boot_info);
}
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 9f4925eb87..75cd9a64a1 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -16,6 +16,7 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/sd/sdhci.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -29,6 +30,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
+ FSL_IMX8MM_NUM_USDHCS = 3,
};
struct FslImx8mmState {
@@ -40,6 +42,7 @@ struct FslImx8mmState {
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
+ SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
};
enum FslImx8mmMemoryRegions {
@@ -154,6 +157,10 @@ enum FslImx8mmMemoryRegions {
};
enum FslImx8mmIrqs {
+ FSL_IMX8MM_USDHC1_IRQ = 22,
+ FSL_IMX8MM_USDHC2_IRQ = 23,
+ FSL_IMX8MM_USDHC3_IRQ = 24,
+
FSL_IMX8MM_UART1_IRQ = 26,
FSL_IMX8MM_UART2_IRQ = 27,
FSL_IMX8MM_UART3_IRQ = 28,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 07/15] hw/arm/fsl-imx8mm: Add PCIe support
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (5 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 06/15] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 08/15] hw/arm/fsl-imx8mm: Add GPIO controllers Gaurav Sharma
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
This enables support for Designware PCI Express Controller emulation
It provides a controlled environment to debug the linux pci subsystem
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 3 +++
hw/arm/fsl-imx8mm.c | 30 ++++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 10 ++++++++++
4 files changed, 44 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index f379a1cc97..cabaef157e 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -13,6 +13,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* Generic Interrupt Controller (GICv3)
* 4 UARTs
* 3 USDHC Storage Controllers
+ * 1 Designware PCI Express Controller
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e7fe4af968..045649516f 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -628,11 +628,14 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
+ imply PCI_DEVICES
select ARM_GIC
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
select SDHCI
+ select PCI_EXPRESS_DESIGNWARE
+ select PCI_EXPRESS_FSL_IMX8M_PHY
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index e770217017..f142dea805 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -184,6 +184,10 @@ static void fsl_imx8mm_init(Object *obj)
g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+
+ object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
+ object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
+ TYPE_FSL_IMX8M_PCIE_PHY);
}
static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
@@ -378,6 +382,30 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+ /* PCIe */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_PCIE1].addr);
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTA_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTB_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTC_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_INTD_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_PCI_MSI_IRQ));
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie_phy), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_PCIE_PHY1].addr);
+
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mm_memmap); i++) {
switch (i) {
@@ -385,6 +413,8 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_PCIE1:
+ case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 75cd9a64a1..183c8ef80e 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -16,6 +16,8 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/pci-host/designware.h"
+#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -43,6 +45,8 @@ struct FslImx8mmState {
IMX7SNVSState snvs;
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
+ DesignwarePCIEHost pcie;
+ FslImx8mPciePhyState pcie_phy;
};
enum FslImx8mmMemoryRegions {
@@ -165,6 +169,12 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART2_IRQ = 27,
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+
+ FSL_IMX8MM_PCI_INTA_IRQ = 122,
+ FSL_IMX8MM_PCI_INTB_IRQ = 123,
+ FSL_IMX8MM_PCI_INTC_IRQ = 124,
+ FSL_IMX8MM_PCI_INTD_IRQ = 125,
+ FSL_IMX8MM_PCI_MSI_IRQ = 127,
};
#endif /* FSL_IMX8MM_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 08/15] hw/arm/fsl-imx8mm: Add GPIO controllers
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (6 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 07/15] hw/arm/fsl-imx8mm: Add PCIe support Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 09/15] hw/arm/fsl-imx8mm: Adding support for I2C emulation Gaurav Sharma
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
Enabled GPIO controller emulation
Also updated the GPIO IRQ lines of iMX8MM
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/fsl-imx8mm.c | 54 ++++++++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 14 +++++++++
3 files changed, 69 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index cabaef157e..809ff0bdb8 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -14,6 +14,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 4 UARTs
* 3 USDHC Storage Controllers
* 1 Designware PCI Express Controller
+ * 5 GPIO Controllers
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index f142dea805..2dee5da5a1 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
+ g_autofree char *name = g_strdup_printf("gpio%d", i + 1);
+ object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
+ }
+
for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
g_autofree char *name = g_strdup_printf("usdhc%d", i + 1);
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
@@ -355,6 +360,54 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
}
+ /* GPIOs */
+ for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq_low;
+ unsigned int irq_high;
+ } gpio_table[FSL_IMX8MM_NUM_GPIOS] = {
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO1].addr,
+ FSL_IMX8MM_GPIO1_LOW_IRQ,
+ FSL_IMX8MM_GPIO1_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO2].addr,
+ FSL_IMX8MM_GPIO2_LOW_IRQ,
+ FSL_IMX8MM_GPIO2_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO3].addr,
+ FSL_IMX8MM_GPIO3_LOW_IRQ,
+ FSL_IMX8MM_GPIO3_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO4].addr,
+ FSL_IMX8MM_GPIO4_LOW_IRQ,
+ FSL_IMX8MM_GPIO4_HIGH_IRQ
+ },
+ {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPIO5].addr,
+ FSL_IMX8MM_GPIO5_LOW_IRQ,
+ FSL_IMX8MM_GPIO5_HIGH_IRQ
+ },
+ };
+ object_property_set_bool(OBJECT(&s->gpio[i]), "has-edge-sel", true,
+ &error_abort);
+ object_property_set_bool(OBJECT(&s->gpio[i]), "has-upper-pin-irq",
+ true, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
+ qdev_get_gpio_in(gicdev, gpio_table[i].irq_low));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
+ qdev_get_gpio_in(gicdev, gpio_table[i].irq_high));
+ }
+
/* USDHCs */
for (i = 0; i < FSL_IMX8MM_NUM_USDHCS; i++) {
static const struct {
@@ -413,6 +466,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_CCM:
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
+ case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 183c8ef80e..7e48760e19 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -12,6 +12,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
+#include "hw/gpio/imx_gpio.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
@@ -30,6 +31,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_GPIOS = 5,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
@@ -40,6 +42,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMXGPIOState gpio[FSL_IMX8MM_NUM_GPIOS];
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
@@ -170,6 +173,17 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
+ FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
+ FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
+ FSL_IMX8MM_GPIO2_HIGH_IRQ = 67,
+ FSL_IMX8MM_GPIO3_LOW_IRQ = 68,
+ FSL_IMX8MM_GPIO3_HIGH_IRQ = 69,
+ FSL_IMX8MM_GPIO4_LOW_IRQ = 70,
+ FSL_IMX8MM_GPIO4_HIGH_IRQ = 71,
+ FSL_IMX8MM_GPIO5_LOW_IRQ = 72,
+ FSL_IMX8MM_GPIO5_HIGH_IRQ = 73,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 09/15] hw/arm/fsl-imx8mm: Adding support for I2C emulation
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (7 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 08/15] hw/arm/fsl-imx8mm: Add GPIO controllers Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 10/15] hw/arm/fsl-imx8mm: Adding support for SPI controller Gaurav Sharma
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
This can be used to test and debug I2C device drivers.
Added I2C interrupts
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 2 ++
hw/arm/fsl-imx8mm.c | 27 +++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 8 ++++++++
4 files changed, 38 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 809ff0bdb8..8500430d03 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -15,6 +15,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 3 USDHC Storage Controllers
* 1 Designware PCI Express Controller
* 5 GPIO Controllers
+ * 6 I2C Controllers
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 045649516f..43f27735ad 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -629,10 +629,12 @@ config FSL_IMX8MP_EVK
config FSL_IMX8MM
bool
imply PCI_DEVICES
+ imply I2C_DEVICES
select ARM_GIC
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select IMX_I2C
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 2dee5da5a1..96e9f9f56a 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
+ g_autofree char *name = g_strdup_printf("i2c%d", i + 1);
+ object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
+ }
+
for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
g_autofree char *name = g_strdup_printf("gpio%d", i + 1);
object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
@@ -360,6 +365,27 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
}
+ /* I2Cs */
+ for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } i2c_table[FSL_IMX8MM_NUM_I2CS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C1].addr, FSL_IMX8MM_I2C1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C2].addr, FSL_IMX8MM_I2C2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C3].addr, FSL_IMX8MM_I2C3_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_I2C4].addr, FSL_IMX8MM_I2C4_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+ qdev_get_gpio_in(gicdev, i2c_table[i].irq));
+ }
+
/* GPIOs */
for (i = 0; i < FSL_IMX8MM_NUM_GPIOS; i++) {
static const struct {
@@ -467,6 +493,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
+ case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
case FSL_IMX8MM_RAM:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 7e48760e19..16effacc43 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -13,6 +13,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/gpio/imx_gpio.h"
+#include "hw/i2c/imx_i2c.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
@@ -32,6 +33,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_GPIOS = 5,
+ FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
@@ -46,6 +48,7 @@ struct FslImx8mmState {
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
+ IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
DesignwarePCIEHost pcie;
@@ -173,6 +176,11 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_I2C1_IRQ = 35,
+ FSL_IMX8MM_I2C2_IRQ = 36,
+ FSL_IMX8MM_I2C3_IRQ = 37,
+ FSL_IMX8MM_I2C4_IRQ = 38,
+
FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 10/15] hw/arm/fsl-imx8mm: Adding support for SPI controller
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (8 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 09/15] hw/arm/fsl-imx8mm: Adding support for I2C emulation Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 11/15] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Gaurav Sharma
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
It enables emulation of ECSPI in iMX8MM
Added SPI IRQ lines
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/fsl-imx8mm.c | 26 ++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
3 files changed, 34 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 8500430d03..fb74950e28 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -16,6 +16,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 1 Designware PCI Express Controller
* 5 GPIO Controllers
* 6 I2C Controllers
+ * 3 SPI Controllers
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 96e9f9f56a..6b5b769733 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -195,6 +195,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+ for (i = 0; i < FSL_IMX8MM_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);
+ }
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -454,6 +459,26 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
}
+ /* ECSPIs */
+ for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } spi_table[FSL_IMX8MM_NUM_ECSPIS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI1].addr, FSL_IMX8MM_ECSPI1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI2].addr, FSL_IMX8MM_ECSPI2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_ECSPI3].addr, FSL_IMX8MM_ECSPI3_IRQ },
+ };
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ qdev_get_gpio_in(gicdev, spi_table[i].irq));
+ }
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -493,6 +518,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_DIST:
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
+ case FSL_IMX8MM_ECSPI1 ... FSL_IMX8MM_ECSPI3:
case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 16effacc43..33fbfb72da 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -21,6 +21,7 @@
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -32,6 +33,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mmState, FSL_IMX8MM)
enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
+ FSL_IMX8MM_NUM_ECSPIS = 3,
FSL_IMX8MM_NUM_GPIOS = 5,
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
@@ -48,6 +50,7 @@ struct FslImx8mmState {
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
IMX7SNVSState snvs;
+ IMXSPIState spi[FSL_IMX8MM_NUM_ECSPIS];
IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
@@ -176,6 +179,10 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_UART3_IRQ = 28,
FSL_IMX8MM_UART4_IRQ = 29,
+ FSL_IMX8MM_ECSPI1_IRQ = 31,
+ FSL_IMX8MM_ECSPI2_IRQ = 32,
+ FSL_IMX8MM_ECSPI3_IRQ = 33,
+
FSL_IMX8MM_I2C1_IRQ = 35,
FSL_IMX8MM_I2C2_IRQ = 36,
FSL_IMX8MM_I2C3_IRQ = 37,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 11/15] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (9 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 10/15] hw/arm/fsl-imx8mm: Adding support for SPI controller Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 12/15] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Gaurav Sharma
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
It enables emulation of WDT in iMX8MM
Added WDT IRQ lines
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 28 ++++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 7 +++++++
4 files changed, 37 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index fb74950e28..b7034ff472 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -17,6 +17,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 5 GPIO Controllers
* 6 I2C Controllers
* 3 SPI Controllers
+ * 3 Watchdogs
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 43f27735ad..b757557ac7 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -638,6 +638,7 @@ config FSL_IMX8MM
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
+ select WDT_IMX2
config FSL_IMX8MM_EVK
bool
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 6b5b769733..16599cc58f 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -200,6 +200,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_WDTS; i++) {
+ g_autofree char *name = g_strdup_printf("wdt%d", i);
+ object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
+ }
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -486,6 +491,28 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0,
fsl_imx8mm_memmap[FSL_IMX8MM_SNVS_HP].addr);
+ /* Watchdogs */
+ for (i = 0; i < FSL_IMX8MM_NUM_WDTS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } wdog_table[FSL_IMX8MM_NUM_WDTS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG1].addr, FSL_IMX8MM_WDOG1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG2].addr, FSL_IMX8MM_WDOG2_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_WDOG3].addr, FSL_IMX8MM_WDOG3_IRQ },
+ };
+
+ object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
+ true, &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, wdog_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
+ qdev_get_gpio_in(gicdev, wdog_table[i].irq));
+ }
+
/* PCIe */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie), errp)) {
return;
@@ -526,6 +553,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
+ case FSL_IMX8MM_WDOG1 ... FSL_IMX8MM_WDOG3:
/* device implemented and treated above */
break;
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 33fbfb72da..70292a2a9b 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -22,6 +22,7 @@
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "hw/ssi/imx_spi.h"
+#include "hw/watchdog/wdt_imx2.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -39,6 +40,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
FSL_IMX8MM_NUM_USDHCS = 3,
+ FSL_IMX8MM_NUM_WDTS = 3,
};
struct FslImx8mmState {
@@ -54,6 +56,7 @@ struct FslImx8mmState {
IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
+ IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
};
@@ -199,6 +202,10 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_GPIO5_LOW_IRQ = 72,
FSL_IMX8MM_GPIO5_HIGH_IRQ = 73,
+ FSL_IMX8MM_WDOG1_IRQ = 78,
+ FSL_IMX8MM_WDOG2_IRQ = 79,
+ FSL_IMX8MM_WDOG3_IRQ = 10,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 12/15] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (10 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 11/15] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 13/15] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Gaurav Sharma
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
It enables emulation of GPT in iMX8MM
Added GPT IRQ lines
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 53 ++++++++++++++++++++++++++++++++++
hw/timer/imx_gpt.c | 26 +++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 11 +++++++
include/hw/timer/imx_gpt.h | 2 ++
6 files changed, 94 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index b7034ff472..96981bf27d 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -18,6 +18,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 6 I2C Controllers
* 3 SPI Controllers
* 3 Watchdogs
+ * 6 General Purpose Timers
* Secure Non-Volatile Storage (SNVS) including an RTC
* Clock Tree
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index b757557ac7..f84bf725be 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -635,6 +635,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_CCM
select IMX
select IMX_I2C
+ select OR_IRQ
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 16599cc58f..33c4b9a0fd 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -180,6 +180,13 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
}
+ for (i = 0; i < FSL_IMX8MM_NUM_GPTS; i++) {
+ g_autofree char *name = g_strdup_printf("gpt%d", i + 1);
+ object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX8MM_GPT);
+ }
+ object_initialize_child(obj, "gpt5-gpt6-irq", &s->gpt5_gpt6_irq,
+ TYPE_OR_IRQ);
+
for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
g_autofree char *name = g_strdup_printf("i2c%d", i + 1);
object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
@@ -375,6 +382,52 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, serial_table[i].irq));
}
+ /* GPTs */
+ object_property_set_int(OBJECT(&s->gpt5_gpt6_irq), "num-lines", 2,
+ &error_abort);
+ if (!qdev_realize(DEVICE(&s->gpt5_gpt6_irq), NULL, errp)) {
+ return;
+ }
+
+ qdev_connect_gpio_out(DEVICE(&s->gpt5_gpt6_irq), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_GPT5_GPT6_IRQ));
+
+ for (i = 0; i < FSL_IMX8MM_NUM_GPTS; i++) {
+ hwaddr gpt_addrs[FSL_IMX8MM_NUM_GPTS] = {
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT1].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT2].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT3].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT4].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT5].addr,
+ fsl_imx8mm_memmap[FSL_IMX8MM_GPT6].addr,
+ };
+
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
+
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), errp)) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_addrs[i]);
+
+ if (i < FSL_IMX8MM_NUM_GPTS - 2) {
+ static const unsigned int gpt_irqs[FSL_IMX8MM_NUM_GPTS - 2] = {
+ FSL_IMX8MM_GPT1_IRQ,
+ FSL_IMX8MM_GPT2_IRQ,
+ FSL_IMX8MM_GPT3_IRQ,
+ FSL_IMX8MM_GPT4_IRQ,
+ };
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
+ qdev_get_gpio_in(gicdev, gpt_irqs[i]));
+ } else {
+ int irq = i - FSL_IMX8MM_NUM_GPTS + 2;
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
+ qdev_get_gpio_in(DEVICE(&s->gpt5_gpt6_irq), irq));
+ }
+ }
+
/* I2Cs */
for (i = 0; i < FSL_IMX8MM_NUM_I2CS; i++) {
static const struct {
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 8c7cbfdeac..5eba637f7d 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -6,6 +6,7 @@
* Originally written by Hans Jiang
* Updated by Peter Chubb
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ * Updated by Gaurav Sharma <gaurav.sharma_7@nxp.com>
*
* This code is licensed under GPL version 2 or later. See
* the COPYING file in the top-level directory.
@@ -137,6 +138,17 @@ static const IMXClk imx8mp_gpt_clocks[] = {
CLK_NONE, /* 111 not defined */
};
+static const IMXClk imx8mm_gpt_clocks[] = {
+ CLK_NONE, /* 000 No clock source */
+ CLK_IPG, /* 001 ipg_clk, 532MHz */
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
+ CLK_EXT, /* 011 External clock */
+ CLK_32k, /* 100 ipg_clk_32k */
+ CLK_HIGH, /* 101 ipg_clk_16M */
+ CLK_NONE, /* 110 not defined */
+ CLK_NONE, /* 111 not defined */
+};
+
/* Must be called from within ptimer_transaction_begin/commit block */
static void imx_gpt_set_freq(IMXGPTState *s)
{
@@ -570,6 +582,13 @@ static void imx8mp_gpt_init(Object *obj)
s->clocks = imx8mp_gpt_clocks;
}
+static void imx8mm_gpt_init(Object *obj)
+{
+ IMXGPTState *s = IMX_GPT(obj);
+
+ s->clocks = imx8mm_gpt_clocks;
+}
+
static const TypeInfo imx25_gpt_info = {
.name = TYPE_IMX25_GPT,
.parent = TYPE_SYS_BUS_DEVICE,
@@ -608,6 +627,12 @@ static const TypeInfo imx8mp_gpt_info = {
.instance_init = imx8mp_gpt_init,
};
+static const TypeInfo imx8mm_gpt_info = {
+ .name = TYPE_IMX8MM_GPT,
+ .parent = TYPE_IMX25_GPT,
+ .instance_init = imx8mm_gpt_init,
+};
+
static void imx_gpt_register_types(void)
{
type_register_static(&imx25_gpt_info);
@@ -616,6 +641,7 @@ static void imx_gpt_register_types(void)
type_register_static(&imx6ul_gpt_info);
type_register_static(&imx7_gpt_info);
type_register_static(&imx8mp_gpt_info);
+ type_register_static(&imx8mm_gpt_info);
}
type_init(imx_gpt_register_types)
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 70292a2a9b..c5407ea9e7 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -18,10 +18,12 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/or-irq.h"
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
#include "hw/sd/sdhci.h"
#include "hw/ssi/imx_spi.h"
+#include "hw/timer/imx_gpt.h"
#include "hw/watchdog/wdt_imx2.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -36,6 +38,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_CPUS = 4,
FSL_IMX8MM_NUM_ECSPIS = 3,
FSL_IMX8MM_NUM_GPIOS = 5,
+ FSL_IMX8MM_NUM_GPTS = 6,
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
@@ -48,6 +51,7 @@ struct FslImx8mmState {
ARMCPU cpu[FSL_IMX8MM_NUM_CPUS];
GICv3State gic;
+ IMXGPTState gpt[FSL_IMX8MM_NUM_GPTS];
IMXGPIOState gpio[FSL_IMX8MM_NUM_GPIOS];
IMX8MPCCMState ccm;
IMX8MPAnalogState analog;
@@ -59,6 +63,7 @@ struct FslImx8mmState {
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
+ OrIRQState gpt5_gpt6_irq;
};
enum FslImx8mmMemoryRegions {
@@ -191,6 +196,12 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_I2C3_IRQ = 37,
FSL_IMX8MM_I2C4_IRQ = 38,
+ FSL_IMX8MM_GPT1_IRQ = 55,
+ FSL_IMX8MM_GPT2_IRQ = 54,
+ FSL_IMX8MM_GPT3_IRQ = 53,
+ FSL_IMX8MM_GPT4_IRQ = 52,
+ FSL_IMX8MM_GPT5_GPT6_IRQ = 51,
+
FSL_IMX8MM_GPIO1_LOW_IRQ = 64,
FSL_IMX8MM_GPIO1_HIGH_IRQ = 65,
FSL_IMX8MM_GPIO2_LOW_IRQ = 66,
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
index 5488f7e4df..379ee5de75 100644
--- a/include/hw/timer/imx_gpt.h
+++ b/include/hw/timer/imx_gpt.h
@@ -6,6 +6,7 @@
* Originally written by Hans Jiang
* Updated by Peter Chubb
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ * Updated by Gaurav Sharma <gaurav.sharma_7@nxp.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -81,6 +82,7 @@
#define TYPE_IMX6UL_GPT "imx6ul.gpt"
#define TYPE_IMX7_GPT "imx7.gpt"
#define TYPE_IMX8MP_GPT "imx8mp.gpt"
+#define TYPE_IMX8MM_GPT "imx8mm.gpt"
#define TYPE_IMX_GPT TYPE_IMX25_GPT
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 13/15] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (11 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 12/15] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 14/15] hw/arm/fsl-imx8mm: Adding support for USB controller Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 15/15] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Gaurav Sharma
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
It enables emulation of ENET ethernet controller in iMX8MM
Enables testing and debugging of network dependent drivers
Added ENET MAC IRQ lines
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 24 ++++++++++++++++++++++++
hw/arm/imx8mm-evk.c | 1 +
include/hw/arm/fsl-imx8mm.h | 8 ++++++++
5 files changed, 35 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index 96981bf27d..c8445099e8 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -14,6 +14,7 @@ The ``imx8mm-evk`` machine implements the following devices:
* 4 UARTs
* 3 USDHC Storage Controllers
* 1 Designware PCI Express Controller
+ * 1 Ethernet Controller
* 5 GPIO Controllers
* 6 I2C Controllers
* 3 SPI Controllers
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index f84bf725be..4095351490 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -634,6 +634,7 @@ config FSL_IMX8MM
select FSL_IMX8MP_ANALOG
select FSL_IMX8MP_CCM
select IMX
+ select IMX_FEC
select IMX_I2C
select OR_IRQ
select SDHCI
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index 33c4b9a0fd..f67fabc435 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -212,6 +212,8 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
}
+ object_initialize_child(obj, "eth0", &s->enet, TYPE_IMX_ENET);
+
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie_phy", &s->pcie_phy,
TYPE_FSL_IMX8M_PCIE_PHY);
@@ -537,6 +539,21 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, spi_table[i].irq));
}
+ /* ENET1 */
+ object_property_set_uint(OBJECT(&s->enet), "phy-num", s->phy_num,
+ &error_abort);
+ object_property_set_uint(OBJECT(&s->enet), "tx-ring-num", 3, &error_abort);
+ qemu_configure_nic_device(DEVICE(&s->enet), true, NULL);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->enet), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->enet), 0,
+ fsl_imx8mm_memmap[FSL_IMX8MM_ENET1].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 0,
+ qdev_get_gpio_in(gicdev, FSL_IMX8MM_ENET1_MAC_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 1,
+ qdev_get_gpio_in(gicdev, FSL_IMX6_ENET1_MAC_1588_IRQ));
+
/* SNVS */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) {
return;
@@ -599,6 +616,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_GIC_REDIST:
case FSL_IMX8MM_GPIO1 ... FSL_IMX8MM_GPIO5:
case FSL_IMX8MM_ECSPI1 ... FSL_IMX8MM_ECSPI3:
+ case FSL_IMX8MM_ENET1:
case FSL_IMX8MM_I2C1 ... FSL_IMX8MM_I2C4:
case FSL_IMX8MM_PCIE1:
case FSL_IMX8MM_PCIE_PHY1:
@@ -619,10 +637,16 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
}
}
+static const Property fsl_imx8mm_properties[] = {
+ DEFINE_PROP_UINT32("fec1-phy-num", FslImx8mmState, phy_num, 0),
+ DEFINE_PROP_BOOL("fec1-phy-connected", FslImx8mmState, phy_connected, true),
+};
+
static void fsl_imx8mm_class_init(ObjectClass *oc, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
+ device_class_set_props(dc, fsl_imx8mm_properties);
dc->realize = fsl_imx8mm_realize;
dc->desc = "i.MX 8MM SoC";
diff --git a/hw/arm/imx8mm-evk.c b/hw/arm/imx8mm-evk.c
index 2ecef38210..fd25e224bc 100644
--- a/hw/arm/imx8mm-evk.c
+++ b/hw/arm/imx8mm-evk.c
@@ -78,6 +78,7 @@ static void imx8mm_evk_init(MachineState *machine)
};
s = FSL_IMX8MM(object_new(TYPE_FSL_IMX8MM));
+ object_property_set_uint(OBJECT(s), "fec1-phy-num", 1, &error_fatal);
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index c5407ea9e7..326766e071 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -18,6 +18,7 @@
#include "hw/misc/imx7_snvs.h"
#include "hw/misc/imx8mp_analog.h"
#include "hw/misc/imx8mp_ccm.h"
+#include "hw/net/imx_fec.h"
#include "hw/or-irq.h"
#include "hw/pci-host/designware.h"
#include "hw/pci-host/fsl_imx8m_phy.h"
@@ -59,11 +60,15 @@ struct FslImx8mmState {
IMXSPIState spi[FSL_IMX8MM_NUM_ECSPIS];
IMXI2CState i2c[FSL_IMX8MM_NUM_I2CS];
IMXSerialState uart[FSL_IMX8MM_NUM_UARTS];
+ IMXFECState enet;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
OrIRQState gpt5_gpt6_irq;
+
+ uint32_t phy_num;
+ bool phy_connected;
};
enum FslImx8mmMemoryRegions {
@@ -217,6 +222,9 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_WDOG2_IRQ = 79,
FSL_IMX8MM_WDOG3_IRQ = 10,
+ FSL_IMX8MM_ENET1_MAC_IRQ = 118,
+ FSL_IMX6_ENET1_MAC_1588_IRQ = 121,
+
FSL_IMX8MM_PCI_INTA_IRQ = 122,
FSL_IMX8MM_PCI_INTB_IRQ = 123,
FSL_IMX8MM_PCI_INTC_IRQ = 124,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 14/15] hw/arm/fsl-imx8mm: Adding support for USB controller
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (12 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 13/15] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 15/15] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Gaurav Sharma
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma, Philippe Mathieu-Daude
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>
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
docs/system/arm/imx8mm-evk.rst | 1 +
hw/arm/Kconfig | 1 +
hw/arm/fsl-imx8mm.c | 27 +++++++++++++++++++++++++++
include/hw/arm/fsl-imx8mm.h | 6 ++++++
4 files changed, 35 insertions(+)
diff --git a/docs/system/arm/imx8mm-evk.rst b/docs/system/arm/imx8mm-evk.rst
index c8445099e8..f9fbc7b054 100644
--- a/docs/system/arm/imx8mm-evk.rst
+++ b/docs/system/arm/imx8mm-evk.rst
@@ -15,6 +15,7 @@ The ``imx8mm-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/hw/arm/Kconfig b/hw/arm/Kconfig
index 4095351490..2ed236171a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -640,6 +640,7 @@ config FSL_IMX8MM
select SDHCI
select PCI_EXPRESS_DESIGNWARE
select PCI_EXPRESS_FSL_IMX8M_PHY
+ select USB_DWC3
select WDT_IMX2
config FSL_IMX8MM_EVK
diff --git a/hw/arm/fsl-imx8mm.c b/hw/arm/fsl-imx8mm.c
index f67fabc435..6759abbb8f 100644
--- a/hw/arm/fsl-imx8mm.c
+++ b/hw/arm/fsl-imx8mm.c
@@ -202,6 +202,11 @@ static void fsl_imx8mm_init(Object *obj)
object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
}
+ for (i = 0; i < FSL_IMX8MM_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_IMX8MM_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);
@@ -519,6 +524,27 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in(gicdev, usdhc_table[i].irq));
}
+ /* USBs */
+ for (i = 0; i < FSL_IMX8MM_NUM_USBS; i++) {
+ static const struct {
+ hwaddr addr;
+ unsigned int irq;
+ } usb_table[FSL_IMX8MM_NUM_USBS] = {
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB1].addr, FSL_IMX8MM_USB1_IRQ },
+ { fsl_imx8mm_memmap[FSL_IMX8MM_USB2].addr, FSL_IMX8MM_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", 2);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i].sysbus_xhci), 0,
+ qdev_get_gpio_in(gicdev, usb_table[i].irq));
+ }
+
/* ECSPIs */
for (i = 0; i < FSL_IMX8MM_NUM_ECSPIS; i++) {
static const struct {
@@ -623,6 +649,7 @@ static void fsl_imx8mm_realize(DeviceState *dev, Error **errp)
case FSL_IMX8MM_RAM:
case FSL_IMX8MM_SNVS_HP:
case FSL_IMX8MM_UART1 ... FSL_IMX8MM_UART4:
+ case FSL_IMX8MM_USB1 ... FSL_IMX8MM_USB2:
case FSL_IMX8MM_USDHC1 ... FSL_IMX8MM_USDHC3:
case FSL_IMX8MM_WDOG1 ... FSL_IMX8MM_WDOG3:
/* device implemented and treated above */
diff --git a/include/hw/arm/fsl-imx8mm.h b/include/hw/arm/fsl-imx8mm.h
index 326766e071..471c410a12 100644
--- a/include/hw/arm/fsl-imx8mm.h
+++ b/include/hw/arm/fsl-imx8mm.h
@@ -25,6 +25,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"
@@ -43,6 +44,7 @@ enum FslImx8mmConfiguration {
FSL_IMX8MM_NUM_I2CS = 4,
FSL_IMX8MM_NUM_IRQS = 128,
FSL_IMX8MM_NUM_UARTS = 4,
+ FSL_IMX8MM_NUM_USBS = 2,
FSL_IMX8MM_NUM_USDHCS = 3,
FSL_IMX8MM_NUM_WDTS = 3,
};
@@ -63,6 +65,7 @@ struct FslImx8mmState {
IMXFECState enet;
SDHCIState usdhc[FSL_IMX8MM_NUM_USDHCS];
IMX2WdtState wdt[FSL_IMX8MM_NUM_WDTS];
+ USBDWC3 usb[FSL_IMX8MM_NUM_USBS];
DesignwarePCIEHost pcie;
FslImx8mPciePhyState pcie_phy;
OrIRQState gpt5_gpt6_irq;
@@ -201,6 +204,9 @@ enum FslImx8mmIrqs {
FSL_IMX8MM_I2C3_IRQ = 37,
FSL_IMX8MM_I2C4_IRQ = 38,
+ FSL_IMX8MM_USB1_IRQ = 40,
+ FSL_IMX8MM_USB2_IRQ = 41,
+
FSL_IMX8MM_GPT1_IRQ = 55,
FSL_IMX8MM_GPT2_IRQ = 54,
FSL_IMX8MM_GPT3_IRQ = 53,
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCHv4 15/15] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
` (13 preceding siblings ...)
2025-12-05 5:38 ` [PATCHv4 14/15] hw/arm/fsl-imx8mm: Adding support for USB controller Gaurav Sharma
@ 2025-12-05 5:38 ` Gaurav Sharma
14 siblings, 0 replies; 16+ messages in thread
From: Gaurav Sharma @ 2025-12-05 5:38 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, peter.maydell, Gaurav Sharma
Added script that would validate the iMX8MM emulation by checking the
linux console log. If it succeeds, it will return:-
ok 1 test_imx8mm_evk.Imx8mmEvkMachine.test_aarch64_imx8mm_evk_usdhc
Signed-off-by: Gaurav Sharma <gaurav.sharma_7@nxp.com>
---
tests/functional/aarch64/meson.build | 2 +
tests/functional/aarch64/test_imx8mm_evk.py | 67 +++++++++++++++++++++
2 files changed, 69 insertions(+)
create mode 100755 tests/functional/aarch64/test_imx8mm_evk.py
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
index 5ad52f93e1..c0e5be1b58 100644
--- a/tests/functional/aarch64/meson.build
+++ b/tests/functional/aarch64/meson.build
@@ -4,6 +4,7 @@ test_aarch64_timeouts = {
'aspeed_ast2700' : 600,
'aspeed_ast2700fc' : 600,
'device_passthrough' : 720,
+ 'imx8mm_evk' : 240,
'imx8mp_evk' : 240,
'raspi4' : 480,
'reverse_debug' : 180,
@@ -27,6 +28,7 @@ tests_aarch64_system_thorough = [
'aspeed_ast2700fc',
'device_passthrough',
'hotplug_pci',
+ 'imx8mm_evk',
'imx8mp_evk',
'kvm',
'multiprocess',
diff --git a/tests/functional/aarch64/test_imx8mm_evk.py b/tests/functional/aarch64/test_imx8mm_evk.py
new file mode 100755
index 0000000000..224fe4669e
--- /dev/null
+++ b/tests/functional/aarch64/test_imx8mm_evk.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+
+class Imx8mmEvkMachine(LinuxKernelTest):
+
+ ASSET_IMAGE = Asset(
+ ('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/'
+ 'debian-12-generic-arm64-20231210-1590.tar.xz'),
+ '7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359')
+
+ KERNEL_OFFSET = 0x51000000
+ KERNEL_SIZE = 32622528
+ INITRD_OFFSET = 0x76000000
+ INITRD_SIZE = 30987766
+ DTB_OFFSET = 0x64DB5000
+ DTB_SIZE = 36812
+
+ def extract(self, in_path, out_path, offset, size):
+ try:
+ with open(in_path, "rb") as source:
+ source.seek(offset)
+ data = source.read(size)
+ with open(out_path, "wb") as target:
+ target.write(data)
+ except (IOError, ValueError) as e:
+ self.log.error(f"Failed to extract {out_path}: {e}")
+ raise
+
+ def setUp(self):
+ super().setUp()
+
+ self.image_path = self.scratch_file("disk.raw")
+ self.kernel_path = self.scratch_file("linux")
+ self.initrd_path = self.scratch_file("initrd.zstd")
+ self.dtb_path = self.scratch_file("imx8mm-evk.dtb")
+
+ self.archive_extract(self.ASSET_IMAGE)
+ self.extract(self.image_path, self.kernel_path,
+ self.KERNEL_OFFSET, self.KERNEL_SIZE)
+ self.extract(self.image_path, self.initrd_path,
+ self.INITRD_OFFSET, self.INITRD_SIZE)
+ self.extract(self.image_path, self.dtb_path,
+ self.DTB_OFFSET, self.DTB_SIZE)
+
+ def test_aarch64_imx8mm_evk_usdhc(self):
+ self.require_accelerator("tcg")
+ self.set_machine('imx8mm-evk')
+ self.vm.set_console(console_index=1)
+ self.vm.add_args('-m', '2G',
+ '-smp', '4',
+ '-kernel', self.kernel_path,
+ '-initrd', self.initrd_path,
+ '-dtb', self.dtb_path,
+ '-append', 'root=/dev/mmcblk2p1',
+ '-drive', f'file={self.image_path},if=sd,bus=2,'
+ 'format=raw,id=mmcblk2,snapshot=on')
+
+ self.vm.launch()
+ self.wait_for_console_pattern('Welcome to ')
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-12-05 5:41 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-05 5:38 [PATCHv4 00/15] Adding comprehensive support for i.MX8MM EVK board Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 01/15] hw/arm: Add the i.MX 8MM EVK(Evaluation Kit) board Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 02/15] hw/misc/imx8mp_analog: Add property to analog device Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 03/15] hw/arm/fsl-imx8mm: Add Analog device IP to iMX8MM SOC Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 04/15] hw/arm/fsl-imx8mm: Add Clock Control Module IP to iMX8MM Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 05/15] hw/arm/fsl-imx8mm: Implemented support for SNVS Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 06/15] hw/arm/fsl-imx8mm: Adding support for USDHC storage controllers Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 07/15] hw/arm/fsl-imx8mm: Add PCIe support Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 08/15] hw/arm/fsl-imx8mm: Add GPIO controllers Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 09/15] hw/arm/fsl-imx8mm: Adding support for I2C emulation Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 10/15] hw/arm/fsl-imx8mm: Adding support for SPI controller Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 11/15] hw/arm/fsl-imx8mm: Adding support for Watchdog Timers Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 12/15] hw/arm/fsl-imx8mm: Adding support for General Purpose Timers Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 13/15] hw/arm/fsl-imx8mm: Adding support for ENET ethernet controller Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 14/15] hw/arm/fsl-imx8mm: Adding support for USB controller Gaurav Sharma
2025-12-05 5:38 ` [PATCHv4 15/15] hw/arm/fsl-imx8mm: Adding functional testing of iMX8MM emulation Gaurav Sharma
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).