Enable 8 Cadence GPIO controllers into Axiado AX3000 SoC
Signed-off-by: Kuan-Jui Chiu <[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 5240b57079a..4801a18a737 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -723,6 +723,7 @@ config AXIADO_SOC
depends on ARM
select ARM_GIC
select CADENCE # UART
+ select CADENCE_GPIO
select AXIADO_SDHCI
select UNIMP
diff --git a/hw/arm/ax3000-soc.c b/hw/arm/ax3000-soc.c
index fd8c2f977e7..3f9abc59dff 100644
--- a/hw/arm/ax3000-soc.c
+++ b/hw/arm/ax3000-soc.c
@@ -65,6 +65,11 @@ static void ax3000_init(Object *obj)
}
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)
@@ -212,6 +217,31 @@ static void ax3000_realize(DeviceState *dev, Error **errp)
blk_by_legacy_dinfo((drive_get(IF_SD, 0, 0))),
&error_fatal);
qdev_realize_and_unref(card, s->sdhci0.sd_bus, &error_fatal);
+
+ /* GPIOs */
+ for (int i = 0; i < AX3000_NUM_GPIOS; i++) {
+ 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 }
+ };
+
+ 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 763866ce6e2..aa388f79f0e 100644
--- a/include/hw/arm/ax3000-soc.h
+++ b/include/hw/arm/ax3000-soc.h
@@ -12,6 +12,7 @@
#include "cpu.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/char/cadence_uart.h"
+#include "hw/gpio/cadence_gpio.h"
#include "hw/sd/axiado_sdhci.h"
#include "hw/core/sysbus.h"
#include "qemu/units.h"
@@ -37,6 +38,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
#define CLKRST_CPU_PLL_POSTDIV_OFFSET 0x0C
@@ -47,6 +57,7 @@ enum Ax3000Configuration {
AX3000_NUM_IRQS = 224,
AX3000_NUM_BANKS = 2,
AX3000_NUM_UARTS = 4,
+ AX3000_NUM_GPIOS = 8,
};
typedef struct Ax3000SoCState {
@@ -57,6 +68,7 @@ typedef struct Ax3000SoCState {
MemoryRegion dram[AX3000_NUM_BANKS];
MemoryRegion pll_ctrl;
CadenceUARTState uart[AX3000_NUM_UARTS];
+ CadenceGPIOState gpio[AX3000_NUM_GPIOS];
AxiadoSDHCIState sdhci0;
} Ax3000SoCState;
@@ -73,6 +85,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.34.1