summaryrefslogtreecommitdiff
path: root/hw/arm/aspeed_ast2600.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/aspeed_ast2600.c')
-rw-r--r--hw/arm/aspeed_ast2600.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index d1f18e471a..1a10d0fe1e 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/misc/unimp.h"
#include "hw/arm/aspeed_soc.h"
@@ -24,6 +25,7 @@
static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_SPI_BOOT] = 0x00000000,
[ASPEED_DEV_SRAM0] = 0x10000000,
+ [ASPEED_DEV_SRAM1] = 0x1E710000, /* ACRY SRAM */
[ASPEED_DEV_DPMCU] = 0x18000000,
/* 0x16000000 0x17FFFFFF : AHB BUS do LPC Bus bridge */
[ASPEED_DEV_IOMEM] = 0x1E600000,
@@ -32,6 +34,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_SPI1] = 0x1E630000,
[ASPEED_DEV_SPI2] = 0x1E631000,
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
+ [ASPEED_DEV_UDC] = 0x1E6A2000,
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
[ASPEED_DEV_MII1] = 0x1E650000,
[ASPEED_DEV_MII2] = 0x1E650008,
@@ -50,6 +53,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_DP] = 0x1E6EB000,
[ASPEED_DEV_PCIE_PHY1] = 0x1E6ED200,
[ASPEED_DEV_SBC] = 0x1E6F2000,
+ [ASPEED_DEV_ACRY] = 0x1E6FA000,
[ASPEED_DEV_EMMC_BC] = 0x1E6f5000,
[ASPEED_DEV_VIDEO] = 0x1E700000,
[ASPEED_DEV_SDHCI] = 0x1E740000,
@@ -142,6 +146,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
[ASPEED_DEV_FSI1] = 100,
[ASPEED_DEV_FSI2] = 101,
[ASPEED_DEV_I3C] = 102, /* 102 -> 107 */
+ [ASPEED_DEV_ACRY] = 160,
};
static qemu_irq aspeed_soc_ast2600_get_irq(AspeedSoCState *s, int dev)
@@ -214,6 +219,10 @@ static void aspeed_soc_ast2600_init(Object *obj)
TYPE_PLATFORM_EHCI);
}
+ object_initialize_child(obj, "udc", &a->udc, TYPE_ASPEED_UDC);
+ object_initialize_child(obj, "ehci2-udc-orgate", &a->ehci2_udc_orgate,
+ TYPE_OR_IRQ);
+
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -267,6 +276,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
object_initialize_child(obj, "hace", &s->hace, typename);
+ object_initialize_child(obj, "acry", &s->acry, TYPE_ASPEED_ACRY);
+
object_initialize_child(obj, "i3c", &s->i3c, TYPE_ASPEED_I3C);
object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_AST2600_SBC);
@@ -361,6 +372,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
AspeedSoCState *s = ASPEED_SOC(dev);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
qemu_irq irq;
+ g_autofree char *sram1_name = NULL;
g_autofree char *sram_name = NULL;
int uart;
@@ -444,6 +456,19 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(s->memory,
sc->memmap[ASPEED_DEV_SRAM0], &s->sram[0]);
+ /* ACRY SRAM */
+ sram1_name = g_strdup_printf("aspeed.acry.sram.%d",
+ CPU(&a->cpu[0])->cpu_index);
+ if (!memory_region_init_ram(&s->sram[1], OBJECT(s), sram1_name,
+ sc->sram_size[1], errp)) {
+ return;
+ }
+ memory_region_init(&s->sram_container[1], OBJECT(s),
+ "aspeed.acry.sram-container", sc->sram_size[1]);
+ memory_region_add_subregion(&s->sram_container[1], 0, &s->sram[1]);
+ memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM1],
+ &s->sram_container[1]);
+
/* DPMCU */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->dpmcu),
"aspeed.dpmcu",
@@ -561,6 +586,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_SPI1 + i));
}
+ /*
+ * EHCI2 and the UDC share one SoC interrupt line, so OR their outputs
+ * together and drive that GIC input from the OR gate.
+ */
+ object_property_set_int(OBJECT(&a->ehci2_udc_orgate), "num-lines", 2,
+ &error_abort);
+ qdev_realize(DEVICE(&a->ehci2_udc_orgate), NULL, &error_abort);
+ qdev_connect_gpio_out(DEVICE(&a->ehci2_udc_orgate), 0,
+ aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_EHCI2));
+
/* EHCI */
for (i = 0; i < sc->ehcis_num; i++) {
if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
@@ -568,10 +603,26 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
}
aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->ehci[i]), 0,
sc->memmap[ASPEED_DEV_EHCI1 + i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
- aspeed_soc_ast2600_get_irq(s,
- ASPEED_DEV_EHCI1 + i));
}
+ /*
+ * EHCI1 has its own IRQ; EHCI2 shares the UDC's IRQ, so route it through
+ * the OR gate.
+ */
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[0]), 0,
+ aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_EHCI1));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[1]), 0,
+ qdev_get_gpio_in(DEVICE(&a->ehci2_udc_orgate), 0));
+
+ /* UDC - USB 2.0 Device Controller */
+ object_property_set_link(OBJECT(&a->udc), "dram", OBJECT(s->dram_mr),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->udc), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&a->udc), 0,
+ sc->memmap[ASPEED_DEV_UDC]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->udc), 0,
+ qdev_get_gpio_in(DEVICE(&a->ehci2_udc_orgate), 1));
/* SDMC - SDRAM Memory Controller */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
@@ -710,6 +761,19 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_HACE));
+ /* ACRY */
+ object_property_set_link(OBJECT(&s->acry), "dram", OBJECT(s->dram_mr),
+ &error_abort);
+ object_property_set_link(OBJECT(&s->acry), "sram", OBJECT(&s->sram[1]),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->acry), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->acry), 0,
+ sc->memmap[ASPEED_DEV_ACRY]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->acry), 0,
+ aspeed_soc_ast2600_get_irq(s, ASPEED_DEV_ACRY));
+
/* I3C */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp)) {
return;
@@ -765,6 +829,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, const void *data)
sc->valid_cpu_types = valid_cpu_types;
sc->silicon_rev = AST2600_A3_SILICON_REV;
sc->sram_size[0] = 0x16400;
+ sc->sram_size[1] = 64 * KiB; /* ACRY SRAM */
sc->spis_num = 2;
sc->ehcis_num = 2;
sc->wdts_num = 4;