From: Kuan-Jui Chiu <[email protected]> Enable 8 Cadence GPIO controllers into Axiado AX3000 SoC
Signed-off-by: Kuan-Jui Chiu <[email protected]> Reviewed-by: Peter Maydell <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Message-id: [email protected] Signed-off-by: Peter Maydell <[email protected]> --- hw/arm/Kconfig | 1 + hw/arm/ax3000-soc.c | 30 ++++++++++++++++++++++++++++++ include/hw/arm/ax3000-soc.h | 21 +++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index d16b3d2f47..e22c34a2e1 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -731,6 +731,7 @@ config AXIADO_SOC select ARM_GIC select CADENCE # UART select AXIADO_CLK + select CADENCE_GPIO select AXIADO_SDHCI select UNIMP diff --git a/hw/arm/ax3000-soc.c b/hw/arm/ax3000-soc.c index 23903b081b..71e31c6fb4 100644 --- a/hw/arm/ax3000-soc.c +++ b/hw/arm/ax3000-soc.c @@ -36,6 +36,11 @@ static void ax3000_init(Object *obj) object_initialize_child(obj, "clk", &s->ax3000_clk, TYPE_AX3000_CLK); object_initialize_child(obj, "sdhci0", &s->sdhci0, TYPE_AXIADO_SDHCI); + + for (int i = 0; i < AX3000_NUM_GPIOS; i++) { + g_autofree char *name = g_strdup_printf("gpio%d", i); + object_initialize_child(obj, name, &s->gpio[i], TYPE_CADENCE_GPIO); + } } static void ax3000_realize(DeviceState *dev, Error **errp) @@ -187,6 +192,31 @@ static void ax3000_realize(DeviceState *dev, Error **errp) &error_fatal); qdev_realize_and_unref(card, s->sdhci0.sd_bus, &error_fatal); } + + /* GPIOs */ + const struct { + hwaddr addr; + unsigned int irq; + } gpio_table[] = { + { AX3000_GPIO0_BASE, AX3000_GPIO0_IRQ }, + { AX3000_GPIO1_BASE, AX3000_GPIO1_IRQ }, + { AX3000_GPIO2_BASE, AX3000_GPIO2_IRQ }, + { AX3000_GPIO3_BASE, AX3000_GPIO3_IRQ }, + { AX3000_GPIO4_BASE, AX3000_GPIO4_IRQ }, + { AX3000_GPIO5_BASE, AX3000_GPIO5_IRQ }, + { AX3000_GPIO6_BASE, AX3000_GPIO6_IRQ }, + { AX3000_GPIO7_BASE, AX3000_GPIO7_IRQ } + }; + + for (int i = 0; i < AX3000_NUM_GPIOS; i++) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), errp)) { + return; + } + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, + qdev_get_gpio_in(gic_dev, gpio_table[i].irq)); + } } static void ax3000_class_init(ObjectClass *oc, const void *data) diff --git a/include/hw/arm/ax3000-soc.h b/include/hw/arm/ax3000-soc.h index 52b47aa829..344fcb6f3c 100644 --- a/include/hw/arm/ax3000-soc.h +++ b/include/hw/arm/ax3000-soc.h @@ -13,6 +13,7 @@ #include "hw/intc/arm_gicv3_common.h" #include "hw/char/cadence_uart.h" #include "hw/misc/axiado_clk.h" +#include "hw/gpio/cadence_gpio.h" #include "hw/sd/axiado_sdhci.h" #include "hw/core/sysbus.h" #include "qemu/units.h" @@ -38,6 +39,15 @@ OBJECT_DECLARE_TYPE(Ax3000SoCState, Ax3000SoCClass, AX3000_SOC) #define AX3000_SDHCI0_BASE 0x86000000 #define AX3000_EMMC_PHY_BASE 0x80801C00 +#define AX3000_GPIO0_BASE 0x80500000 +#define AX3000_GPIO1_BASE 0x80580000 +#define AX3000_GPIO2_BASE 0x80600000 +#define AX3000_GPIO3_BASE 0x80680000 +#define AX3000_GPIO4_BASE 0x80700000 +#define AX3000_GPIO5_BASE 0x80780000 +#define AX3000_GPIO6_BASE 0x80800000 +#define AX3000_GPIO7_BASE 0x80880000 + #define AX3000_TIMER_CTRL 0x8A020000 #define AX3000_PLL_BASE 0x80000000 @@ -46,6 +56,7 @@ enum Ax3000Configuration { AX3000_NUM_IRQS = 224, AX3000_NUM_BANKS = 2, AX3000_NUM_UARTS = 4, + AX3000_NUM_GPIOS = 8, }; typedef struct Ax3000SoCState { @@ -56,6 +67,7 @@ typedef struct Ax3000SoCState { MemoryRegion dram[AX3000_NUM_BANKS]; Ax3000ClkState ax3000_clk; CadenceUARTState uart[AX3000_NUM_UARTS]; + CadenceGPIOState gpio[AX3000_NUM_GPIOS]; AxiadoSDHCIState sdhci0; } Ax3000SoCState; @@ -72,6 +84,15 @@ enum Ax3000Irqs { AX3000_UART3_IRQ = 170, AX3000_SDHCI0_IRQ = 123, + + AX3000_GPIO0_IRQ = 183, + AX3000_GPIO1_IRQ = 184, + AX3000_GPIO2_IRQ = 185, + AX3000_GPIO3_IRQ = 186, + AX3000_GPIO4_IRQ = 187, + AX3000_GPIO5_IRQ = 188, + AX3000_GPIO6_IRQ = 189, + AX3000_GPIO7_IRQ = 190, }; #endif /* AXIADO_AX3000_H */ -- 2.43.0
