From: Bernhard Beschow <shentey@gmail.com>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Alistair Francis" <alistair@alistair23.me>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Jean-Christophe Dubois" <jcd@tribudubois.net>,
qemu-arm@nongnu.org, "Andrey Smirnov" <andrew.smirnov@gmail.com>,
"Edgar E. Iglesias" <edgar.iglesias@gmail.com>,
"Bernhard Beschow" <shentey@gmail.com>
Subject: [PATCH 06/21] hw/arm/fsl-imx8mp: Implement clock tree
Date: Mon, 20 Jan 2025 21:37:33 +0100 [thread overview]
Message-ID: <20250120203748.4687-7-shentey@gmail.com> (raw)
In-Reply-To: <20250120203748.4687-1-shentey@gmail.com>
Fixes quite a few stack traces during the Linux boot process. Also provides the
clocks for devices added later, e.g. enet1.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
---
MAINTAINERS | 2 +
docs/system/arm/imx8mp-evk.rst | 1 +
include/hw/arm/fsl-imx8mp.h | 3 +
include/hw/misc/imx8mp_ccm.h | 97 ++++++++++
hw/arm/fsl-imx8mp.c | 20 +++
hw/misc/imx8mp_ccm.c | 315 +++++++++++++++++++++++++++++++++
hw/misc/meson.build | 1 +
7 files changed, 439 insertions(+)
create mode 100644 include/hw/misc/imx8mp_ccm.h
create mode 100644 hw/misc/imx8mp_ccm.c
diff --git a/MAINTAINERS b/MAINTAINERS
index cace8cf25b..3c60581fe7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -825,7 +825,9 @@ L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/imx8mp-evk.c
F: hw/arm/fsl-imx8mp.c
+F: hw/misc/imx8mp_*.c
F: include/hw/arm/fsl-imx8mp.h
+F: include/hw/misc/imx8mp_*.h
F: docs/system/arm/imx8mp-evk.rst
MPS2 / MPS3
diff --git a/docs/system/arm/imx8mp-evk.rst b/docs/system/arm/imx8mp-evk.rst
index 184f1ef7e6..3de4a73530 100644
--- a/docs/system/arm/imx8mp-evk.rst
+++ b/docs/system/arm/imx8mp-evk.rst
@@ -13,6 +13,7 @@ The ``imx8mp-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/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h
index 57e23d1b69..979cdbd8c4 100644
--- a/include/hw/arm/fsl-imx8mp.h
+++ b/include/hw/arm/fsl-imx8mp.h
@@ -12,6 +12,7 @@
#include "cpu.h"
#include "hw/char/imx_serial.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/imx8mp_ccm.h"
#include "qom/object.h"
#include "qemu/units.h"
@@ -32,6 +33,8 @@ struct FslImx8mpState {
ARMCPU cpu[FSL_IMX8MP_NUM_CPUS];
GICv3State gic;
+ IMX8MPCCMState ccm;
+ IMX8MPAnalogState analog;
IMXSerialState uart[FSL_IMX8MP_NUM_UARTS];
};
diff --git a/include/hw/misc/imx8mp_ccm.h b/include/hw/misc/imx8mp_ccm.h
new file mode 100644
index 0000000000..2378c157de
--- /dev/null
+++ b/include/hw/misc/imx8mp_ccm.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com>
+ *
+ * i.MX8MP CCM, ANALOG IP blocks emulation code
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef IMX8MP_CCM_H
+#define IMX8MP_CCM_H
+
+#include "hw/misc/imx_ccm.h"
+#include "qom/object.h"
+
+enum IMX8MPAnalogRegisters {
+ ANALOG_AUDIO_PLL1_GEN_CTRL = 0x000 / 4,
+ ANALOG_AUDIO_PLL1_FDIV_CTL0 = 0x004 / 4,
+ ANALOG_AUDIO_PLL1_FDIV_CTL1 = 0x008 / 4,
+ ANALOG_AUDIO_PLL1_SSCG_CTRL = 0x00c / 4,
+ ANALOG_AUDIO_PLL1_MNIT_CTRL = 0x010 / 4,
+ ANALOG_AUDIO_PLL2_GEN_CTRL = 0x014 / 4,
+ ANALOG_AUDIO_PLL2_FDIV_CTL0 = 0x018 / 4,
+ ANALOG_AUDIO_PLL2_FDIV_CTL1 = 0x01c / 4,
+ ANALOG_AUDIO_PLL2_SSCG_CTRL = 0x020 / 4,
+ ANALOG_AUDIO_PLL2_MNIT_CTRL = 0x024 / 4,
+ ANALOG_VIDEO_PLL1_GEN_CTRL = 0x028 / 4,
+ ANALOG_VIDEO_PLL1_FDIV_CTL0 = 0x02c / 4,
+ ANALOG_VIDEO_PLL1_FDIV_CTL1 = 0x030 / 4,
+ ANALOG_VIDEO_PLL1_SSCG_CTRL = 0x034 / 4,
+ ANALOG_VIDEO_PLL1_MNIT_CTRL = 0x038 / 4,
+ ANALOG_DRAM_PLL_GEN_CTRL = 0x050 / 4,
+ ANALOG_DRAM_PLL_FDIV_CTL0 = 0x054 / 4,
+ ANALOG_DRAM_PLL_FDIV_CTL1 = 0x058 / 4,
+ ANALOG_DRAM_PLL_SSCG_CTRL = 0x05c / 4,
+ ANALOG_DRAM_PLL_MNIT_CTRL = 0x060 / 4,
+ ANALOG_GPU_PLL_GEN_CTRL = 0x064 / 4,
+ ANALOG_GPU_PLL_FDIV_CTL0 = 0x068 / 4,
+ ANALOG_GPU_PLL_LOCKD_CTRL = 0x06c / 4,
+ ANALOG_GPU_PLL_MNIT_CTRL = 0x070 / 4,
+ ANALOG_VPU_PLL_GEN_CTRL = 0x074 / 4,
+ ANALOG_VPU_PLL_FDIV_CTL0 = 0x078 / 4,
+ ANALOG_VPU_PLL_LOCKD_CTRL = 0x07c / 4,
+ ANALOG_VPU_PLL_MNIT_CTRL = 0x080 / 4,
+ ANALOG_ARM_PLL_GEN_CTRL = 0x084 / 4,
+ ANALOG_ARM_PLL_FDIV_CTL0 = 0x088 / 4,
+ ANALOG_ARM_PLL_LOCKD_CTRL = 0x08c / 4,
+ ANALOG_ARM_PLL_MNIT_CTRL = 0x090 / 4,
+ ANALOG_SYS_PLL1_GEN_CTRL = 0x094 / 4,
+ ANALOG_SYS_PLL1_FDIV_CTL0 = 0x098 / 4,
+ ANALOG_SYS_PLL1_LOCKD_CTRL = 0x09c / 4,
+ ANALOG_SYS_PLL1_MNIT_CTRL = 0x100 / 4,
+ ANALOG_SYS_PLL2_GEN_CTRL = 0x104 / 4,
+ ANALOG_SYS_PLL2_FDIV_CTL0 = 0x108 / 4,
+ ANALOG_SYS_PLL2_LOCKD_CTRL = 0x10c / 4,
+ ANALOG_SYS_PLL2_MNIT_CTRL = 0x110 / 4,
+ ANALOG_SYS_PLL3_GEN_CTRL = 0x114 / 4,
+ ANALOG_SYS_PLL3_FDIV_CTL0 = 0x118 / 4,
+ ANALOG_SYS_PLL3_LOCKD_CTRL = 0x11c / 4,
+ ANALOG_SYS_PLL3_MNIT_CTRL = 0x120 / 4,
+ ANALOG_OSC_MISC_CFG = 0x124 / 4,
+ ANALOG_ANAMIX_PLL_MNIT_CTL = 0x128 / 4,
+
+ ANALOG_DIGPROG = 0x800 / 4,
+ ANALOG_MAX,
+};
+
+enum IMX8MPCCMRegisters {
+ CCM_MAX = 0xc6fc / sizeof(uint32_t) + 1,
+};
+
+#define TYPE_IMX8MP_CCM "imx8mp.ccm"
+OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPCCMState, IMX8MP_CCM)
+
+struct IMX8MPCCMState {
+ IMXCCMState parent_obj;
+
+ MemoryRegion iomem;
+
+ uint32_t ccm[CCM_MAX];
+};
+
+
+#define TYPE_IMX8MP_ANALOG "imx8mp.analog"
+OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPAnalogState, IMX8MP_ANALOG)
+
+struct IMX8MPAnalogState {
+ IMXCCMState parent_obj;
+
+ struct {
+ MemoryRegion container;
+ MemoryRegion analog;
+ } mmio;
+
+ uint32_t analog[ANALOG_MAX];
+};
+
+#endif /* IMX8MP_CCM_H */
diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c
index 6b2cdb2c0a..311b8ee0cd 100644
--- a/hw/arm/fsl-imx8mp.c
+++ b/hw/arm/fsl-imx8mp.c
@@ -200,6 +200,10 @@ static void fsl_imx8mp_init(Object *obj)
object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GICV3);
+ 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_IMX8MP_NUM_UARTS; i++) {
snprintf(name, NAME_SIZE, "uart%d", i + 1);
object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
@@ -308,6 +312,20 @@ static void fsl_imx8mp_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_imx8mp_memmap[FSL_IMX8MP_CCM].addr);
+
+ /* Analog */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->analog), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0,
+ fsl_imx8mp_memmap[FSL_IMX8MP_ANA_PLL].addr);
+
/* UARTs */
for (i = 0; i < FSL_IMX8MP_NUM_UARTS; i++) {
static const struct {
@@ -333,6 +351,8 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp)
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(fsl_imx8mp_memmap); i++) {
switch (i) {
+ case FSL_IMX8MP_ANA_PLL:
+ case FSL_IMX8MP_CCM:
case FSL_IMX8MP_GIC_DIST:
case FSL_IMX8MP_GIC_REDIST:
case FSL_IMX8MP_RAM:
diff --git a/hw/misc/imx8mp_ccm.c b/hw/misc/imx8mp_ccm.c
new file mode 100644
index 0000000000..17658eb876
--- /dev/null
+++ b/hw/misc/imx8mp_ccm.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com>
+ *
+ * i.MX8MP CCM, PMU and ANALOG IP blocks emulation code
+ *
+ * Based on hw/misc/imx7_ccm.c
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+
+#include "hw/misc/imx8mp_ccm.h"
+#include "migration/vmstate.h"
+
+#include "trace.h"
+
+#define CKIH_FREQ 16000000 /* 16MHz crystal input */
+
+#define ANALOG_PLL_LOCK BIT(31)
+
+static void imx8mp_analog_reset(DeviceState *dev)
+{
+ IMX8MPAnalogState *s = IMX8MP_ANALOG(dev);
+
+ memset(s->analog, 0, sizeof(s->analog));
+
+ s->analog[ANALOG_AUDIO_PLL1_GEN_CTRL] = 0x00002010;
+ s->analog[ANALOG_AUDIO_PLL1_FDIV_CTL0] = 0x00145032;
+ s->analog[ANALOG_AUDIO_PLL1_FDIV_CTL1] = 0x00000000;
+ s->analog[ANALOG_AUDIO_PLL1_SSCG_CTRL] = 0x00000000;
+ s->analog[ANALOG_AUDIO_PLL1_MNIT_CTRL] = 0x00100103;
+ s->analog[ANALOG_AUDIO_PLL2_GEN_CTRL] = 0x00002010;
+ s->analog[ANALOG_AUDIO_PLL2_FDIV_CTL0] = 0x00145032;
+ s->analog[ANALOG_AUDIO_PLL2_FDIV_CTL1] = 0x00000000;
+ s->analog[ANALOG_AUDIO_PLL2_SSCG_CTRL] = 0x00000000;
+ s->analog[ANALOG_AUDIO_PLL2_MNIT_CTRL] = 0x00100103;
+ s->analog[ANALOG_VIDEO_PLL1_GEN_CTRL] = 0x00002010;
+ s->analog[ANALOG_VIDEO_PLL1_FDIV_CTL0] = 0x00145032;
+ s->analog[ANALOG_VIDEO_PLL1_FDIV_CTL1] = 0x00000000;
+ s->analog[ANALOG_VIDEO_PLL1_SSCG_CTRL] = 0x00000000;
+ s->analog[ANALOG_VIDEO_PLL1_MNIT_CTRL] = 0x00100103;
+ s->analog[ANALOG_DRAM_PLL_GEN_CTRL] = 0x00002010;
+ s->analog[ANALOG_DRAM_PLL_FDIV_CTL0] = 0x0012c032;
+ s->analog[ANALOG_DRAM_PLL_FDIV_CTL1] = 0x00000000;
+ s->analog[ANALOG_DRAM_PLL_SSCG_CTRL] = 0x00000000;
+ s->analog[ANALOG_DRAM_PLL_MNIT_CTRL] = 0x00100103;
+ s->analog[ANALOG_GPU_PLL_GEN_CTRL] = 0x00000810;
+ s->analog[ANALOG_GPU_PLL_FDIV_CTL0] = 0x000c8031;
+ s->analog[ANALOG_GPU_PLL_LOCKD_CTRL] = 0x0010003f;
+ s->analog[ANALOG_GPU_PLL_MNIT_CTRL] = 0x00280081;
+ s->analog[ANALOG_VPU_PLL_GEN_CTRL] = 0x00000810;
+ s->analog[ANALOG_VPU_PLL_FDIV_CTL0] = 0x0012c032;
+ 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;
+ s->analog[ANALOG_ARM_PLL_LOCKD_CTRL] = 0x0010003f;
+ s->analog[ANALOG_ARM_PLL_MNIT_CTRL] = 0x00280081;
+ s->analog[ANALOG_SYS_PLL1_GEN_CTRL] = 0x0aaaa810;
+ s->analog[ANALOG_SYS_PLL1_FDIV_CTL0] = 0x00190032;
+ s->analog[ANALOG_SYS_PLL1_LOCKD_CTRL] = 0x0010003f;
+ s->analog[ANALOG_SYS_PLL1_MNIT_CTRL] = 0x00280081;
+ s->analog[ANALOG_SYS_PLL2_GEN_CTRL] = 0x0aaaa810;
+ s->analog[ANALOG_SYS_PLL2_FDIV_CTL0] = 0x000fa031;
+ s->analog[ANALOG_SYS_PLL2_LOCKD_CTRL] = 0x0010003f;
+ s->analog[ANALOG_SYS_PLL2_MNIT_CTRL] = 0x00280081;
+ s->analog[ANALOG_SYS_PLL3_GEN_CTRL] = 0x00000810;
+ s->analog[ANALOG_SYS_PLL3_FDIV_CTL0] = 0x000fa031;
+ s->analog[ANALOG_SYS_PLL3_LOCKD_CTRL] = 0x0010003f;
+ s->analog[ANALOG_SYS_PLL3_MNIT_CTRL] = 0x00280081;
+ s->analog[ANALOG_OSC_MISC_CFG] = 0x00000000;
+ s->analog[ANALOG_ANAMIX_PLL_MNIT_CTL] = 0x00000000;
+ s->analog[ANALOG_DIGPROG] = 0x00824010;
+
+ /* all PLLs need to be locked */
+ s->analog[ANALOG_AUDIO_PLL1_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_AUDIO_PLL2_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_VIDEO_PLL1_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_DRAM_PLL_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_GPU_PLL_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_VPU_PLL_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_ARM_PLL_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_SYS_PLL1_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_SYS_PLL2_GEN_CTRL] |= ANALOG_PLL_LOCK;
+ s->analog[ANALOG_SYS_PLL3_GEN_CTRL] |= ANALOG_PLL_LOCK;
+}
+
+static void imx8mp_ccm_reset(DeviceState *dev)
+{
+ IMX8MPCCMState *s = IMX8MP_CCM(dev);
+
+ memset(s->ccm, 0, sizeof(s->ccm));
+}
+
+#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
+#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
+
+enum {
+ CCM_BITOP_NONE = 0x00,
+ CCM_BITOP_SET = 0x04,
+ CCM_BITOP_CLR = 0x08,
+ CCM_BITOP_TOG = 0x0C,
+};
+
+static uint64_t imx8mp_set_clr_tog_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ const uint32_t *mmio = opaque;
+
+ return mmio[CCM_INDEX(offset)];
+}
+
+static void imx8mp_set_clr_tog_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ const uint8_t bitop = CCM_BITOP(offset);
+ const uint32_t index = CCM_INDEX(offset);
+ uint32_t *mmio = opaque;
+
+ switch (bitop) {
+ case CCM_BITOP_NONE:
+ mmio[index] = value;
+ break;
+ case CCM_BITOP_SET:
+ mmio[index] |= value;
+ break;
+ case CCM_BITOP_CLR:
+ mmio[index] &= ~value;
+ break;
+ case CCM_BITOP_TOG:
+ mmio[index] ^= value;
+ break;
+ };
+}
+
+static const struct MemoryRegionOps imx8mp_set_clr_tog_ops = {
+ .read = imx8mp_set_clr_tog_read,
+ .write = imx8mp_set_clr_tog_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ /*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static uint64_t imx8mp_analog_read(void *opaque, hwaddr offset, unsigned size)
+{
+ IMX8MPAnalogState *s = opaque;
+
+ return s->analog[offset >> 2];
+}
+
+static void imx8mp_analog_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ IMX8MPAnalogState *s = opaque;
+
+ if (offset >> 2 == ANALOG_DIGPROG) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Guest write to read-only ANALOG_DIGPROG register\n");
+ } else {
+ s->analog[offset >> 2] = value;
+ }
+}
+
+static const struct MemoryRegionOps imx8mp_analog_ops = {
+ .read = imx8mp_analog_read,
+ .write = imx8mp_analog_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static void imx8mp_ccm_init(Object *obj)
+{
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+ IMX8MPCCMState *s = IMX8MP_CCM(obj);
+
+ memory_region_init_io(&s->iomem,
+ obj,
+ &imx8mp_set_clr_tog_ops,
+ s->ccm,
+ TYPE_IMX8MP_CCM ".ccm",
+ sizeof(s->ccm));
+
+ sysbus_init_mmio(sd, &s->iomem);
+}
+
+static void imx8mp_analog_init(Object *obj)
+{
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+ IMX8MPAnalogState *s = IMX8MP_ANALOG(obj);
+
+ memory_region_init(&s->mmio.container, obj, TYPE_IMX8MP_ANALOG, 0x10000);
+
+ memory_region_init_io(&s->mmio.analog, obj, &imx8mp_analog_ops, s,
+ TYPE_IMX8MP_ANALOG, sizeof(s->analog));
+ memory_region_add_subregion(&s->mmio.container, 0, &s->mmio.analog);
+
+ sysbus_init_mmio(sd, &s->mmio.container);
+}
+
+static const VMStateDescription vmstate_imx8mp_ccm = {
+ .name = TYPE_IMX8MP_CCM,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(ccm, IMX8MPCCMState, CCM_MAX),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static uint32_t imx8mp_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
+{
+ /*
+ * This function is "consumed" by GPT emulation code. Some clocks
+ * have fixed frequencies and we can provide requested frequency
+ * easily. However for CCM provided clocks (like IPG) each GPT
+ * timer can have its own clock root.
+ * This means we need additional information when calling this
+ * function to know the requester's identity.
+ */
+ uint32_t freq = 0;
+
+ switch (clock) {
+ case CLK_NONE:
+ break;
+ case CLK_32k:
+ freq = CKIL_FREQ;
+ break;
+ case CLK_HIGH:
+ freq = CKIH_FREQ;
+ break;
+ case CLK_IPG:
+ case CLK_IPG_HIGH:
+ /*
+ * For now we don't have a way to figure out the device this
+ * function is called for. Until then the IPG derived clocks
+ * are left unimplemented.
+ */
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
+ TYPE_IMX8MP_CCM, __func__, clock);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
+ TYPE_IMX8MP_CCM, __func__, clock);
+ break;
+ }
+
+ trace_ccm_clock_freq(clock, freq);
+
+ return freq;
+}
+
+static void imx8mp_ccm_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
+
+ device_class_set_legacy_reset(dc, imx8mp_ccm_reset);
+ dc->vmsd = &vmstate_imx8mp_ccm;
+ dc->desc = "i.MX8MP Clock Control Module";
+
+ ccm->get_clock_frequency = imx8mp_ccm_get_clock_frequency;
+}
+
+static const VMStateDescription vmstate_imx8mp_analog = {
+ .name = TYPE_IMX8MP_ANALOG,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(analog, IMX8MPAnalogState, ANALOG_MAX),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static void imx8mp_analog_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ device_class_set_legacy_reset(dc, imx8mp_analog_reset);
+ dc->vmsd = &vmstate_imx8mp_analog;
+ dc->desc = "i.MX8MP Analog Module";
+}
+
+static const TypeInfo imx8mp_ccm_types[] = {
+ {
+ .name = TYPE_IMX8MP_CCM,
+ .parent = TYPE_IMX_CCM,
+ .instance_size = sizeof(IMX8MPCCMState),
+ .instance_init = imx8mp_ccm_init,
+ .class_init = imx8mp_ccm_class_init,
+ },
+ {
+ .name = TYPE_IMX8MP_ANALOG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(IMX8MPAnalogState),
+ .instance_init = imx8mp_analog_init,
+ .class_init = imx8mp_analog_class_init,
+ }
+};
+
+DEFINE_TYPES(imx8mp_ccm_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 55f493521b..d556965821 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -65,6 +65,7 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
'imx7_src.c',
'imx7_gpr.c',
'imx7_snvs.c',
+ 'imx8mp_ccm.c',
'imx_ccm.c',
'imx_rngc.c',
))
--
2.48.1
next prev parent reply other threads:[~2025-01-20 20:39 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-20 20:37 [PATCH 00/21] Add i.MX 8M Plus EVK machine Bernhard Beschow
2025-01-20 20:37 ` [PATCH 01/21] hw/char/imx_serial: Fix reset value of UFCR register Bernhard Beschow
2025-01-20 20:37 ` [PATCH 02/21] hw/char/imx_serial: Update all state before restarting ageing timer Bernhard Beschow
2025-01-20 20:37 ` [PATCH 03/21] hw/pci-host/designware: Expose MSI IRQ Bernhard Beschow
2025-01-20 20:37 ` [PATCH 04/21] hw/usb/hcd-dwc3: Align global registers size with Linux Bernhard Beschow
2025-01-28 14:21 ` Peter Maydell
2025-01-20 20:37 ` [PATCH 05/21] hw/arm: Add i.MX 8M Plus EVK board Bernhard Beschow
2025-01-28 14:29 ` Peter Maydell
2025-01-28 22:16 ` Bernhard Beschow
2025-01-29 12:17 ` Peter Maydell
2025-01-29 13:04 ` Bernhard Beschow
2025-01-20 20:37 ` Bernhard Beschow [this message]
2025-01-28 14:35 ` [PATCH 06/21] hw/arm/fsl-imx8mp: Implement clock tree Peter Maydell
2025-01-28 21:53 ` Bernhard Beschow
2025-01-20 20:37 ` [PATCH 07/21] hw/arm/fsl-imx8mp: Add SNVS Bernhard Beschow
2025-01-28 14:31 ` Peter Maydell
2025-01-20 20:37 ` [PATCH 08/21] hw/arm/fsl-imx8mp: Add USDHC storage controllers Bernhard Beschow
2025-01-21 2:52 ` BALATON Zoltan
2025-02-03 23:01 ` Bernhard Beschow
2025-01-20 20:37 ` [PATCH 09/21] hw/arm/fsl-imx8mp: Add PCIe support Bernhard Beschow
2025-01-28 14:33 ` Peter Maydell
2025-01-28 22:04 ` Bernhard Beschow
2025-01-29 17:54 ` BALATON Zoltan
2025-02-01 14:45 ` Bernhard Beschow
2025-01-20 20:37 ` [PATCH 10/21] hw/arm/fsl-imx8mp: Add GPIO controllers Bernhard Beschow
2025-01-20 20:37 ` [PATCH 11/21] hw/arm/fsl-imx8mp: Add I2C controllers Bernhard Beschow
2025-01-20 20:37 ` [PATCH 12/21] hw/arm/fsl-imx8mp: Add SPI controllers Bernhard Beschow
2025-01-20 20:37 ` [PATCH 13/21] hw/arm/fsl-imx8mp: Add watchdog support Bernhard Beschow
2025-01-20 20:37 ` [PATCH 14/21] hw/arm/fsl-imx8mp: Implement gneral purpose timers Bernhard Beschow
2025-01-20 20:37 ` [PATCH 15/21] hw/arm/fsl-imx8mp: Add Ethernet controller Bernhard Beschow
2025-01-20 20:37 ` [PATCH 16/21] hw/arm/fsl-imx8mp: Add USB support Bernhard Beschow
2025-01-20 20:37 ` [PATCH 17/21] hw/arm/fsl-imx8mp: Add boot ROM Bernhard Beschow
2025-01-21 3:00 ` BALATON Zoltan
2025-01-21 21:03 ` Bernhard Beschow
2025-01-20 20:37 ` [PATCH 18/21] hw/arm/fsl-imx8mp: Add on-chip RAM Bernhard Beschow
2025-01-20 20:37 ` [PATCH 19/21] hw/rtc: Add Ricoh RS5C372 RTC emulation Bernhard Beschow
2025-01-20 20:37 ` [PATCH 20/21] hw/i2c: Import TCA6416 emulation from Xilinx Bernhard Beschow
2025-01-21 3:07 ` BALATON Zoltan
2025-01-28 22:20 ` Bernhard Beschow
2025-01-30 1:14 ` Corey Minyard
2025-01-30 23:05 ` Philippe Mathieu-Daudé
2025-02-01 15:28 ` Bernhard Beschow
2025-02-02 17:09 ` Philippe Mathieu-Daudé
2025-02-03 5:42 ` Dmitriy Sharikhin
2025-02-04 8:13 ` Bernhard Beschow
2025-02-17 18:06 ` Bernhard Beschow
2025-02-03 22:38 ` Bernhard Beschow
2025-01-20 20:37 ` [PATCH 21/21] hw/gpio/imx_gpio: Don't clear input GPIO values upon reset Bernhard Beschow
2025-01-28 14:33 ` Gustavo Romero
2025-02-03 23:06 ` Bernhard Beschow
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=20250120203748.4687-7-shentey@gmail.com \
--to=shentey@gmail.com \
--cc=alistair@alistair23.me \
--cc=andrew.smirnov@gmail.com \
--cc=edgar.iglesias@gmail.com \
--cc=jcd@tribudubois.net \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/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.