aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@linaro.org>2020-02-10 22:56:13 +0100
committerLoic Poulain <loic.poulain@linaro.org>2020-02-10 22:56:13 +0100
commit4e5922c13eaef1203751a5d9442ff946c9a4d523 (patch)
tree09e5a679b1f121ecde26d3b025b09914ecb13f8d
parentfb2246882a2c8d7f084ebe0617e97ac78467d156 (diff)
hw: arm: virt: Add secondary uart and i2c
secure uart as secondary uart if non-secure i2c controller + tmp105 sensor. Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
-rw-r--r--hw/arm/virt.c47
-rw-r--r--include/hw/arm/virt.h1
2 files changed, 48 insertions, 0 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d4bedc2607..e59843186c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -42,6 +42,7 @@
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/display/ramfb.h"
+#include "hw/i2c/i2c.h"
#include "net/net.h"
#include "sysemu/device_tree.h"
#include "sysemu/numa.h"
@@ -137,6 +138,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 },
[VIRT_UART] = { 0x09000000, 0x00001000 },
[VIRT_RTC] = { 0x09010000, 0x00001000 },
+ [VIRT_I2C] = { 0x0901A000, 0x00001000 },
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
@@ -754,6 +756,9 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
if (uart == VIRT_UART) {
qemu_fdt_setprop_string(vms->fdt, "/chosen", "stdout-path", nodename);
+ qemu_fdt_setprop_string(vms->fdt, "/aliases", "serial0", nodename);
+ } else if (!vms->secure) {
+ qemu_fdt_setprop_string(vms->fdt, "/aliases", "serial1", nodename);
} else {
/* Mark as not usable by the normal world */
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
@@ -846,6 +851,39 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
g_free(nodename);
}
+static void create_i2c(const VirtMachineState *vms, qemu_irq *pic)
+{
+ hwaddr base = vms->memmap[VIRT_I2C].base;
+ hwaddr size = vms->memmap[VIRT_I2C].size;
+ hwaddr i2c_addr = 0x48;
+ const char compat1[] = "arm,versatile-i2c";
+ const char compat2[] = "ti,tmp105";
+ DeviceState *dev;
+ char *nodename;
+ I2CBus *i2c;
+
+ dev = sysbus_create_simple("versatile_i2c", base, NULL);
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
+ dev = i2c_create_slave(i2c, "tmp105", i2c_addr);
+ object_property_set_int(OBJECT(dev), 31000, "temperature", &error_abort);
+
+ uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
+ nodename = g_strdup_printf("/i2c@%" PRIx64, base);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", 2, base, 2, size);
+ qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat1, sizeof(compat1));
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 1);
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0);
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/i2c@%" PRIx64 "/temp@%" PRIx64, base, i2c_addr);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat2, sizeof(compat2));
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "reg", i2c_addr);
+ g_free(nodename);
+}
+
static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
{
int i;
@@ -1716,11 +1754,18 @@ static void machvirt_init(MachineState *machine)
fdt_add_pmu_nodes(vms);
+ qemu_fdt_add_subnode(vms->fdt, "/aliases");
create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
if (vms->secure) {
create_secure_ram(vms, secure_sysmem);
create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
+ } else {
+ /*
+ * If secure mode is disabled then let's setup the "secure"
+ * UART so that normal world can use it.
+ */
+ create_uart(vms, pic, VIRT_SECURE_UART, sysmem, serial_hd(1));
}
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
@@ -1735,6 +1780,8 @@ static void machvirt_init(MachineState *machine)
create_gpio(vms, pic);
}
+ create_i2c(vms, pic);
+
/* connect powerdown request */
vms->powerdown_notifier.notify = virt_powerdown_req;
qemu_register_powerdown_notifier(&vms->powerdown_notifier);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 0b41083e9d..bfa12c14aa 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -68,6 +68,7 @@ enum {
VIRT_UART,
VIRT_MMIO,
VIRT_RTC,
+ VIRT_I2C,
VIRT_FW_CFG,
VIRT_PCIE,
VIRT_PCIE_MMIO,