Now that we have the DesignWare model we can add buses to the
tt-atlantis machine.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
v2:
- Correct count from 4 to 5
- Fix headers location
---
include/hw/riscv/tt_atlantis.h | 13 ++++++++++++
hw/riscv/tt_atlantis.c | 39 ++++++++++++++++++++++++++++++++++
hw/riscv/Kconfig | 1 +
3 files changed, 53 insertions(+)
diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h
index 10b06894aeca..1b4f61c95184 100644
--- a/include/hw/riscv/tt_atlantis.h
+++ b/include/hw/riscv/tt_atlantis.h
@@ -11,12 +11,15 @@
#include "hw/core/boards.h"
#include "hw/core/sysbus.h"
+#include "hw/i2c/designware_i2c.h"
#include "hw/intc/riscv_imsic.h"
#include "hw/riscv/riscv_hart.h"
#define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis")
OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE)
+#define TT_ATL_NUM_I2C 5
+
struct TTAtlantisState {
/*< private >*/
MachineState parent;
@@ -30,6 +33,7 @@ struct TTAtlantisState {
RISCVHartArrayState soc;
DeviceState *irqchip;
GPEXHost gpex_host;
+ DesignWareI2CState i2c[TT_ATL_NUM_I2C];
int fdt_size;
int aia_guests; /* TODO: This should be hard coded once known */
@@ -37,6 +41,11 @@ struct TTAtlantisState {
enum {
TT_ATL_SYSCON_IRQ = 10,
+ TT_ATL_I2C0_IRQ = 33,
+ TT_ATL_I2C1_IRQ = 34,
+ TT_ATL_I2C2_IRQ = 35,
+ TT_ATL_I2C3_IRQ = 36,
+ TT_ATL_I2C4_IRQ = 37,
TT_ATL_UART0_IRQ = 38,
TT_ATL_UART1_IRQ = 39,
TT_ATL_UART2_IRQ = 40,
@@ -52,6 +61,10 @@ enum {
TT_ATL_DDR_HI,
TT_ATL_FW_CFG,
TT_ATL_I2C0,
+ TT_ATL_I2C1,
+ TT_ATL_I2C2,
+ TT_ATL_I2C3,
+ TT_ATL_I2C4,
TT_ATL_MAPLIC,
TT_ATL_MIMSIC,
TT_ATL_PCIE_ECAM0,
diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
index fa6e4f42a12d..2d0add278c20 100644
--- a/hw/riscv/tt_atlantis.c
+++ b/hw/riscv/tt_atlantis.c
@@ -67,6 +67,11 @@ static const MemMapEntry tt_atlantis_memmap[] = {
[TT_ATL_TIMER] = { 0xa8020000, 0x10000 },
[TT_ATL_WDT0] = { 0xa8030000, 0x10000 },
[TT_ATL_UART0] = { 0xb0100000, 0x10000 },
+ [TT_ATL_I2C0] = { 0xb0400000, 0x10000 },
+ [TT_ATL_I2C1] = { 0xb0500000, 0x10000 },
+ [TT_ATL_I2C2] = { 0xb0600000, 0x10000 },
+ [TT_ATL_I2C3] = { 0xb0700000, 0x10000 },
+ [TT_ATL_I2C4] = { 0xb0800000, 0x10000 },
[TT_ATL_MAPLIC] = { 0xcc000000, 0x4000000 },
[TT_ATL_SAPLIC] = { 0xe8000000, 0x4000000 },
[TT_ATL_DDR_HI] = { 0x100000000, 0x1000000000 },
@@ -478,6 +483,20 @@ static void create_fdt_fw_cfg(void *fdt, const MemMapEntry *mem)
qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0);
}
+static void create_fdt_i2c(void *fdt, const MemMapEntry *mem, uint32_t irq,
+ int irqchip_phandle)
+{
+ g_autofree char *name = g_strdup_printf("/soc/i2c@%" PRIx64, mem->base);
+
+ qemu_fdt_add_subnode(fdt, name);
+ qemu_fdt_setprop_string(fdt, name, "compatible", "snps,designware-i2c");
+ qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
+ qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle);
+ qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4);
+ qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1);
+ qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0);
+}
+
static void finalize_fdt(TTAtlantisState *s)
{
uint32_t aplic_s_phandle = next_phandle();
@@ -505,6 +524,13 @@ static void finalize_fdt(TTAtlantisState *s)
create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ,
aplic_s_phandle);
+
+ for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
+ create_fdt_i2c(fdt,
+ &s->memmap[TT_ATL_I2C0 + i],
+ TT_ATL_I2C0_IRQ + i,
+ aplic_s_phandle);
+ }
}
static void create_fdt(TTAtlantisState *s)
@@ -813,6 +839,19 @@ static void tt_atlantis_machine_init(MachineState *machine)
qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ),
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ /* I2C */
+ for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
+ object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i],
+ TYPE_DESIGNWARE_I2C);
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_fatal);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->i2c[i]);
+ memory_region_add_subregion(system_memory,
+ s->memmap[TT_ATL_I2C0 + i].base,
+ sysbus_mmio_get_region(sbd, 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+ qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + i));
+ }
+
/* Load or create device tree */
if (machine->dtb) {
machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 5317eccd06e7..ee876557ef15 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -137,6 +137,7 @@ config TENSTORRENT
select RISCV_IMSIC
select FW_CFG_DMA
select PLATFORM_BUS
+ select DESIGNWARE_I2C
config XIANGSHAN_KUNMINGHU
bool
--
2.47.3
Joel Stanley <joel@jms.id.au> writes:
> Now that we have the DesignWare model we can add buses to the
> tt-atlantis machine.
This is triggering a configure failure for me:
Configuring aarch64-softmmu-config-devices.mak with command
../../meson.build:3448:25: ERROR: Command `/home/alex/lsrc/qemu.git/builds/all/pyvenv/bin/python3 /home/alex/lsrc/qemu.git/scripts/minikconf.py --defconfig aarch64-softmmu-config-devices.mak /home/alex/lsrc/qemu.git/builds/all/meson-private/aarch64-softmmu-config-devices.mak.d /home/alex/lsrc/qemu.git/configs/devices/aarch64-softmmu/default.mak /home/alex/lsrc/qemu.git/Kconfig CONFIG_TPM=y CONFIG_PIXMAN=y CONFIG_SPICE=y CONFIG_IVSHMEM=y CONFIG_OPENGL=y CONFIG_GNUTLS=y CONFIG_X11=y CONFIG_FDT=y CONFIG_VHOST_USER=y CONFIG_VHOST_VDPA=y CONFIG_VHOST_KERNEL=y CONFIG_VIRTFS=y CONFIG_LINUX=y CONFIG_MULTIPROCESS_ALLOWED=y CONFIG_HV_BALLOON_POSSIBLE=y CONFIG_TCG=y CONFIG_AARCH64=y CONFIG_TARGET_BIG_ENDIAN=n` failed with status 1.
A full log can be found at /home/alex/lsrc/qemu.git/builds/all/meson-logs/meson-log.txt
FAILED: build.ninja
/home/alex/lsrc/qemu.git/builds/all/pyvenv/bin/meson --internal regenerate /home/alex/lsrc/qemu.git .
ninja: error: rebuilding 'build.ninja': cannot make progress due to previous errors
make: *** [Makefile:170: run-ninja] Error 1
make: Target 'all' not remade because of errors.
make: Leaving directory '/home/alex/lsrc/qemu.git/builds/all'
Compilation exited abnormally with code 2 at Thu Jan 15 11:53:59, duration 3.23 s
Could it be an interaction with the prereq patches?
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> v2:
> - Correct count from 4 to 5
> - Fix headers location
> ---
> include/hw/riscv/tt_atlantis.h | 13 ++++++++++++
> hw/riscv/tt_atlantis.c | 39 ++++++++++++++++++++++++++++++++++
> hw/riscv/Kconfig | 1 +
> 3 files changed, 53 insertions(+)
>
> diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h
> index 10b06894aeca..1b4f61c95184 100644
> --- a/include/hw/riscv/tt_atlantis.h
> +++ b/include/hw/riscv/tt_atlantis.h
> @@ -11,12 +11,15 @@
>
> #include "hw/core/boards.h"
> #include "hw/core/sysbus.h"
> +#include "hw/i2c/designware_i2c.h"
> #include "hw/intc/riscv_imsic.h"
> #include "hw/riscv/riscv_hart.h"
>
> #define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis")
> OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE)
>
> +#define TT_ATL_NUM_I2C 5
> +
> struct TTAtlantisState {
> /*< private >*/
> MachineState parent;
> @@ -30,6 +33,7 @@ struct TTAtlantisState {
> RISCVHartArrayState soc;
> DeviceState *irqchip;
> GPEXHost gpex_host;
> + DesignWareI2CState i2c[TT_ATL_NUM_I2C];
>
> int fdt_size;
> int aia_guests; /* TODO: This should be hard coded once known */
> @@ -37,6 +41,11 @@ struct TTAtlantisState {
>
> enum {
> TT_ATL_SYSCON_IRQ = 10,
> + TT_ATL_I2C0_IRQ = 33,
> + TT_ATL_I2C1_IRQ = 34,
> + TT_ATL_I2C2_IRQ = 35,
> + TT_ATL_I2C3_IRQ = 36,
> + TT_ATL_I2C4_IRQ = 37,
> TT_ATL_UART0_IRQ = 38,
> TT_ATL_UART1_IRQ = 39,
> TT_ATL_UART2_IRQ = 40,
> @@ -52,6 +61,10 @@ enum {
> TT_ATL_DDR_HI,
> TT_ATL_FW_CFG,
> TT_ATL_I2C0,
> + TT_ATL_I2C1,
> + TT_ATL_I2C2,
> + TT_ATL_I2C3,
> + TT_ATL_I2C4,
> TT_ATL_MAPLIC,
> TT_ATL_MIMSIC,
> TT_ATL_PCIE_ECAM0,
> diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
> index fa6e4f42a12d..2d0add278c20 100644
> --- a/hw/riscv/tt_atlantis.c
> +++ b/hw/riscv/tt_atlantis.c
> @@ -67,6 +67,11 @@ static const MemMapEntry tt_atlantis_memmap[] = {
> [TT_ATL_TIMER] = { 0xa8020000, 0x10000 },
> [TT_ATL_WDT0] = { 0xa8030000, 0x10000 },
> [TT_ATL_UART0] = { 0xb0100000, 0x10000 },
> + [TT_ATL_I2C0] = { 0xb0400000, 0x10000 },
> + [TT_ATL_I2C1] = { 0xb0500000, 0x10000 },
> + [TT_ATL_I2C2] = { 0xb0600000, 0x10000 },
> + [TT_ATL_I2C3] = { 0xb0700000, 0x10000 },
> + [TT_ATL_I2C4] = { 0xb0800000, 0x10000 },
> [TT_ATL_MAPLIC] = { 0xcc000000, 0x4000000 },
> [TT_ATL_SAPLIC] = { 0xe8000000, 0x4000000 },
> [TT_ATL_DDR_HI] = { 0x100000000, 0x1000000000 },
> @@ -478,6 +483,20 @@ static void create_fdt_fw_cfg(void *fdt, const MemMapEntry *mem)
> qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0);
> }
>
> +static void create_fdt_i2c(void *fdt, const MemMapEntry *mem, uint32_t irq,
> + int irqchip_phandle)
> +{
> + g_autofree char *name = g_strdup_printf("/soc/i2c@%" PRIx64, mem->base);
> +
> + qemu_fdt_add_subnode(fdt, name);
> + qemu_fdt_setprop_string(fdt, name, "compatible", "snps,designware-i2c");
> + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->size);
> + qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle);
> + qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4);
> + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1);
> + qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0);
> +}
> +
> static void finalize_fdt(TTAtlantisState *s)
> {
> uint32_t aplic_s_phandle = next_phandle();
> @@ -505,6 +524,13 @@ static void finalize_fdt(TTAtlantisState *s)
>
> create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ,
> aplic_s_phandle);
> +
> + for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
> + create_fdt_i2c(fdt,
> + &s->memmap[TT_ATL_I2C0 + i],
> + TT_ATL_I2C0_IRQ + i,
> + aplic_s_phandle);
> + }
> }
>
> static void create_fdt(TTAtlantisState *s)
> @@ -813,6 +839,19 @@ static void tt_atlantis_machine_init(MachineState *machine)
> qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ),
> 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
>
> + /* I2C */
> + for (int i = 0; i < TT_ATL_NUM_I2C; i++) {
> + object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i],
> + TYPE_DESIGNWARE_I2C);
> + sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_fatal);
> + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->i2c[i]);
> + memory_region_add_subregion(system_memory,
> + s->memmap[TT_ATL_I2C0 + i].base,
> + sysbus_mmio_get_region(sbd, 0));
> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
> + qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + i));
> + }
> +
> /* Load or create device tree */
> if (machine->dtb) {
> machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index 5317eccd06e7..ee876557ef15 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -137,6 +137,7 @@ config TENSTORRENT
> select RISCV_IMSIC
> select FW_CFG_DMA
> select PLATFORM_BUS
> + select DESIGNWARE_I2C
>
> config XIANGSHAN_KUNMINGHU
> bool
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
© 2016 - 2026 Red Hat, Inc.