[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 44/51] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor
From: |
Peter Maydell |
Subject: |
[PULL 44/51] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor |
Date: |
Thu, 24 Oct 2019 17:27:17 +0100 |
From: Philippe Mathieu-Daudé <address@hidden>
We will soon implement the SYS_timer. This timer is used by Linux
in the thermal subsystem, so once available, the subsystem will be
enabled and poll the temperature sensors. We need to provide the
minimum required to keep Linux booting.
Add a dummy thermal sensor returning ~25°C based on:
https://github.com/raspberrypi/linux/blob/rpi-5.3.y/drivers/thermal/broadcom/bcm2835_thermal.c
Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
Reviewed-by: Alistair Francis <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
hw/misc/Makefile.objs | 1 +
include/hw/misc/bcm2835_thermal.h | 27 ++++++
hw/misc/bcm2835_thermal.c | 135 ++++++++++++++++++++++++++++++
3 files changed, 163 insertions(+)
create mode 100644 include/hw/misc/bcm2835_thermal.h
create mode 100644 hw/misc/bcm2835_thermal.c
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a1506809660..c89f3816a52 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -53,6 +53,7 @@ common-obj-$(CONFIG_OMAP) += omap_tap.o
common-obj-$(CONFIG_RASPI) += bcm2835_mbox.o
common-obj-$(CONFIG_RASPI) += bcm2835_property.o
common-obj-$(CONFIG_RASPI) += bcm2835_rng.o
+common-obj-$(CONFIG_RASPI) += bcm2835_thermal.o
common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
diff --git a/include/hw/misc/bcm2835_thermal.h
b/include/hw/misc/bcm2835_thermal.h
new file mode 100644
index 00000000000..c3651b27ec6
--- /dev/null
+++ b/include/hw/misc/bcm2835_thermal.h
@@ -0,0 +1,27 @@
+/*
+ * BCM2835 dummy thermal sensor
+ *
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <address@hidden>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_BCM2835_THERMAL_H
+#define HW_MISC_BCM2835_THERMAL_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_BCM2835_THERMAL "bcm2835-thermal"
+
+#define BCM2835_THERMAL(obj) \
+ OBJECT_CHECK(Bcm2835ThermalState, (obj), TYPE_BCM2835_THERMAL)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+ MemoryRegion iomem;
+ uint32_t ctl;
+} Bcm2835ThermalState;
+
+#endif
diff --git a/hw/misc/bcm2835_thermal.c b/hw/misc/bcm2835_thermal.c
new file mode 100644
index 00000000000..c6f3b1ad605
--- /dev/null
+++ b/hw/misc/bcm2835_thermal.c
@@ -0,0 +1,135 @@
+/*
+ * BCM2835 dummy thermal sensor
+ *
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <address@hidden>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/misc/bcm2835_thermal.h"
+#include "hw/registerfields.h"
+#include "migration/vmstate.h"
+
+REG32(CTL, 0)
+FIELD(CTL, POWER_DOWN, 0, 1)
+FIELD(CTL, RESET, 1, 1)
+FIELD(CTL, BANDGAP_CTRL, 2, 3)
+FIELD(CTL, INTERRUPT_ENABLE, 5, 1)
+FIELD(CTL, DIRECT, 6, 1)
+FIELD(CTL, INTERRUPT_CLEAR, 7, 1)
+FIELD(CTL, HOLD, 8, 10)
+FIELD(CTL, RESET_DELAY, 18, 8)
+FIELD(CTL, REGULATOR_ENABLE, 26, 1)
+
+REG32(STAT, 4)
+FIELD(STAT, DATA, 0, 10)
+FIELD(STAT, VALID, 10, 1)
+FIELD(STAT, INTERRUPT, 11, 1)
+
+#define THERMAL_OFFSET_C 412
+#define THERMAL_COEFF (-0.538f)
+
+static uint16_t bcm2835_thermal_temp2adc(int temp_C)
+{
+ return (temp_C - THERMAL_OFFSET_C) / THERMAL_COEFF;
+}
+
+static uint64_t bcm2835_thermal_read(void *opaque, hwaddr addr, unsigned size)
+{
+ Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);
+ uint32_t val = 0;
+
+ switch (addr) {
+ case A_CTL:
+ val = s->ctl;
+ break;
+ case A_STAT:
+ /* Temperature is constantly 25°C. */
+ val = FIELD_DP32(bcm2835_thermal_temp2adc(25), STAT, VALID, true);
+ break;
+ default:
+ /* MemoryRegionOps are aligned, so this can not happen. */
+ g_assert_not_reached();
+ }
+ return val;
+}
+
+static void bcm2835_thermal_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ Bcm2835ThermalState *s = BCM2835_THERMAL(opaque);
+
+ switch (addr) {
+ case A_CTL:
+ s->ctl = value;
+ break;
+ case A_STAT:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: write 0x%" PRIx64
+ " to 0x%" HWADDR_PRIx "\n",
+ __func__, value, addr);
+ break;
+ default:
+ /* MemoryRegionOps are aligned, so this can not happen. */
+ g_assert_not_reached();
+ }
+}
+
+static const MemoryRegionOps bcm2835_thermal_ops = {
+ .read = bcm2835_thermal_read,
+ .write = bcm2835_thermal_write,
+ .impl.max_access_size = 4,
+ .valid.min_access_size = 4,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void bcm2835_thermal_reset(DeviceState *dev)
+{
+ Bcm2835ThermalState *s = BCM2835_THERMAL(dev);
+
+ s->ctl = 0;
+}
+
+static void bcm2835_thermal_realize(DeviceState *dev, Error **errp)
+{
+ Bcm2835ThermalState *s = BCM2835_THERMAL(dev);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_thermal_ops,
+ s, TYPE_BCM2835_THERMAL, 8);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static const VMStateDescription bcm2835_thermal_vmstate = {
+ .name = "bcm2835_thermal",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ctl, Bcm2835ThermalState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void bcm2835_thermal_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = bcm2835_thermal_realize;
+ dc->reset = bcm2835_thermal_reset;
+ dc->vmsd = &bcm2835_thermal_vmstate;
+}
+
+static const TypeInfo bcm2835_thermal_info = {
+ .name = TYPE_BCM2835_THERMAL,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(Bcm2835ThermalState),
+ .class_init = bcm2835_thermal_class_init,
+};
+
+static void bcm2835_thermal_register_types(void)
+{
+ type_register_static(&bcm2835_thermal_info);
+}
+
+type_init(bcm2835_thermal_register_types)
--
2.20.1
- [PULL 34/51] hw/watchdog/milkymist-sysctl.c: Switch to transaction-based ptimer API, (continued)
- [PULL 34/51] hw/watchdog/milkymist-sysctl.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 31/51] hw/timer/slavio_timer.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 33/51] hw/m68k/mcf5206.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 35/51] target/arm/monitor: Introduce qmp_query_cpu_model_expansion, Peter Maydell, 2019/10/24
- [PULL 36/51] tests: arm: Introduce cpu feature tests, Peter Maydell, 2019/10/24
- [PULL 37/51] target/arm: Allow SVE to be disabled via a CPU property, Peter Maydell, 2019/10/24
- [PULL 40/51] target/arm/kvm64: max cpu: Enable SVE when available, Peter Maydell, 2019/10/24
- [PULL 41/51] target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features, Peter Maydell, 2019/10/24
- [PULL 39/51] target/arm/kvm64: Add kvm_arch_get/put_sve, Peter Maydell, 2019/10/24
- [PULL 38/51] target/arm/cpu64: max cpu: Introduce sve<N> properties, Peter Maydell, 2019/10/24
- [PULL 44/51] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor,
Peter Maydell <=
- [PULL 45/51] hw/arm/bcm2835_peripherals: Use the thermal sensor block, Peter Maydell, 2019/10/24
- [PULL 43/51] target/arm/kvm: host cpu: Add support for sve<N> properties, Peter Maydell, 2019/10/24
- [PULL 47/51] hw/arm/bcm2835_peripherals: Use the SYS_timer, Peter Maydell, 2019/10/24
- [PULL 46/51] hw/timer/bcm2835: Add the BCM2835 SYS_timer, Peter Maydell, 2019/10/24
- [PULL 48/51] hw/arm/bcm2836: Make the SoC code modular, Peter Maydell, 2019/10/24
- [PULL 42/51] target/arm/cpu64: max cpu: Support sve properties with KVM, Peter Maydell, 2019/10/24
- [PULL 49/51] hw/arm/bcm2836: Rename cpus[] as cpu[].core, Peter Maydell, 2019/10/24
- [PULL 51/51] hw/arm/highbank: Use AddressSpace when using write_secondary_boot(), Peter Maydell, 2019/10/24
- [PULL 50/51] hw/arm/raspi: Use AddressSpace when using arm_boot::write_secondary_boot, Peter Maydell, 2019/10/24
- Re: [PULL 00/51] target-arm queue, Philippe Mathieu-Daudé, 2019/10/24