qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Andrey Smirnov <andrew.smirnov@gmail.com>
To: qemu-arm@nongnu.org
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	qemu-devel@nongnu.org, yurovsky@gmail.com
Subject: [Qemu-devel] [PATCH 12/17] i.MX: Add i.MX7 CCM, PMU and ANALOG device
Date: Mon, 18 Sep 2017 12:50:55 -0700	[thread overview]
Message-ID: <20170918195100.17593-13-andrew.smirnov@gmail.com> (raw)
In-Reply-To: <20170918195100.17593-1-andrew.smirnov@gmail.com>

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org
Cc: yurovsky@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 hw/misc/Makefile.objs      |   1 +
 hw/misc/imx7_ccm.c         | 201 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/misc/imx7_ccm.h |  76 +++++++++++++++++
 3 files changed, 278 insertions(+)
 create mode 100644 hw/misc/imx7_ccm.c
 create mode 100644 include/hw/misc/imx7_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 29fb922cef..ac1be05a03 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -34,6 +34,7 @@ obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
+obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
new file mode 100644
index 0000000000..418aafe7cc
--- /dev/null
+++ b/hw/misc/imx7_ccm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/sizes.h"
+#include "hw/misc/imx7_ccm.h"
+#include "qemu/log.h"
+
+static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
+{
+    /*
+     * This function is "consumed" by GPT emulation code, however on
+     * i.MX7 each GPT block can have their own clock root. This means
+     * that this functions needs somehow to know requester's identity
+     * and the way to pass it: be it via additional IMXClk constants
+     * or by adding another argument to this method needs to be
+     * figured out
+     */
+    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
+                  TYPE_IMX7_CCM, __func__);
+    return 0;
+}
+
+static void imx7_ccm_reset(DeviceState *dev)
+{
+    IMX7CCMState *s = IMX7_CCM(dev);
+
+    s->analog[CCM_ANALOG_PLL_ARM]         = 0x00002042;
+    s->analog[CCM_ANALOG_PLL_DDR]         = 0x0060302c;
+    s->analog[CCM_ANALOG_PLL_DDR_SS]      = 0x00000000;
+    s->analog[CCM_ANALOG_PLL_DDR_NUM]     = 0x06aaac4d;
+    s->analog[CCM_ANALOG_PLL_DDR_DENOM]   = 0x100003ec;
+    s->analog[CCM_ANALOG_PLL_480]         = 0x00002000;    
+    s->analog[CCM_ANALOG_PLL_480A]        = 0x52605a56;
+    s->analog[CCM_ANALOG_PLL_480B]        = 0x52525216;
+    s->analog[CCM_ANALOG_PLL_ENET]        = 0x00001fc0;
+    s->analog[CCM_ANALOG_PLL_AUDIO]       = 0x0001301b;
+    s->analog[CCM_ANALOG_PLL_AUDIO_SS]    = 0x00000000;
+    s->analog[CCM_ANALOG_PLL_AUDIO_NUM]   = 0x05f5e100;
+    s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
+    s->analog[CCM_ANALOG_PLL_VIDEO]       = 0x0008201b;
+    s->analog[CCM_ANALOG_PLL_VIDEO_SS]    = 0x00000000;
+    s->analog[CCM_ANALOG_PLL_VIDEO_NUM]   = 0x0000f699;
+    s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
+    s->analog[CCM_ANALOG_PLL_MISC0]       = 0x00000000;
+
+    /* all PLLs need to be locked */
+    s->analog[CCM_ANALOG_PLL_ARM]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_DDR]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_480]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_480A]  |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_480B]  |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_ENET]  |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_MISC0] |= CCM_ANALOG_PLL_LOCK;
+}
+
+#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 imx7_set_clr_tog_read(void *opaque, hwaddr offset,
+                                      unsigned size)
+{
+    const uint32_t *mmio = opaque;
+
+    return (uint64_t)mmio[CCM_INDEX(offset)];
+}
+
+static void imx7_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 imx7_set_clr_tog_ops = {
+    .read = imx7_set_clr_tog_read,
+    .write = imx7_set_clr_tog_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        /*
+         * 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 void imx7_ccm_init(Object *obj)
+{
+    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+    IMX7CCMState *s = IMX7_CCM(obj);
+
+    memory_region_init(&s->mmio.container, obj, TYPE_IMX7_CCM,
+                       0x30000);
+
+    memory_region_init_io(&s->mmio.analog,
+                          obj,
+                          &imx7_set_clr_tog_ops,
+                          s->analog,
+                          TYPE_IMX7_CCM ".analog",
+                          sizeof(s->analog));
+
+    memory_region_add_subregion(&s->mmio.container,
+                                0x60, &s->mmio.analog);
+
+    memory_region_init_io(&s->mmio.pmu,
+                          obj,
+                          &imx7_set_clr_tog_ops,
+                          s->pmu,
+                          TYPE_IMX7_CCM ".pmu",
+                          sizeof(s->pmu));
+
+    memory_region_add_subregion(&s->mmio.container,
+                                0x200, &s->mmio.pmu);
+    
+    memory_region_init_io(&s->mmio.ccm,
+                          obj,
+                          &imx7_set_clr_tog_ops,
+                          s->ccm,
+                          TYPE_IMX7_CCM ".ccm",
+                          sizeof(s->ccm));
+
+    memory_region_add_subregion(&s->mmio.container,
+                                0x20000, &s->mmio.ccm);
+
+    sysbus_init_mmio(sd, &s->mmio.container);
+}
+
+static const VMStateDescription vmstate_imx7_ccm = {
+    .name = TYPE_IMX7_CCM,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(ccm, IMX7CCMState, CCM_MAX),
+        VMSTATE_UINT32_ARRAY(analog, IMX7CCMState, CCM_ANALOG_MAX),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static void imx7_ccm_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
+
+    dc->reset = imx7_ccm_reset;
+    dc->vmsd  = &vmstate_imx7_ccm;
+    dc->desc  = "i.MX7 Clock Control Module";
+
+    ccm->get_clock_frequency = imx7_ccm_get_clock_frequency;
+}
+
+static const TypeInfo imx7_ccm_info = {
+    .name          = TYPE_IMX7_CCM,
+    .parent        = TYPE_IMX_CCM,
+    .instance_size = sizeof(IMX7CCMState),
+    .instance_init = imx7_ccm_init,
+    .class_init    = imx7_ccm_class_init,
+};
+
+static void imx7_ccm_register_type(void)
+{
+    type_register_static(&imx7_ccm_info);
+}
+type_init(imx7_ccm_register_type)
diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h
new file mode 100644
index 0000000000..72ca10a04a
--- /dev/null
+++ b/include/hw/misc/imx7_ccm.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX7_CCM_H
+#define IMX7_CCM_H
+
+#include "hw/misc/imx_ccm.h"
+#include "qemu/bitops.h"
+
+#define REG_SET_CLR_TOG(name)  name, name##_SET, name##_CLR, name##_TOG
+
+enum IMX7AnalogRegisters {
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_ARM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_DDR),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_DDR_SS),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_DDR_NUM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_DDR_DENOM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_480),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_480A),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_480B),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_ENET),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_AUDIO),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_AUDIO_SS),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_AUDIO_NUM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_AUDIO_DENOM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_VIDEO),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_VIDEO_SS),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_VIDEO_NUM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_VIDEO_DENOM),
+    REG_SET_CLR_TOG(CCM_ANALOG_PLL_MISC0),
+
+    CCM_ANALOG_MAX,
+
+    CCM_ANALOG_PLL_LOCK = BIT(31)
+};
+
+enum IMX7CCMRegisters {
+    CCM_MAX = 0xBC80 / sizeof(uint32_t),
+};
+
+enum IMX7PMURegisters {
+    PMU_MAX = 0x140 / sizeof(uint32_t),
+};
+
+#undef REG_SET_CLR_TOG
+
+#define TYPE_IMX7_CCM "imx7.ccm"
+#define IMX7_CCM(obj) OBJECT_CHECK(IMX7CCMState, (obj), TYPE_IMX7_CCM)
+
+typedef struct IMX6CCMState {
+    /* <private> */
+    IMXCCMState parent_obj;
+
+    /* <public> */
+    struct {
+        MemoryRegion container;
+        MemoryRegion ccm;
+        MemoryRegion pmu;
+        MemoryRegion analog;
+    } mmio;
+
+    uint32_t ccm[CCM_MAX];
+    uint32_t pmu[PMU_MAX];
+    uint32_t analog[CCM_ANALOG_MAX];
+
+} IMX7CCMState;
+
+#endif /* IMX7_CCM_H */
-- 
2.13.5

  parent reply	other threads:[~2017-09-18 19:51 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-18 19:50 [Qemu-devel] [PATCH 00/17] Initial i.MX7 support Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 01/17] imx_fec: Do not link to netdev Andrey Smirnov
2017-10-06 13:46   ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 02/17] imx_fec: Do not calculate FEC Andrey Smirnov
2017-10-06 13:48   ` Peter Maydell
2017-10-09 14:47     ` Andrey Smirnov
2017-10-09 17:03       ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 03/17] imx_fec: Refactor imx_eth_enable_rx() Andrey Smirnov
2017-10-06 13:49   ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 04/17] imx_fec: Change queue flushing heuristics Andrey Smirnov
2017-09-22  7:27   ` Jason Wang
2017-09-25 18:10     ` Andrey Smirnov
2017-10-06 13:56   ` Peter Maydell
2017-10-09 14:57     ` Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 05/17] imx_fec: Use ENET_FTRL to determine truncation length Andrey Smirnov
2017-09-30  0:17   ` Philippe Mathieu-Daudé
2017-10-06 14:00     ` Peter Maydell
2017-10-09 15:19       ` Andrey Smirnov
2017-10-06 14:03   ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 06/17] imx_fec: Use MIN instead of explicit ternary operator Andrey Smirnov
2017-09-30  0:19   ` [Qemu-devel] [Qemu-arm] " Philippe Mathieu-Daudé
2017-09-18 19:50 ` [Qemu-devel] [PATCH 07/17] imx_fec: Emulate SHIFT16 in ENETx_RACC Andrey Smirnov
2017-10-06 14:02   ` Peter Maydell
2017-10-09 15:22     ` Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 08/17] imx_fec: Add support for multiple Tx DMA rings Andrey Smirnov
2017-09-22  7:33   ` Jason Wang
2017-09-25 18:23     ` Andrey Smirnov
2017-10-06 14:10   ` Peter Maydell
2017-10-09 15:38     ` Andrey Smirnov
2017-10-09 17:06       ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 09/17] imx_fec: Use correct length for packet size Andrey Smirnov
2017-10-06 14:12   ` Peter Maydell
2017-09-18 19:50 ` [Qemu-devel] [PATCH 10/17] sdhci: Add i.MX specific subtype of SDHCI Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 11/17] sdhci: Implement write method of ACMD12ERRSTS register Andrey Smirnov
2017-09-18 19:50 ` Andrey Smirnov [this message]
2017-09-18 19:50 ` [Qemu-devel] [PATCH 13/17] i.MX: Add code to emulate i.MX2 watchdog IP block Andrey Smirnov
2017-10-06 14:22   ` Peter Maydell
2017-10-09 15:54     ` Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 14/17] i.MX7: Add code to emulate SNVS IP-block Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 15/17] include/qemu: Add sizes.h from Linux Andrey Smirnov
2017-10-06 14:13   ` Peter Maydell
2017-10-09 15:55     ` Andrey Smirnov
2017-09-18 19:50 ` [Qemu-devel] [PATCH 16/17] i.MX: Add i.MX7 SOC implementation Andrey Smirnov
2017-10-06 14:38   ` Peter Maydell
2017-10-09 16:18     ` Andrey Smirnov
2017-10-09 17:09       ` Peter Maydell
2017-09-18 19:51 ` [Qemu-devel] [PATCH 17/17] Implement support for i.MX7 Sabre board Andrey Smirnov
2017-10-06 14:42   ` Peter Maydell
2017-10-09 16:30     ` Andrey Smirnov
2017-09-18 21:00 ` [Qemu-devel] [PATCH 00/17] Initial i.MX7 support no-reply
2017-10-06 14:46 ` Peter Maydell

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=20170918195100.17593-13-andrew.smirnov@gmail.com \
    --to=andrew.smirnov@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=yurovsky@gmail.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 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).