From: Bernhard Beschow <shentey@gmail.com>
To: qemu-devel@nongnu.org
Cc: Gaurav Sharma <gaurav.sharma_7@nxp.com>,
Bernhard Beschow <shentey@gmail.com>,
Pavel Pisa <pisa@cmp.felk.cvut.cz>,
Jason Wang <jasowang@redhat.com>,
Francisco Iglesias <francisco.iglesias@amd.com>,
Peter Maydell <peter.maydell@linaro.org>,
qemu-arm@nongnu.org, Matyas Bobek <matyas.bobek@gmail.com>,
Jean-Christophe Dubois <jcd@tribudubois.net>,
Vikram Garhwal <vikram.garhwal@bytedance.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Subject: [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk
Date: Thu, 2 Jul 2026 00:46:12 +0200 [thread overview]
Message-ID: <20260701224612.48342-5-shentey@gmail.com> (raw)
In-Reply-To: <20260701224612.48342-1-shentey@gmail.com>
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
next prev parent reply other threads:[~2026-07-01 22:48 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Bernhard Beschow [this message]
2026-07-02 12:41 ` [PATCH 4/4] hw/arm: Add basic FlexCAN3 support to TYPE_FSL_IMX8MP and imx8mp-evk Philippe Mathieu-Daudé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701224612.48342-5-shentey@gmail.com \
--to=shentey@gmail.com \
--cc=francisco.iglesias@amd.com \
--cc=gaurav.sharma_7@nxp.com \
--cc=jasowang@redhat.com \
--cc=jcd@tribudubois.net \
--cc=matyas.bobek@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=pisa@cmp.felk.cvut.cz \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vikram.garhwal@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.