All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Venture <venture@google.com>
To: crauer@google.com, peter.maydell@linaro.org, mst@redhat.com,
	 imammedo@redhat.com, ani@anisinha.ca, shannon.zhaosl@gmail.com
Cc: qemu-arm@nongnu.org, qemu-devel@nongnu.org, Hao Wu <wuhaotsh@google.com>
Subject: [PATCH 2/2] hw/arm: Enable smbus on arm virt machine.
Date: Mon, 10 Jan 2022 13:47:55 -0800	[thread overview]
Message-ID: <20220110214755.810343-3-venture@google.com> (raw)
In-Reply-To: <20220110214755.810343-1-venture@google.com>

From: Chris Rauer <crauer@google.com>

Reviewed-by: Hao Wu <wuhaotsh@google.com>
Signed-off-by: Chris Rauer <crauer@google.com>
---
 docs/system/arm/virt.rst |  4 +++
 hw/arm/Kconfig           |  1 +
 hw/arm/virt-acpi-build.c | 24 ++++++++++++++++++
 hw/arm/virt.c            | 55 ++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/virt.h    |  3 +++
 5 files changed, 87 insertions(+)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 850787495b..e357143f6b 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -30,6 +30,7 @@ The virt board supports:
 - An RTC
 - The fw_cfg device that allows a guest to obtain data from QEMU
 - A PL061 GPIO controller
+- A DesignWare I2C controller
 - An optional SMMUv3 IOMMU
 - hotpluggable DIMMs
 - hotpluggable NVDIMMs
@@ -121,6 +122,9 @@ ras
   Set ``on``/``off`` to enable/disable reporting host memory errors to a guest
   using ACPI and guest external abort exceptions. The default is off.
 
+smbus
+  Set ``on``/``off`` to enable/disable smbus controller. The default is ``off``.
+
 Linux guest kernel configuration
 """"""""""""""""""""""""""""""""
 
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e652590943..692af8c265 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -28,6 +28,7 @@ config ARM_VIRT
     select ACPI_HW_REDUCED
     select ACPI_APEI
     select ACPI_VIOT
+    select DESIGNWARE_I2C
 
 config CHEETAH
     bool
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index d0f4867fdf..310cd6fb5b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -92,6 +92,26 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
     aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_smbus(Aml *scope, const MemMapEntry *smbus_memmap,
+                                           uint32_t i2c_irq, I2CBus *smbus)
+{
+    Aml *dev = aml_device("SMB0");
+    aml_append(dev, aml_name_decl("_HID", aml_string("APMC0D0F")));
+    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+    aml_append(dev, aml_name_decl("_STA", aml_int(0x0F)));
+    aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
+
+    Aml *crs = aml_resource_template();
+    aml_append(crs, aml_memory32_fixed(smbus_memmap->base,
+                                       smbus_memmap->size, AML_READ_WRITE));
+    aml_append(crs,
+               aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+                             AML_EXCLUSIVE, &i2c_irq, 1));
+    aml_append(dev, aml_name_decl("_CRS", crs));
+
+    aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
 {
     Aml *dev = aml_device("FWCF");
@@ -862,6 +882,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
     acpi_dsdt_add_cpus(scope, vms);
     acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
                        (irqmap[VIRT_UART] + ARM_SPI_BASE));
+    if (vms->smbus_enabled) {
+        acpi_dsdt_add_smbus(scope, &memmap[VIRT_SMBUS],
+                            (irqmap[VIRT_SMBUS] + ARM_SPI_BASE), vms->smbus);
+    }
     if (vmc->acpi_expose_flash) {
         acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
     }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4593fea1ce..dd2219424d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -76,6 +76,7 @@
 #include "hw/acpi/generic_event_device.h"
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/char/pl011.h"
+#include "hw/i2c/designware_i2c.h"
 #include "qemu/guest-random.h"
 
 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
@@ -152,6 +153,7 @@ static const MemMapEntry base_memmap[] = {
     [VIRT_NVDIMM_ACPI] =        { 0x09090000, NVDIMM_ACPI_IO_LEN},
     [VIRT_PVTIME] =             { 0x090a0000, 0x00010000 },
     [VIRT_SECURE_GPIO] =        { 0x090b0000, 0x00001000 },
+    [VIRT_SMBUS] =              { 0x090c0000, 0x00001000 },
     [VIRT_MMIO] =               { 0x0a000000, 0x00000200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     [VIRT_PLATFORM_BUS] =       { 0x0c000000, 0x02000000 },
@@ -188,6 +190,7 @@ static const int a15irqmap[] = {
     [VIRT_GPIO] = 7,
     [VIRT_SECURE_UART] = 8,
     [VIRT_ACPI_GED] = 9,
+    [VIRT_SMBUS] = 10,
     [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
     [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
     [VIRT_SMMU] = 74,    /* ...to 74 + NUM_SMMU_IRQS - 1 */
@@ -878,6 +881,32 @@ static void create_rtc(const VirtMachineState *vms)
     g_free(nodename);
 }
 
+static void create_smbus(VirtMachineState *vms)
+{
+    char *nodename;
+    hwaddr base = vms->memmap[VIRT_SMBUS].base;
+    hwaddr size = vms->memmap[VIRT_SMBUS].size;
+    int irq = vms->irqmap[VIRT_SMBUS];
+    const char compat[] = "snps,designware-i2c";
+    MachineState *ms = MACHINE(vms);
+    DeviceState *dev;
+
+    dev = sysbus_create_simple(TYPE_DESIGNWARE_I2C, base,
+                               qdev_get_gpio_in(vms->gic, irq));
+    vms->smbus = (I2CBus *)qdev_get_child_bus(dev, "i2c-bus");
+
+    nodename = g_strdup_printf("/i2c@%" PRIx64, base);
+    qemu_fdt_add_subnode(ms->fdt, nodename);
+    qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
+                           GIC_FDT_IRQ_TYPE_SPI, irq,
+                           GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+    qemu_fdt_setprop_cell(ms->fdt, nodename, "clocks", vms->clock_phandle);
+    qemu_fdt_setprop_string(ms->fdt, nodename, "clock-names", "apb_pclk");
+    g_free(nodename);
+}
+
 static DeviceState *gpio_key_dev;
 static void virt_powerdown_req(Notifier *n, void *opaque)
 {
@@ -2125,6 +2154,10 @@ static void machvirt_init(MachineState *machine)
 
     vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
 
+    if (vms->smbus_enabled) {
+        create_smbus(vms);
+    }
+
     create_rtc(vms);
 
     create_pcie(vms);
@@ -2400,6 +2433,20 @@ static void virt_set_default_bus_bypass_iommu(Object *obj, bool value,
     vms->default_bus_bypass_iommu = value;
 }
 
+static bool virt_machine_get_smbus(Object *obj, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    return vms->smbus_enabled;
+}
+
+static void virt_machine_set_smbus(Object *obj, bool value, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    vms->smbus_enabled = value;
+}
+
 static CpuInstanceProperties
 virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
 {
@@ -2781,6 +2828,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
                                           "in ACPI table header."
                                           "The string may be up to 8 bytes in size");
 
+    object_class_property_add_bool(oc, "smbus",
+                                   virt_machine_get_smbus,
+                                   virt_machine_set_smbus);
+    object_class_property_set_description(oc, "smbus",
+                                          "Enable SMBUS controller. ");
 }
 
 static void virt_instance_init(Object *obj)
@@ -2828,6 +2880,9 @@ static void virt_instance_init(Object *obj)
     /* MTE is disabled by default.  */
     vms->mte = false;
 
+    /* smbus is disabled by default.  */
+    vms->smbus_enabled = false;
+
     vms->irqmap = a15irqmap;
 
     virt_flash_create(vms);
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index dc6b66ffc8..d28de89695 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -86,6 +86,7 @@ enum {
     VIRT_ACPI_GED,
     VIRT_NVDIMM_ACPI,
     VIRT_PVTIME,
+    VIRT_SMBUS,
     VIRT_LOWMEMMAP_LAST,
 };
 
@@ -148,6 +149,7 @@ struct VirtMachineState {
     bool virt;
     bool ras;
     bool mte;
+    bool smbus_enabled;
     OnOffAuto acpi;
     VirtGICType gic_version;
     VirtIOMMUType iommu;
@@ -169,6 +171,7 @@ struct VirtMachineState {
     DeviceState *acpi_dev;
     Notifier powerdown_notifier;
     PCIBus *bus;
+    I2CBus *smbus;
     char *oem_id;
     char *oem_table_id;
 };
-- 
2.34.1.575.g55b058a8bb-goog



  parent reply	other threads:[~2022-01-10 21:57 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-10 21:47 [PATCH 0/2] Adds designware i2c module and adds it to virt arm Patrick Venture
2022-01-10 21:47 ` [PATCH 1/2] hw/i2c: Add designware i2c controller Patrick Venture
2022-01-10 21:47 ` Patrick Venture [this message]
2022-01-13 11:48 ` [PATCH 0/2] Adds designware i2c module and adds it to virt arm Peter Maydell
2022-01-13 11:51   ` Peter Maydell
2022-01-26 17:12     ` Chris Rauer
2022-01-26 18:03       ` Peter Maydell
2022-01-26 22:01         ` Chris Rauer
2022-01-26 23:42         ` Philippe Mathieu-Daudé via
2022-02-21 17:47           ` Chris Rauer
2022-02-22 17:05             ` Corey Minyard

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=20220110214755.810343-3-venture@google.com \
    --to=venture@google.com \
    --cc=ani@anisinha.ca \
    --cc=crauer@google.com \
    --cc=imammedo@redhat.com \
    --cc=mst@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=shannon.zhaosl@gmail.com \
    --cc=wuhaotsh@google.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 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.