From: Guenter Roeck <linux@roeck-us.net>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org,
Guenter Roeck <linux@roeck-us.net>,
Jean-Christophe Dubois <jcd@tribudubois.net>
Subject: [PATCH 1/3] Add dummy i.MXS STMP register support
Date: Sun, 1 Mar 2020 09:04:41 -0800 [thread overview]
Message-ID: <20200301170443.12904-2-linux@roeck-us.net> (raw)
In-Reply-To: <20200301170443.12904-1-linux@roeck-us.net>
STMP registers are registers with a specific register layout.
When using this layout, a register is implemented as set of four:
- The register itself
- A register to set individual register bits
- A register to reset individual register bits
- A register to toggle individual register bits
This register layout is used in various i.MXS SoCs.
In some cases, bit 31 of a STMP register has special reset functionality.
Setting the reset bit resets the chip or block and then sets bit 30. This
functionality is common enough that the Linux kernel implements a library
function to support it.
This patch implements an STMP register as a special device called STMP
device. An STMP device can be instantiated on top of an unimplemented
device. Each instance implements a single register of this unimplemented
device. In some cases, this is necessary and sufficient to be able to load
a driver.
The term "STMP" originates from the Linux kernel. Its origin and meaning
is unknown to the author, but it seemed to make sense to use the same
terminology here.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/misc/Kconfig | 3 +
hw/misc/Makefile.objs | 1 +
hw/misc/stmp.c | 121 +++++++++++++++++++++++++++++++++++++++++
include/hw/misc/stmp.h | 47 ++++++++++++++++
4 files changed, 172 insertions(+)
create mode 100644 hw/misc/stmp.c
create mode 100644 include/hw/misc/stmp.h
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index bdd77d8020..68af3f1e2a 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -123,6 +123,9 @@ config AUX
bool
select I2C
+config STMP
+ bool
+
config UNIMP
bool
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index da993f45b7..942653854c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -9,6 +9,7 @@ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
common-obj-$(CONFIG_EDU) += edu.o
common-obj-$(CONFIG_PCA9552) += pca9552.o
+common-obj-$(CONFIG_STMP) += stmp.o
common-obj-$(CONFIG_UNIMP) += unimp.o
common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
diff --git a/hw/misc/stmp.c b/hw/misc/stmp.c
new file mode 100644
index 0000000000..eb909fccfe
--- /dev/null
+++ b/hw/misc/stmp.c
@@ -0,0 +1,121 @@
+/*
+ * MXS "STMP" dummy device
+ *
+ * This is a dummy device which follows MXS "STMP" register layout.
+ * It's useful for stubbing out regions of an SoC or board
+ * map which correspond to devices that have not yet been
+ * implemented, yet require "STMP" device specific reset support.
+ * This is often sufficient to placate initial guest device
+ * driver probing such that the system will come up.
+ *
+ * Derived from "unimplemented" device code.
+ * Copyright Linaro Limited, 2017
+ * Written by Peter Maydell
+ *
+ * Written by Guenter Roeck
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/misc/stmp.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+#define REG_VAL 0x0
+#define REG_SET 0x4
+#define REG_CLR 0x8
+#define REG_TOG 0xc
+
+#define STMP_MODULE_CLKGATE (1 << 30)
+#define STMP_MODULE_SFTRST (1 << 31)
+
+static uint64_t stmp_read(void *opaque, hwaddr offset, unsigned size)
+{
+ StmpDeviceState *s = STMP_DEVICE(opaque);
+
+ switch (offset) {
+ case REG_VAL:
+ return s->regval;
+ default:
+ return 0;
+ }
+}
+
+static void stmp_write(void *opaque, hwaddr offset, uint64_t value,
+ unsigned size)
+{
+ StmpDeviceState *s = STMP_DEVICE(opaque);
+
+ switch (offset) {
+ case REG_VAL:
+ s->regval = value;
+ break;
+ case REG_SET:
+ s->regval |= value;
+ if (s->have_reset && (value & STMP_MODULE_SFTRST)) {
+ s->regval |= STMP_MODULE_CLKGATE;
+ }
+ break;
+ case REG_CLR:
+ s->regval &= ~value;
+ break;
+ case REG_TOG:
+ s->regval ^= value;
+ break;
+ default:
+ break;
+ }
+}
+
+static const MemoryRegionOps stmp_ops = {
+ .read = stmp_read,
+ .write = stmp_write,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stmp_realize(DeviceState *dev, Error **errp)
+{
+ StmpDeviceState *s = STMP_DEVICE(dev);
+
+ if (s->name == NULL) {
+ error_setg(errp, "property 'name' not specified");
+ return;
+ }
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &stmp_ops, s,
+ s->name, 0x10);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static Property stmp_properties[] = {
+ DEFINE_PROP_STRING("name", StmpDeviceState, name),
+ DEFINE_PROP_BOOL("have-reset", StmpDeviceState, have_reset, false),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void stmp_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = stmp_realize;
+ device_class_set_props(dc, stmp_properties);
+}
+
+static const TypeInfo stmp_info = {
+ .name = TYPE_STMP_DEVICE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(StmpDeviceState),
+ .class_init = stmp_class_init,
+};
+
+static void stmp_register_types(void)
+{
+ type_register_static(&stmp_info);
+}
+
+type_init(stmp_register_types)
diff --git a/include/hw/misc/stmp.h b/include/hw/misc/stmp.h
new file mode 100644
index 0000000000..941ceb25dd
--- /dev/null
+++ b/include/hw/misc/stmp.h
@@ -0,0 +1,47 @@
+/*
+ * "Stmp" device
+ *
+ * Written by Guenter Roeck
+ */
+
+#ifndef HW_MISC_STMP_H
+#define HW_MISC_STMP_H
+
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+
+#define TYPE_STMP_DEVICE "stmp-device"
+
+#define STMP_DEVICE(obj) \
+ OBJECT_CHECK(StmpDeviceState, (obj), TYPE_STMP_DEVICE)
+
+typedef struct {
+ SysBusDevice parent_obj;
+ MemoryRegion iomem;
+ char *name;
+ bool have_reset;
+ uint32_t regval;
+} StmpDeviceState;
+
+/**
+ * create_stmp_device: create and map a dummy device with STMP register layout
+ * @name: name of the device for debug logging
+ * @have_reset: True if the register has reset functionality
+ * @base: base address of the device's MMIO region
+ *
+ * This utility function creates and maps an instance of stmp-device,
+ * which is a dummy device which follows STMP register layout.
+ */
+static inline void create_stmp_device(const char *name, bool have_reset,
+ hwaddr base)
+{
+ DeviceState *dev = qdev_create(NULL, TYPE_STMP_DEVICE);
+
+ qdev_prop_set_string(dev, "name", name);
+ qdev_prop_set_bit(dev, "have-reset", have_reset);
+ qdev_init_nofail(dev);
+
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(dev), 0, base, 0);
+}
+
+#endif
--
2.17.1
next prev parent reply other threads:[~2020-03-01 17:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-01 17:04 [PATCH 0/3] Wire up USB controllers on fsl-imx6 and fsl-imx6ul Guenter Roeck
2020-03-01 17:04 ` Guenter Roeck [this message]
2020-03-01 17:04 ` [PATCH 2/3] arm: fsl-imx6ul: Wire up USB controllers Guenter Roeck
2020-03-01 17:04 ` [PATCH 3/3] hw/arm/fsl-imx6: " Guenter Roeck
2020-03-09 17:09 ` [PATCH 0/3] Wire up USB controllers on fsl-imx6 and fsl-imx6ul Peter Maydell
2020-03-09 17:27 ` Guenter Roeck
2020-03-09 17:29 ` 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=20200301170443.12904-2-linux@roeck-us.net \
--to=linux@roeck-us.net \
--cc=jcd@tribudubois.net \
--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.