[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC PATCH 12/15] aspeed: add support for the AST2600 eval bo
From: |
Cédric Le Goater |
Subject: |
[Qemu-arm] [RFC PATCH 12/15] aspeed: add support for the AST2600 eval board |
Date: |
Wed, 4 Sep 2019 22:46:56 +0200 |
Initial definitions for a simple machine using an AST2600 SoC (Cortex
CPU).
Differences with the AST2400 and the AST2500 SoCs are handled using
the ASPEED_IS_AST2600() macro. This is not optimal but it is not too
invasive either. We could modify the model to add custom instance_init
and realize handlers in the future.
Signed-off-by: Cédric Le Goater <address@hidden>
---
include/hw/arm/aspeed_soc.h | 4 +
include/hw/misc/aspeed_scu.h | 1 +
hw/arm/aspeed.c | 18 ++++
hw/arm/aspeed_soc.c | 189 ++++++++++++++++++++++++++++++++---
4 files changed, 197 insertions(+), 15 deletions(-)
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index b427f2668a8a..74db48374531 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -12,6 +12,7 @@
#ifndef ASPEED_SOC_H
#define ASPEED_SOC_H
+#include "hw/cpu/a15mpcore.h"
#include "hw/intc/aspeed_vic.h"
#include "hw/misc/aspeed_scu.h"
#include "hw/misc/aspeed_sdmc.h"
@@ -38,6 +39,7 @@ typedef struct AspeedSoCState {
/*< public >*/
ARMCPU cpu[ASPEED_CPUS_NUM];
uint32_t num_cpus;
+ A15MPPrivState a7mpcore;
MemoryRegion sram;
AspeedVICState vic;
AspeedRtcState rtc;
@@ -51,6 +53,7 @@ typedef struct AspeedSoCState {
AspeedWDTState wdt[ASPEED_WDTS_NUM];
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
AspeedGPIOState gpio;
+ AspeedGPIOState gpio_1_8v;
AspeedSDHCIState sdhci;
} AspeedSoCState;
@@ -97,6 +100,7 @@ enum {
ASPEED_SRAM,
ASPEED_SDHCI,
ASPEED_GPIO,
+ ASPEED_GPIO_1_8V,
ASPEED_RTC,
ASPEED_TIMER1,
ASPEED_TIMER2,
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index 1d7f7ffc1598..670804e85f28 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -43,6 +43,7 @@ typedef struct AspeedSCUState {
#define AST2600_A0_SILICON_REV 0x05000303U
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)
+#define ASPEED_IS_AST2600(si_rev) ((((si_rev) >> 24) & 0xff) == 0x05)
extern bool is_supported_silicon_rev(uint32_t silicon_rev);
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 03cc0952e8f3..f4f1dd29b011 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -88,6 +88,9 @@ struct AspeedBoardState {
/* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */
#define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1
+/* AST2600 evb hardware value: (QEMU prototype) */
+#define AST2600_EVB_HW_STRAP1 AST2500_EVB_HW_STRAP1
+
/*
* The max ram region is for firmwares that scan the address space
* with load/store to guess how much RAM the SoC has.
@@ -294,6 +297,12 @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338",
0x32);
}
+static void ast2600_evb_i2c_init(AspeedBoardState *bmc)
+{
+ /* Start with some devices on our I2C busses */
+ ast2500_evb_i2c_init(bmc);
+}
+
static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
@@ -441,6 +450,15 @@ static const AspeedBoardConfig aspeed_boards[] = {
.num_cs = 2,
.i2c_init = witherspoon_bmc_i2c_init,
.ram = 512 * MiB,
+ }, {
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
+ .desc = "Aspeed AST2600 EVB (Cortex A7)",
+ .soc_name = "ast2600-a0",
+ .hw_strap1 = AST2600_EVB_HW_STRAP1,
+ .fmc_model = "mx25l25635e",
+ .spi_model = "mx25l25635e",
+ .num_cs = 1,
+ .i2c_init = ast2600_evb_i2c_init,
},
};
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 5c5fcb810944..80d7f206004c 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -81,6 +81,38 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
[ASPEED_SDRAM] = 0x80000000,
};
+static const hwaddr aspeed_soc_ast2600_memmap[] = {
+ [ASPEED_SRAM] = 0x10000000,
+ /* 0x16000000 0x17FFFFFF : AHB BUS do LPC Bus bridge */
+ [ASPEED_IOMEM] = 0x1E600000,
+ [ASPEED_PWM] = 0x1E610000,
+ [ASPEED_FMC] = 0x1E620000,
+ [ASPEED_SPI1] = 0x1E630000,
+ [ASPEED_SPI2] = 0x1E641000,
+ [ASPEED_ETH1] = 0x1E660000,
+ [ASPEED_ETH2] = 0x1E680000,
+ [ASPEED_VIC] = 0x1E6C0000,
+ [ASPEED_SDMC] = 0x1E6E0000,
+ [ASPEED_SCU] = 0x1E6E2000,
+ [ASPEED_XDMA] = 0x1E6E7000,
+ [ASPEED_ADC] = 0x1E6E9000,
+ [ASPEED_SDHCI] = 0x1E740000,
+ [ASPEED_GPIO] = 0x1E780000,
+ [ASPEED_GPIO_1_8V] = 0x1E780800,
+ [ASPEED_RTC] = 0x1E781000,
+ [ASPEED_TIMER1] = 0x1E782000,
+ [ASPEED_WDT] = 0x1E785000,
+ [ASPEED_LPC] = 0x1E789000,
+ [ASPEED_IBT] = 0x1E789140,
+ [ASPEED_I2C] = 0x1E78A000,
+ [ASPEED_UART1] = 0x1E783000,
+ [ASPEED_UART5] = 0x1E784000,
+ [ASPEED_VUART] = 0x1E787000,
+ [ASPEED_SDRAM] = 0x80000000,
+};
+
+#define ASPEED_A7MPCORE_ADDR 0x40460000
+
static const int aspeed_soc_ast2400_irqmap[] = {
[ASPEED_UART1] = 9,
[ASPEED_UART2] = 32,
@@ -115,6 +147,41 @@ static const int aspeed_soc_ast2400_irqmap[] = {
#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
+#define ASPEED_SOC_AST2600_MAX_IRQ 128
+
+static const int aspeed_soc_ast2600_irqmap[] = {
+ [ASPEED_UART1] = 47,
+ [ASPEED_UART2] = 48,
+ [ASPEED_UART3] = 49,
+ [ASPEED_UART4] = 50,
+ [ASPEED_UART5] = 8,
+ [ASPEED_VUART] = 8,
+ [ASPEED_FMC] = 39,
+ [ASPEED_SDMC] = 0,
+ [ASPEED_SCU] = 12,
+ [ASPEED_XDMA] = 6,
+ [ASPEED_ADC] = 46,
+ [ASPEED_SDHCI] = 43,
+ [ASPEED_GPIO] = 40,
+ [ASPEED_GPIO_1_8V] = 11,
+ [ASPEED_RTC] = 13,
+ [ASPEED_TIMER1] = 16,
+ [ASPEED_TIMER2] = 17,
+ [ASPEED_TIMER3] = 18,
+ [ASPEED_TIMER4] = 19,
+ [ASPEED_TIMER5] = 20,
+ [ASPEED_TIMER6] = 21,
+ [ASPEED_TIMER7] = 22,
+ [ASPEED_TIMER8] = 23,
+ [ASPEED_WDT] = 24,
+ [ASPEED_PWM] = 44,
+ [ASPEED_LPC] = 35,
+ [ASPEED_IBT] = 35, /* LPC */
+ [ASPEED_I2C] = 110, /* 110 -> 125 */
+ [ASPEED_ETH1] = 2,
+ [ASPEED_ETH2] = 3,
+};
+
static const AspeedSoCInfo aspeed_socs[] = {
{
.name = "ast2400-a1",
@@ -136,14 +203,26 @@ static const AspeedSoCInfo aspeed_socs[] = {
.irqmap = aspeed_soc_ast2500_irqmap,
.memmap = aspeed_soc_ast2500_memmap,
.num_cpus = 1,
+ }, {
+ .name = "ast2600-a0",
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"),
+ .silicon_rev = AST2600_A0_SILICON_REV,
+ .sram_size = 0x10000,
+ .spis_num = 2,
+ .wdts_num = 4,
+ .irqmap = aspeed_soc_ast2600_irqmap,
+ .memmap = aspeed_soc_ast2600_memmap,
+ .num_cpus = 2,
},
};
static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
{
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ DeviceState *intc = ASPEED_IS_AST2600(sc->info->silicon_rev) ?
+ DEVICE(&s->a7mpcore) : DEVICE(&s->vic);
- return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]);
+ return qdev_get_gpio_in(intc, sc->info->irqmap[ctrl]);
}
static void aspeed_soc_init(Object *obj)
@@ -176,8 +255,13 @@ static void aspeed_soc_init(Object *obj)
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
"hw-prot-key", &error_abort);
- sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
- TYPE_ASPEED_VIC);
+ if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+ sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore,
+ sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
+ } else {
+ sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
+ TYPE_ASPEED_VIC);
+ }
sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc),
TYPE_ASPEED_RTC);
@@ -233,6 +317,12 @@ static void aspeed_soc_init(Object *obj)
sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
typename);
+ if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+ snprintf(typename, sizeof(typename), "aspeed.gpio-%s-1_8v", socname);
+ sysbus_init_child_obj(obj, "gpio_1_8v", OBJECT(&s->gpio_1_8v),
+ sizeof(s->gpio_1_8v), typename);
+ }
+
sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
TYPE_ASPEED_SDHCI);
@@ -243,6 +333,16 @@ static void aspeed_soc_init(Object *obj)
}
}
+/*
+ * ASPEED ast2600 has 0xf as cluster ID
+ *
+ *
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/CIHEBGFG.html
+ */
+static uint64_t aspeed_calc_affinity(int cpu)
+{
+ return (0xf << ARM_AFF1_SHIFT) | cpu;
+}
+
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
{
int i;
@@ -262,6 +362,23 @@ static void aspeed_soc_realize(DeviceState *dev, Error
**errp)
/* CPU */
for (i = 0; i < s->num_cpus; i++) {
+ if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+ object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC,
+ "psci-conduit", &error_abort);
+ if (s->num_cpus > 1) {
+ object_property_set_int(OBJECT(&s->cpu[i]),
+ ASPEED_A7MPCORE_ADDR,
+ "reset-cbar", &error_abort);
+ }
+ object_property_set_int(OBJECT(&s->cpu[i]),
aspeed_calc_affinity(i),
+ "mp-affinity", &error_abort);
+
+ /*
+ * TODO: the secondary CPUs are started and a boot helper
+ * is needed when using -kernel
+ */
+ }
+
object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
if (err) {
error_propagate(errp, err);
@@ -269,6 +386,48 @@ static void aspeed_soc_realize(DeviceState *dev, Error
**errp)
}
}
+ /* A7MPCORE */
+ if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+ qemu_irq irq;
+
+ object_property_set_int(OBJECT(&s->a7mpcore), s->num_cpus, "num-cpu",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->a7mpcore),
+ ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL,
+ "num-irq", &error_abort);
+
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
+ &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, ASPEED_A7MPCORE_ADDR);
+
+ for (i = 0; i < s->num_cpus; i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
+
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
+ sysbus_connect_irq(sbd, i, irq);
+ irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
+ sysbus_connect_irq(sbd, i + s->num_cpus, irq);
+ irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ);
+ sysbus_connect_irq(sbd, i + 2 * s->num_cpus, irq);
+ irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ);
+ sysbus_connect_irq(sbd, i + 3 * s->num_cpus, irq);
+ }
+ } else {
+ /* VIC */
+ object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0,
+ sc->info->memmap[ASPEED_VIC]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
+ }
+
/* SRAM */
memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram",
sc->info->sram_size, &err);
@@ -287,18 +446,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error
**errp)
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]);
- /* VIC */
- object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
-
/* RTC */
object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err);
if (err) {
@@ -433,6 +580,18 @@ static void aspeed_soc_realize(DeviceState *dev, Error
**errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
aspeed_soc_get_irq(s, ASPEED_GPIO));
+ if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+ object_property_set_bool(OBJECT(&s->gpio_1_8v), true, "realized",
&err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
+ sc->info->memmap[ASPEED_GPIO_1_8V]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
+ aspeed_soc_get_irq(s, ASPEED_GPIO_1_8V));
+ }
+
/* SDHCI */
object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
if (err) {
--
2.21.0
- [Qemu-arm] [RFC PATCH 02/15] aspeed/timer: Introduce an object class per SoC, (continued)
- [Qemu-arm] [RFC PATCH 02/15] aspeed/timer: Introduce an object class per SoC, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 03/15] aspeed/timer: Add support for control register 3, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 04/15] aspeed/timer: Add support for AST2600, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 05/15] aspeed/timer: Add support for IRQ status register on the AST2600, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 06/15] aspeed/sdmc: Introduce an object class per SoC, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 07/15] aspeed/sdmc: Add AST2600 support, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 08/15] watchdog/aspeed: Introduce an object class per SoC, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 09/15] hw: wdt_aspeed: Add AST2600 support, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 10/15] aspeed/smc: Add support for the AST2600 SoC, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 11/15] hw/gpio: Add in AST2600 specific implementation, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 12/15] aspeed: add support for the AST2600 eval board,
Cédric Le Goater <=
- [Qemu-arm] [RFC PATCH 13/15] aspeed: Parameterise number of MACs, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 14/15] aspeed: add support for the Aspeed MII controller of the AST2600, Cédric Le Goater, 2019/09/04
- [Qemu-arm] [RFC PATCH 15/15] aspeed/soc: Add ASPEED Video stub, Cédric Le Goater, 2019/09/04