All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support
@ 2026-07-01 22:46 Bernhard Beschow
  2026-07-01 22:46 ` [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN Bernhard Beschow
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-01 22:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gaurav Sharma, Bernhard Beschow, Pavel Pisa, Jason Wang,
	Francisco Iglesias, Peter Maydell, qemu-arm, Matyas Bobek,
	Jean-Christophe Dubois, Vikram Garhwal, Paolo Bonzini,
	Pierrick Bouvier

Now that FlexCAN emulation is on its way into master [1], let's add it to
imx8mp-evk as well. While the real i.MX8M Plus supports CAN FD which isn't
emulated yet, the non-FD mode works well under Linux: It is possible to use
`cangen` and `candump` either way on the host and on the guest, as described in
docs/system/devices/can.rst.

This series consists of four patches where the first three are preparations.
The last patch integrates FlexCAN into the i.MX8M Plus SoC and EVK board.

It would be nice if this series could make it into 11.1.

Based-on: cover.1782140438.git.matyas.bobek@gmail.com

[1]
https://lore.kernel.org/qemu-devel/20260629120032.1645265-35-peter.
maydell@linaro.org/

Bernhard Beschow (4):
  hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN
  hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64
  hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState
  hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk

 docs/system/arm/imx8m.rst   |  1 +
 include/hw/arm/fsl-imx8mp.h |  8 +++++
 include/hw/net/flexcan.h    |  4 ++-
 hw/arm/fsl-imx6.c           |  2 +-
 hw/arm/fsl-imx8mp.c         | 37 +++++++++++++++++++++
 hw/arm/imx8mp-evk.c         | 64 ++++++++++++++++++++++++++++++-------
 hw/misc/imx8mp_ccm.c        |  3 ++
 hw/net/can/flexcan.c        | 61 +++++++++++++++++++++++++++--------
 hw/arm/Kconfig              |  1 +
 9 files changed, 154 insertions(+), 27 deletions(-)

-- 
2.54.0



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN
  2026-07-01 22:46 [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support Bernhard Beschow
@ 2026-07-01 22:46 ` Bernhard Beschow
  2026-07-02 12:45   ` Philippe Mathieu-Daudé
  2026-07-01 22:46 ` [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64 Bernhard Beschow
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-01 22:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gaurav Sharma, Bernhard Beschow, Pavel Pisa, Jason Wang,
	Francisco Iglesias, Peter Maydell, qemu-arm, Matyas Bobek,
	Jean-Christophe Dubois, Vikram Garhwal, Paolo Bonzini,
	Pierrick Bouvier

Subclass TYPE_CAN_FLEXCAN, yielding TYPE_CAN_FLEXCAN2 and TYPE_CAN_FLEXCAN3.
Since TYPE_CAN_FLEXCAN is now abstract, TYPE_FSL_IMX6 needs to use
TYPE_CAN_FLEXCAN2. TYPE_CAN_FLEXCAN3 will be used in TYPE_FSL_IMX8MP.

Note that Linux performs 8 byte accesses on the i.MX8M Plus, therefore
.max_access_size has to be adjusted. Otherwise this results in bus errors.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 include/hw/net/flexcan.h |  4 ++-
 hw/arm/fsl-imx6.c        |  2 +-
 hw/net/can/flexcan.c     | 61 +++++++++++++++++++++++++++++++---------
 3 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/include/hw/net/flexcan.h b/include/hw/net/flexcan.h
index 153afc1e03..32de7b904a 100644
--- a/include/hw/net/flexcan.h
+++ b/include/hw/net/flexcan.h
@@ -139,7 +139,9 @@ typedef struct FlexcanState {
 } FlexcanState;
 
 #define TYPE_CAN_FLEXCAN "flexcan"
-
 OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);
 
+#define TYPE_CAN_FLEXCAN2 "flexcan2"
+#define TYPE_CAN_FLEXCAN3 "flexcan3"
+
 #endif
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index bf106a9063..57cdde971c 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -92,7 +92,7 @@ static void fsl_imx6_init(Object *obj)
     }
     for (i = 0; i < FSL_IMX6_NUM_CANS; i++) {
         snprintf(name, NAME_SIZE, "flexcan%d", i + 1);
-        object_initialize_child(obj, name, &s->flexcan[i], TYPE_CAN_FLEXCAN);
+        object_initialize_child(obj, name, &s->flexcan[i], TYPE_CAN_FLEXCAN2);
     }
     for (i = 0; i < FSL_IMX6_NUM_WDTS; i++) {
         snprintf(name, NAME_SIZE, "wdt%d", i);
diff --git a/hw/net/can/flexcan.c b/hw/net/can/flexcan.c
index 1ea459d9f6..d6a76c28ab 100644
--- a/hw/net/can/flexcan.c
+++ b/hw/net/can/flexcan.c
@@ -1298,7 +1298,7 @@ static const struct MemoryRegionOps flexcan_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
     .valid = {
         .min_access_size = 1,
-        .max_access_size = 4,
+        .max_access_size = 8,
         .unaligned = true,
         .accepts = flexcan_mem_accepts
     },
@@ -1324,16 +1324,26 @@ static int flexcan_connect_to_bus(FlexcanState *s, CanBusState *bus)
     return 0;
 }
 
-static void flexcan_init(Object *obj)
+static void flexcan2_init(Object *obj)
 {
     FlexcanState *s = CAN_FLEXCAN(obj);
 
     memory_region_init_io(
-        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN,
+        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN2,
         offsetof(FlexcanRegs, _reserved6)
     );
 }
 
+static void flexcan3_init(Object *obj)
+{
+    FlexcanState *s = CAN_FLEXCAN(obj);
+
+    memory_region_init_io(
+        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN3,
+        sizeof(FlexcanRegs)
+    );
+}
+
 static void flexcan_realize(DeviceState *dev, Error **errp)
 {
     FlexcanState *s = CAN_FLEXCAN(dev);
@@ -1378,19 +1388,42 @@ static void flexcan_class_init(ObjectClass *klass, const void *data)
     dc->realize = flexcan_realize;
     device_class_set_props(dc, flexcan_properties);
     dc->vmsd = &vmstate_can;
-    dc->desc = "i.MX FLEXCAN Controller";
 }
 
-static const TypeInfo flexcan_info = {
-    .name          = TYPE_CAN_FLEXCAN,
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(FlexcanState),
-    .class_init    = flexcan_class_init,
-    .instance_init = flexcan_init,
-};
+static void flexcan2_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-static void can_register_types(void)
+    dc->desc = "i.MX FlexCAN 2 Controller";
+}
+
+static void flexcan3_class_init(ObjectClass *klass, const void *data)
 {
-    type_register_static(&flexcan_info);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->desc = "i.MX FlexCAN 3 Controller";
 }
-type_init(can_register_types)
+
+static const TypeInfo flexcan_types[] = {
+    {
+        .name          = TYPE_CAN_FLEXCAN,
+        .parent        = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(FlexcanState),
+        .class_init    = flexcan_class_init,
+        .abstract      = true,
+    },
+    {
+        .name          = TYPE_CAN_FLEXCAN2,
+        .parent        = TYPE_CAN_FLEXCAN,
+        .class_init    = flexcan2_class_init,
+        .instance_init = flexcan2_init,
+    },
+    {
+        .name          = TYPE_CAN_FLEXCAN3,
+        .parent        = TYPE_CAN_FLEXCAN,
+        .class_init    = flexcan3_class_init,
+        .instance_init = flexcan3_init,
+    },
+};
+
+DEFINE_TYPES(flexcan_types)
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64
  2026-07-01 22:46 [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support Bernhard Beschow
  2026-07-01 22:46 ` [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN Bernhard Beschow
@ 2026-07-01 22:46 ` Bernhard Beschow
  2026-07-02 12:23   ` Philippe Mathieu-Daudé
  2026-07-01 22:46 ` [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState Bernhard Beschow
  2026-07-01 22:46 ` [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk Bernhard Beschow
  3 siblings, 1 reply; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-01 22:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gaurav Sharma, Bernhard Beschow, Pavel Pisa, Jason Wang,
	Francisco Iglesias, Peter Maydell, qemu-arm, Matyas Bobek,
	Jean-Christophe Dubois, Vikram Garhwal, Paolo Bonzini,
	Pierrick Bouvier

Open code the DEFINE_MACHINE_AARCH64 macro in preparation of creating
FslImx8mpEvkState class, needed for FlexCAN emulation.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/arm/imx8mp-evk.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c
index b84ac91a17..4a0c9df76b 100644
--- a/hw/arm/imx8mp-evk.c
+++ b/hw/arm/imx8mp-evk.c
@@ -113,8 +113,10 @@ static const char *imx8mp_evk_get_default_cpu_type(const MachineState *ms)
     return ARM_CPU_TYPE_NAME("cortex-a53");
 }
 
-static void imx8mp_evk_machine_init(MachineClass *mc)
+static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "NXP i.MX 8M Plus EVK Board";
     mc->init = imx8mp_evk_init;
     mc->default_cpus = 4;
@@ -124,4 +126,13 @@ static void imx8mp_evk_machine_init(MachineClass *mc)
     mc->get_default_cpu_type = imx8mp_evk_get_default_cpu_type;
 }
 
-DEFINE_MACHINE_AARCH64("imx8mp-evk", imx8mp_evk_machine_init)
+static const TypeInfo imx8mp_evk_machine_types[] = {
+    {
+        .name = MACHINE_TYPE_NAME("imx8mp-evk"),
+        .parent = TYPE_MACHINE,
+        .class_init = imx8mp_evk_machine_class_init,
+        .interfaces = aarch64_machine_interfaces,
+    },
+};
+
+DEFINE_TYPES(imx8mp_evk_machine_types)
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState
  2026-07-01 22:46 [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support Bernhard Beschow
  2026-07-01 22:46 ` [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN Bernhard Beschow
  2026-07-01 22:46 ` [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64 Bernhard Beschow
@ 2026-07-01 22:46 ` Bernhard Beschow
  2026-07-02 12:23   ` Philippe Mathieu-Daudé
  2026-07-01 22:46 ` [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk Bernhard Beschow
  3 siblings, 1 reply; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-01 22:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gaurav Sharma, Bernhard Beschow, Pavel Pisa, Jason Wang,
	Francisco Iglesias, Peter Maydell, qemu-arm, Matyas Bobek,
	Jean-Christophe Dubois, Vikram Garhwal, Paolo Bonzini,
	Pierrick Bouvier

Introduce class FslImx8mpEvkState which will be needed for holding
CanBusState attributes and associated properties.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 hw/arm/imx8mp-evk.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c
index 4a0c9df76b..ca0ee2d3f2 100644
--- a/hw/arm/imx8mp-evk.c
+++ b/hw/arm/imx8mp-evk.c
@@ -19,6 +19,17 @@
 #include "qapi/error.h"
 #include <libfdt.h>
 
+#define TYPE_IMX8MPEVK_MACHINE MACHINE_TYPE_NAME("imx8mp-evk")
+OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpEvkState, IMX8MPEVK_MACHINE)
+
+struct FslImx8mpEvkState {
+    MachineState parent_obj;
+
+    FslImx8mpState soc;
+
+    struct arm_boot_info boot_info;
+};
+
 static void imx8mp_evk_modify_dtb(const struct arm_boot_info *info, void *fdt)
 {
     int i, offset;
@@ -57,8 +68,7 @@ static void imx8mp_evk_modify_dtb(const struct arm_boot_info *info, void *fdt)
 
 static void imx8mp_evk_init(MachineState *machine)
 {
-    static struct arm_boot_info boot_info;
-    FslImx8mpState *s;
+    FslImx8mpEvkState *s = IMX8MPEVK_MACHINE(machine);
 
     if (machine->ram_size > FSL_IMX8MP_RAM_SIZE_MAX) {
         error_report("RAM size " RAM_ADDR_FMT " above max supported (%08" PRIx64 ")",
@@ -66,7 +76,7 @@ static void imx8mp_evk_init(MachineState *machine)
         exit(1);
     }
 
-    boot_info = (struct arm_boot_info) {
+    s->boot_info = (struct arm_boot_info) {
         .loader_start = FSL_IMX8MP_RAM_START,
         .board_id = -1,
         .ram_size = machine->ram_size,
@@ -74,10 +84,9 @@ static void imx8mp_evk_init(MachineState *machine)
         .modify_dtb = imx8mp_evk_modify_dtb,
     };
 
-    s = FSL_IMX8MP(object_new(TYPE_FSL_IMX8MP));
-    object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
-    object_property_set_uint(OBJECT(s), "fec1-phy-num", 1, &error_fatal);
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
+    object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_FSL_IMX8MP);
+    object_property_set_uint(OBJECT(&s->soc), "fec1-phy-num", 1, &error_fatal);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->soc), &error_fatal);
 
     memory_region_add_subregion(get_system_memory(), FSL_IMX8MP_RAM_START,
                                 machine->ram);
@@ -93,14 +102,14 @@ static void imx8mp_evk_init(MachineState *machine)
         }
 
         blk = blk_by_legacy_dinfo(di);
-        bus = qdev_get_child_bus(DEVICE(&s->usdhc[i]), "sd-bus");
+        bus = qdev_get_child_bus(DEVICE(&s->soc.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);
+        arm_load_kernel(&s->soc.cpu[0], machine, &s->boot_info);
     }
 }
 
@@ -128,9 +137,10 @@ static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
 
 static const TypeInfo imx8mp_evk_machine_types[] = {
     {
-        .name = MACHINE_TYPE_NAME("imx8mp-evk"),
+        .name = TYPE_IMX8MPEVK_MACHINE,
         .parent = TYPE_MACHINE,
         .class_init = imx8mp_evk_machine_class_init,
+        .instance_size = sizeof(FslImx8mpEvkState),
         .interfaces = aarch64_machine_interfaces,
     },
 };
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk
  2026-07-01 22:46 [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support Bernhard Beschow
                   ` (2 preceding siblings ...)
  2026-07-01 22:46 ` [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState Bernhard Beschow
@ 2026-07-01 22:46 ` Bernhard Beschow
  2026-07-02 12:41   ` Philippe Mathieu-Daudé
  3 siblings, 1 reply; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-01 22:46 UTC (permalink / raw)
  To: qemu-devel
  Cc: Gaurav Sharma, Bernhard Beschow, Pavel Pisa, Jason Wang,
	Francisco Iglesias, Peter Maydell, qemu-arm, Matyas Bobek,
	Jean-Christophe Dubois, Vikram Garhwal, Paolo Bonzini,
	Pierrick Bouvier

Real hardware supports CAN FD which is missing in the emulation and is
considered future work. Still, CAN communication already works under Linux.

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
 docs/system/arm/imx8m.rst   |  1 +
 include/hw/arm/fsl-imx8mp.h |  8 ++++++++
 hw/arm/fsl-imx8mp.c         | 37 +++++++++++++++++++++++++++++++++++++
 hw/arm/imx8mp-evk.c         | 21 +++++++++++++++++++++
 hw/misc/imx8mp_ccm.c        |  3 +++
 hw/arm/Kconfig              |  1 +
 6 files changed, 71 insertions(+)

diff --git a/docs/system/arm/imx8m.rst b/docs/system/arm/imx8m.rst
index afbc33b2f4..1bcb8255be 100644
--- a/docs/system/arm/imx8m.rst
+++ b/docs/system/arm/imx8m.rst
@@ -18,6 +18,7 @@ following devices:
  * 1 Designware PCI Express Controller
  * 1 Ethernet Controller
  * 2 Designware USB 3 Controllers
+ * 2 FlexCAN 3 CAN Controllers (``imx8mp-evk`` only)
  * 5 GPIO Controllers
  * 6 I2C Controllers
  * 3 SPI Controllers
diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index 3b6183ed1d..2be3c51af5 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -17,6 +17,7 @@
 #include "hw/misc/imx7_snvs.h"
 #include "hw/misc/imx8mp_analog.h"
 #include "hw/misc/imx8mp_ccm.h"
+#include "hw/net/flexcan.h"
 #include "hw/net/imx_fec.h"
 #include "hw/core/or-irq.h"
 #include "hw/pci-host/designware.h"
@@ -37,6 +38,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP)
 #define FSL_IMX8MP_RAM_SIZE_MAX     (8 * GiB)
 
 enum FslImx8mpConfiguration {
+    FSL_IMX8MP_NUM_CANS         = 2,
     FSL_IMX8MP_NUM_CPUS         = 4,
     FSL_IMX8MP_NUM_ECSPIS       = 3,
     FSL_IMX8MP_NUM_GPIOS        = 5,
@@ -68,11 +70,14 @@ struct FslImx8mpState {
     USBDWC3            usb[FSL_IMX8MP_NUM_USBS];
     DesignwarePCIEHost pcie;
     FslImx8mPciePhyState   pcie_phy;
+    FlexcanState       flexcan[FSL_IMX8MP_NUM_CANS];
     OrIRQState         gpt5_gpt6_irq;
     MemoryRegion       ocram;
 
     uint32_t           phy_num;
     bool               phy_connected;
+
+    CanBusState       *canbus[FSL_IMX8MP_NUM_CANS];
 };
 
 enum FslImx8mpMemoryRegions {
@@ -279,6 +284,9 @@ enum FslImx8mpIrqs {
     FSL_IMX8MP_PCI_INTC_IRQ = 124,
     FSL_IMX8MP_PCI_INTD_IRQ = 123,
     FSL_IMX8MP_PCI_MSI_IRQ  = 140,
+
+    FSL_IMX8MP_FLEXCAN1_IRQ  = 142,
+    FSL_IMX8MP_FLEXCAN2_IRQ  = 144,
 };
 
 #endif /* FSL_IMX8MP_H */
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 7c03ed3c34..c7ce30a17d 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -246,6 +246,11 @@ static void fsl_imx8mp_init(Object *obj)
         object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
     }
 
+    for (i = 0; i < FSL_IMX8MP_NUM_CANS; i++) {
+        g_autofree char *name = g_strdup_printf("flexcan%d", i);
+        object_initialize_child(obj, name, &s->flexcan[i], TYPE_CAN_FLEXCAN3);
+    }
+
     object_initialize_child(obj, "eth0", &s->enet, TYPE_IMX_ENET);
 
     object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
@@ -669,6 +674,33 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie_phy), 0,
                     fsl_imx8mp_memmap[FSL_IMX8MP_PCIE_PHY1].addr);
 
+    /* FLEXCANs */
+    for (i = 0; i < FSL_IMX8MP_NUM_CANS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } flexcan_table[FSL_IMX8MP_NUM_CANS] = {
+            {
+                fsl_imx8mp_memmap[FSL_IMX8MP_FLEXCAN1].addr,
+                FSL_IMX8MP_FLEXCAN1_IRQ
+            }, {
+                fsl_imx8mp_memmap[FSL_IMX8MP_FLEXCAN2].addr,
+                FSL_IMX8MP_FLEXCAN2_IRQ
+            },
+        };
+
+        s->flexcan[i].ccm = IMX_CCM(&s->ccm);
+        object_property_set_link(OBJECT(&s->flexcan[i]), "canbus",
+                                 OBJECT(s->canbus[i]), &error_abort);
+
+        sysbus_realize(SYS_BUS_DEVICE(&s->flexcan[i]), &error_abort);
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
+                        flexcan_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
+                           qdev_get_gpio_in(gicdev, flexcan_table[i].irq));
+    }
+
     /* On-Chip RAM */
     if (!memory_region_init_ram(&s->ocram, OBJECT(dev), "imx8mp.ocram",
                                 fsl_imx8mp_memmap[FSL_IMX8MP_OCRAM].size,
@@ -684,6 +716,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
         switch (i) {
         case FSL_IMX8MP_ANA_PLL:
         case FSL_IMX8MP_CCM:
+        case FSL_IMX8MP_FLEXCAN1 ... FSL_IMX8MP_FLEXCAN2:
         case FSL_IMX8MP_GIC_DIST:
         case FSL_IMX8MP_GIC_REDIST:
         case FSL_IMX8MP_GPIO1 ... FSL_IMX8MP_GPIO5:
@@ -715,6 +748,10 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
 static const Property fsl_imx8mp_properties[] = {
     DEFINE_PROP_UINT32("fec1-phy-num", FslImx8mpState, phy_num, 0),
     DEFINE_PROP_BOOL("fec1-phy-connected", FslImx8mpState, phy_connected, true),
+    DEFINE_PROP_LINK("canbus0", FslImx8mpState, canbus[0], TYPE_CAN_BUS,
+                     CanBusState *),
+    DEFINE_PROP_LINK("canbus1", FslImx8mpState, canbus[1], TYPE_CAN_BUS,
+                     CanBusState *),
 };
 
 static void fsl_imx8mp_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c
index ca0ee2d3f2..16e9722d14 100644
--- a/hw/arm/imx8mp-evk.c
+++ b/hw/arm/imx8mp-evk.c
@@ -26,6 +26,7 @@ struct FslImx8mpEvkState {
     MachineState parent_obj;
 
     FslImx8mpState soc;
+    CanBusState *canbus[FSL_IMX8MP_NUM_CANS];
 
     struct arm_boot_info boot_info;
 };
@@ -86,6 +87,12 @@ static void imx8mp_evk_init(MachineState *machine)
 
     object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_FSL_IMX8MP);
     object_property_set_uint(OBJECT(&s->soc), "fec1-phy-num", 1, &error_fatal);
+    for (int i = 0; i < FSL_IMX8MP_NUM_CANS; i++) {
+        g_autofree char *bus_name = g_strdup_printf("canbus%d", i);
+
+        object_property_set_link(OBJECT(&s->soc), bus_name,
+                                 OBJECT(s->canbus[i]), &error_fatal);
+    }
     sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->soc), &error_fatal);
 
     memory_region_add_subregion(get_system_memory(), FSL_IMX8MP_RAM_START,
@@ -122,6 +129,19 @@ static const char *imx8mp_evk_get_default_cpu_type(const MachineState *ms)
     return ARM_CPU_TYPE_NAME("cortex-a53");
 }
 
+static void imx8mp_evk_machine_init(Object *obj)
+{
+    FslImx8mpEvkState *s = IMX8MPEVK_MACHINE(obj);
+
+    object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
+                             (Object **)&s->canbus[0],
+                             object_property_allow_set_link, 0);
+
+    object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
+                             (Object **)&s->canbus[1],
+                             object_property_allow_set_link, 0);
+}
+
 static void imx8mp_evk_machine_class_init(ObjectClass *oc, const void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -140,6 +160,7 @@ static const TypeInfo imx8mp_evk_machine_types[] = {
         .name = TYPE_IMX8MPEVK_MACHINE,
         .parent = TYPE_MACHINE,
         .class_init = imx8mp_evk_machine_class_init,
+        .instance_init = imx8mp_evk_machine_init,
         .instance_size = sizeof(FslImx8mpEvkState),
         .interfaces = aarch64_machine_interfaces,
     },
diff --git a/hw/misc/imx8mp_ccm.c b/hw/misc/imx8mp_ccm.c
index 911911ed86..97d363e79d 100644
--- a/hw/misc/imx8mp_ccm.c
+++ b/hw/misc/imx8mp_ccm.c
@@ -129,6 +129,9 @@ static uint32_t imx8mp_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     case CLK_HIGH:
         freq = CKIH_FREQ;
         break;
+    case CLK_CAN:
+        freq = 40000000; /* 40Mhz, taken from device tree */
+        break;
     case CLK_IPG:
     case CLK_IPG_HIGH:
         /*
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 5f5c4899ad..0416ba823c 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -600,6 +600,7 @@ config FSL_IMX8MP
     imply I2C_DEVICES
     imply PCI_DEVICES
     select ARM_GIC
+    select CAN_FLEXCAN
     select FSL_IMX8MP_ANALOG
     select FSL_IMX8MP_CCM
     select IMX
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64
  2026-07-01 22:46 ` [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64 Bernhard Beschow
@ 2026-07-02 12:23   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-02 12:23 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: Gaurav Sharma, Pavel Pisa, Jason Wang, Francisco Iglesias,
	Peter Maydell, qemu-arm, Matyas Bobek, Jean-Christophe Dubois,
	Vikram Garhwal, Paolo Bonzini, Pierrick Bouvier

On 2/7/26 00:46, Bernhard Beschow wrote:
> Open code the DEFINE_MACHINE_AARCH64 macro in preparation of creating
> FslImx8mpEvkState class, needed for FlexCAN emulation.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/arm/imx8mp-evk.c | 15 +++++++++++++--
>   1 file changed, 13 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState
  2026-07-01 22:46 ` [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState Bernhard Beschow
@ 2026-07-02 12:23   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-02 12:23 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: Gaurav Sharma, Pavel Pisa, Jason Wang, Francisco Iglesias,
	Peter Maydell, qemu-arm, Matyas Bobek, Jean-Christophe Dubois,
	Vikram Garhwal, Paolo Bonzini, Pierrick Bouvier

On 2/7/26 00:46, Bernhard Beschow wrote:
> Introduce class FslImx8mpEvkState which will be needed for holding
> CanBusState attributes and associated properties.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   hw/arm/imx8mp-evk.c | 30 ++++++++++++++++++++----------
>   1 file changed, 20 insertions(+), 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk
  2026-07-01 22:46 ` [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk Bernhard Beschow
@ 2026-07-02 12:41   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-02 12:41 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: Gaurav Sharma, Pavel Pisa, Jason Wang, Francisco Iglesias,
	Peter Maydell, qemu-arm, Matyas Bobek, Jean-Christophe Dubois,
	Vikram Garhwal, Paolo Bonzini, Pierrick Bouvier

On 2/7/26 00:46, Bernhard Beschow wrote:
> Real hardware supports CAN FD which is missing in the emulation and is
> considered future work. Still, CAN communication already works under Linux.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   docs/system/arm/imx8m.rst   |  1 +
>   include/hw/arm/fsl-imx8mp.h |  8 ++++++++
>   hw/arm/fsl-imx8mp.c         | 37 +++++++++++++++++++++++++++++++++++++
>   hw/arm/imx8mp-evk.c         | 21 +++++++++++++++++++++
>   hw/misc/imx8mp_ccm.c        |  3 +++
>   hw/arm/Kconfig              |  1 +
>   6 files changed, 71 insertions(+)


> +    /* FLEXCANs */
> +    for (i = 0; i < FSL_IMX8MP_NUM_CANS; i++) {
> +        static const struct {
> +            hwaddr addr;
> +            unsigned int irq;
> +        } flexcan_table[FSL_IMX8MP_NUM_CANS] = {
> +            {
> +                fsl_imx8mp_memmap[FSL_IMX8MP_FLEXCAN1].addr,
> +                FSL_IMX8MP_FLEXCAN1_IRQ
> +            }, {
> +                fsl_imx8mp_memmap[FSL_IMX8MP_FLEXCAN2].addr,
> +                FSL_IMX8MP_FLEXCAN2_IRQ
> +            },
> +        };
> +
> +        s->flexcan[i].ccm = IMX_CCM(&s->ccm);

Conditional to setting this using object_property_set_link(), see
https://lore.kernel.org/qemu-devel/77d5891c-de12-467e-8746-02fe43121e3e@oss.qualcomm.com/, 
then:

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

> +        object_property_set_link(OBJECT(&s->flexcan[i]), "canbus",
> +                                 OBJECT(s->canbus[i]), &error_abort);
> +
> +        sysbus_realize(SYS_BUS_DEVICE(&s->flexcan[i]), &error_abort);
> +
> +        sysbus_mmio_map(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
> +                        flexcan_table[i].addr);
> +        sysbus_connect_irq(SYS_BUS_DEVICE(&s->flexcan[i]), 0,
> +                           qdev_get_gpio_in(gicdev, flexcan_table[i].irq));
> +    }


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN
  2026-07-01 22:46 ` [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN Bernhard Beschow
@ 2026-07-02 12:45   ` Philippe Mathieu-Daudé
  2026-07-02 16:58     ` Bernhard Beschow
  0 siblings, 1 reply; 10+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-07-02 12:45 UTC (permalink / raw)
  To: Bernhard Beschow, qemu-devel
  Cc: Gaurav Sharma, Pavel Pisa, Jason Wang, Francisco Iglesias,
	Peter Maydell, qemu-arm, Matyas Bobek, Jean-Christophe Dubois,
	Vikram Garhwal, Paolo Bonzini, Pierrick Bouvier

Hi Bernhard,

On 2/7/26 00:46, Bernhard Beschow wrote:
> Subclass TYPE_CAN_FLEXCAN, yielding TYPE_CAN_FLEXCAN2 and TYPE_CAN_FLEXCAN3.
> Since TYPE_CAN_FLEXCAN is now abstract, TYPE_FSL_IMX6 needs to use
> TYPE_CAN_FLEXCAN2. TYPE_CAN_FLEXCAN3 will be used in TYPE_FSL_IMX8MP.
> 
> Note that Linux performs 8 byte accesses on the i.MX8M Plus, therefore
> .max_access_size has to be adjusted. Otherwise this results in bus errors.
> 
> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
> ---
>   include/hw/net/flexcan.h |  4 ++-
>   hw/arm/fsl-imx6.c        |  2 +-
>   hw/net/can/flexcan.c     | 61 +++++++++++++++++++++++++++++++---------
>   3 files changed, 51 insertions(+), 16 deletions(-)
> 
> diff --git a/include/hw/net/flexcan.h b/include/hw/net/flexcan.h
> index 153afc1e03..32de7b904a 100644
> --- a/include/hw/net/flexcan.h
> +++ b/include/hw/net/flexcan.h
> @@ -139,7 +139,9 @@ typedef struct FlexcanState {
>   } FlexcanState;
>   
>   #define TYPE_CAN_FLEXCAN "flexcan"
> -
>   OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);
>   
> +#define TYPE_CAN_FLEXCAN2 "flexcan2"
> +#define TYPE_CAN_FLEXCAN3 "flexcan3"

> diff --git a/hw/net/can/flexcan.c b/hw/net/can/flexcan.c
> index 1ea459d9f6..d6a76c28ab 100644
> --- a/hw/net/can/flexcan.c
> +++ b/hw/net/can/flexcan.c
> @@ -1298,7 +1298,7 @@ static const struct MemoryRegionOps flexcan_ops = {
>       .endianness = DEVICE_LITTLE_ENDIAN,
>       .valid = {
>           .min_access_size = 1,
> -        .max_access_size = 4,
> +        .max_access_size = 8,

Isn't it better to keep 32-bit renaming as flexcan2_ops and widen to
64-bit for Plus version in a new flexcan8_ops struct?

>           .unaligned = true,
>           .accepts = flexcan_mem_accepts
>       },
> @@ -1324,16 +1324,26 @@ static int flexcan_connect_to_bus(FlexcanState *s, CanBusState *bus)
>       return 0;
>   }
>   
> -static void flexcan_init(Object *obj)
> +static void flexcan2_init(Object *obj)
>   {
>       FlexcanState *s = CAN_FLEXCAN(obj);
>   
>       memory_region_init_io(
> -        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN,
> +        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN2,
>           offsetof(FlexcanRegs, _reserved6)
>       );
>   }
>   
> +static void flexcan3_init(Object *obj)
> +{
> +    FlexcanState *s = CAN_FLEXCAN(obj);
> +
> +    memory_region_init_io(
> +        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN3,
> +        sizeof(FlexcanRegs)
> +    );
> +}


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN
  2026-07-02 12:45   ` Philippe Mathieu-Daudé
@ 2026-07-02 16:58     ` Bernhard Beschow
  0 siblings, 0 replies; 10+ messages in thread
From: Bernhard Beschow @ 2026-07-02 16:58 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Gaurav Sharma, Pavel Pisa, Jason Wang, Francisco Iglesias,
	Peter Maydell, qemu-arm, Matyas Bobek, Jean-Christophe Dubois,
	Vikram Garhwal, Paolo Bonzini, Pierrick Bouvier



Am 2. Juli 2026 12:45:24 UTC schrieb "Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>:
>Hi Bernhard,
>
>On 2/7/26 00:46, Bernhard Beschow wrote:
>> Subclass TYPE_CAN_FLEXCAN, yielding TYPE_CAN_FLEXCAN2 and TYPE_CAN_FLEXCAN3.
>> Since TYPE_CAN_FLEXCAN is now abstract, TYPE_FSL_IMX6 needs to use
>> TYPE_CAN_FLEXCAN2. TYPE_CAN_FLEXCAN3 will be used in TYPE_FSL_IMX8MP.
>> 
>> Note that Linux performs 8 byte accesses on the i.MX8M Plus, therefore
>> .max_access_size has to be adjusted. Otherwise this results in bus errors.
>> 
>> Signed-off-by: Bernhard Beschow <shentey@gmail.com>
>> ---
>>   include/hw/net/flexcan.h |  4 ++-
>>   hw/arm/fsl-imx6.c        |  2 +-
>>   hw/net/can/flexcan.c     | 61 +++++++++++++++++++++++++++++++---------
>>   3 files changed, 51 insertions(+), 16 deletions(-)
>> 
>> diff --git a/include/hw/net/flexcan.h b/include/hw/net/flexcan.h
>> index 153afc1e03..32de7b904a 100644
>> --- a/include/hw/net/flexcan.h
>> +++ b/include/hw/net/flexcan.h
>> @@ -139,7 +139,9 @@ typedef struct FlexcanState {
>>   } FlexcanState;
>>     #define TYPE_CAN_FLEXCAN "flexcan"
>> -
>>   OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);
>>   +#define TYPE_CAN_FLEXCAN2 "flexcan2"
>> +#define TYPE_CAN_FLEXCAN3 "flexcan3"
>
>> diff --git a/hw/net/can/flexcan.c b/hw/net/can/flexcan.c
>> index 1ea459d9f6..d6a76c28ab 100644
>> --- a/hw/net/can/flexcan.c
>> +++ b/hw/net/can/flexcan.c
>> @@ -1298,7 +1298,7 @@ static const struct MemoryRegionOps flexcan_ops = {
>>       .endianness = DEVICE_LITTLE_ENDIAN,
>>       .valid = {
>>           .min_access_size = 1,
>> -        .max_access_size = 4,
>> +        .max_access_size = 8,
>
>Isn't it better to keep 32-bit renaming as flexcan2_ops and widen to
>64-bit for Plus version in a new flexcan8_ops struct?

I agree. Will do in v2.

Best regards,
Bernhard

>
>>           .unaligned = true,
>>           .accepts = flexcan_mem_accepts
>>       },
>> @@ -1324,16 +1324,26 @@ static int flexcan_connect_to_bus(FlexcanState *s, CanBusState *bus)
>>       return 0;
>>   }
>>   -static void flexcan_init(Object *obj)
>> +static void flexcan2_init(Object *obj)
>>   {
>>       FlexcanState *s = CAN_FLEXCAN(obj);
>>         memory_region_init_io(
>> -        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN,
>> +        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN2,
>>           offsetof(FlexcanRegs, _reserved6)
>>       );
>>   }
>>   +static void flexcan3_init(Object *obj)
>> +{
>> +    FlexcanState *s = CAN_FLEXCAN(obj);
>> +
>> +    memory_region_init_io(
>> +        &s->iomem, obj, &flexcan_ops, s, TYPE_CAN_FLEXCAN3,
>> +        sizeof(FlexcanRegs)
>> +    );
>> +}


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-02 17:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-01 22:46 [PATCH 0/4] hw/arm/fsl-imx8mp: Add inital FlexCAN support Bernhard Beschow
2026-07-01 22:46 ` [PATCH 1/4] hw/net/can/flexcan: Subclass TYPE_CAN_FLEXCAN Bernhard Beschow
2026-07-02 12:45   ` Philippe Mathieu-Daudé
2026-07-02 16:58     ` Bernhard Beschow
2026-07-01 22:46 ` [PATCH 2/4] hw/arm/imx8mp-evk: Open code DEFINE_MACHINE_AARCH64 Bernhard Beschow
2026-07-02 12:23   ` Philippe Mathieu-Daudé
2026-07-01 22:46 ` [PATCH 3/4] hw/arm/imx8mp-evk: Introduce FslImx8mpEvkState Bernhard Beschow
2026-07-02 12:23   ` Philippe Mathieu-Daudé
2026-07-01 22:46 ` [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk Bernhard Beschow
2026-07-02 12:41   ` Philippe Mathieu-Daudé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.