143e3346eSAndrew Jeffery /* 2ff90606fSCédric Le Goater * ASPEED SoC family 343e3346eSAndrew Jeffery * 443e3346eSAndrew Jeffery * Andrew Jeffery <andrew@aj.id.au> 543e3346eSAndrew Jeffery * Jeremy Kerr <jk@ozlabs.org> 643e3346eSAndrew Jeffery * 743e3346eSAndrew Jeffery * Copyright 2016 IBM Corp. 843e3346eSAndrew Jeffery * 943e3346eSAndrew Jeffery * This code is licensed under the GPL version 2 or later. See 1043e3346eSAndrew Jeffery * the COPYING file in the top-level directory. 1143e3346eSAndrew Jeffery */ 1243e3346eSAndrew Jeffery 1343e3346eSAndrew Jeffery #include "qemu/osdep.h" 14da34e65cSMarkus Armbruster #include "qapi/error.h" 154771d756SPaolo Bonzini #include "cpu.h" 1643e3346eSAndrew Jeffery #include "exec/address-spaces.h" 17c7c3c9f8SPhilippe Mathieu-Daudé #include "hw/misc/unimp.h" 1800442402SCédric Le Goater #include "hw/arm/aspeed_soc.h" 1943e3346eSAndrew Jeffery #include "hw/char/serial.h" 2003dd024fSPaolo Bonzini #include "qemu/log.h" 210b8fa32fSMarkus Armbruster #include "qemu/module.h" 22ece09beeSCédric Le Goater #include "qemu/error-report.h" 2316020011SCédric Le Goater #include "hw/i2c/aspeed_i2c.h" 24ea337c65SCédric Le Goater #include "net/net.h" 2543e3346eSAndrew Jeffery 26ff90606fSCédric Le Goater #define ASPEED_SOC_IOMEM_SIZE 0x00200000 27d783d1feSCédric Le Goater 28d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2400_memmap[] = { 29d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 30d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 31d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 32d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 33d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 34d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 35118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 36d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 37d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 38d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 39d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 40d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 41d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 42d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 43d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 44d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 45d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 46d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 47d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 48d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 49d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 50d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 51d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x40000000, 52d783d1feSCédric Le Goater }; 53d783d1feSCédric Le Goater 54d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 55d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 56d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 57d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 58d783d1feSCédric Le Goater [ASPEED_SPI2] = 0x1E631000, 59d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 60d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 61d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 62118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 63d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 64d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 65d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 66d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 67d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 68d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 69d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 70d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 71d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 72d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 73d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 74d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 75d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 76d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 77d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 78d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x80000000, 79d783d1feSCédric Le Goater }; 8043e3346eSAndrew Jeffery 81b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 82b456b113SCédric Le Goater [ASPEED_UART1] = 9, 83b456b113SCédric Le Goater [ASPEED_UART2] = 32, 84b456b113SCédric Le Goater [ASPEED_UART3] = 33, 85b456b113SCédric Le Goater [ASPEED_UART4] = 34, 86b456b113SCédric Le Goater [ASPEED_UART5] = 10, 87b456b113SCédric Le Goater [ASPEED_VUART] = 8, 88b456b113SCédric Le Goater [ASPEED_FMC] = 19, 89b456b113SCédric Le Goater [ASPEED_SDMC] = 0, 90b456b113SCédric Le Goater [ASPEED_SCU] = 21, 91b456b113SCédric Le Goater [ASPEED_ADC] = 31, 92b456b113SCédric Le Goater [ASPEED_GPIO] = 20, 93b456b113SCédric Le Goater [ASPEED_RTC] = 22, 94b456b113SCédric Le Goater [ASPEED_TIMER1] = 16, 95b456b113SCédric Le Goater [ASPEED_TIMER2] = 17, 96b456b113SCédric Le Goater [ASPEED_TIMER3] = 18, 97b456b113SCédric Le Goater [ASPEED_TIMER4] = 35, 98b456b113SCédric Le Goater [ASPEED_TIMER5] = 36, 99b456b113SCédric Le Goater [ASPEED_TIMER6] = 37, 100b456b113SCédric Le Goater [ASPEED_TIMER7] = 38, 101b456b113SCédric Le Goater [ASPEED_TIMER8] = 39, 102b456b113SCédric Le Goater [ASPEED_WDT] = 27, 103b456b113SCédric Le Goater [ASPEED_PWM] = 28, 104b456b113SCédric Le Goater [ASPEED_LPC] = 8, 105b456b113SCédric Le Goater [ASPEED_IBT] = 8, /* LPC */ 106b456b113SCédric Le Goater [ASPEED_I2C] = 12, 107b456b113SCédric Le Goater [ASPEED_ETH1] = 2, 108b456b113SCédric Le Goater [ASPEED_ETH2] = 3, 109118c82e7SEddie James [ASPEED_XDMA] = 6, 110b456b113SCédric Le Goater }; 11143e3346eSAndrew Jeffery 112b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 113b456b113SCédric Le Goater 1146dc52326SCédric Le Goater static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" }; 1156dc52326SCédric Le Goater static const char *aspeed_soc_ast2500_typenames[] = { 1166dc52326SCédric Le Goater "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" }; 117dbcabeebSCédric Le Goater 118b033271fSCédric Le Goater static const AspeedSoCInfo aspeed_socs[] = { 11974af4eecSCédric Le Goater { 12074af4eecSCédric Le Goater .name = "ast2400-a0", 121ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm926"), 12274af4eecSCédric Le Goater .silicon_rev = AST2400_A0_SILICON_REV, 12374af4eecSCédric Le Goater .sram_size = 0x8000, 12474af4eecSCédric Le Goater .spis_num = 1, 12574af4eecSCédric Le Goater .fmc_typename = "aspeed.smc.fmc", 12674af4eecSCédric Le Goater .spi_typename = aspeed_soc_ast2400_typenames, 127f986ee1dSJoel Stanley .wdts_num = 2, 128b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2400_irqmap, 129d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2400_memmap, 130ece09beeSCédric Le Goater .num_cpus = 1, 13174af4eecSCédric Le Goater }, { 1326efbac90SCédric Le Goater .name = "ast2400-a1", 133ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm926"), 1346efbac90SCédric Le Goater .silicon_rev = AST2400_A1_SILICON_REV, 1356efbac90SCédric Le Goater .sram_size = 0x8000, 1366efbac90SCédric Le Goater .spis_num = 1, 1376efbac90SCédric Le Goater .fmc_typename = "aspeed.smc.fmc", 1386efbac90SCédric Le Goater .spi_typename = aspeed_soc_ast2400_typenames, 139f986ee1dSJoel Stanley .wdts_num = 2, 140b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2400_irqmap, 141d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2400_memmap, 142ece09beeSCédric Le Goater .num_cpus = 1, 1436efbac90SCédric Le Goater }, { 14474af4eecSCédric Le Goater .name = "ast2400", 145ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm926"), 14674af4eecSCédric Le Goater .silicon_rev = AST2400_A0_SILICON_REV, 14774af4eecSCédric Le Goater .sram_size = 0x8000, 14874af4eecSCédric Le Goater .spis_num = 1, 14974af4eecSCédric Le Goater .fmc_typename = "aspeed.smc.fmc", 15074af4eecSCédric Le Goater .spi_typename = aspeed_soc_ast2400_typenames, 151f986ee1dSJoel Stanley .wdts_num = 2, 152b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2400_irqmap, 153d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2400_memmap, 154ece09beeSCédric Le Goater .num_cpus = 1, 15574af4eecSCédric Le Goater }, { 15674af4eecSCédric Le Goater .name = "ast2500-a1", 157ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm1176"), 15874af4eecSCédric Le Goater .silicon_rev = AST2500_A1_SILICON_REV, 15974af4eecSCédric Le Goater .sram_size = 0x9000, 16074af4eecSCédric Le Goater .spis_num = 2, 16174af4eecSCédric Le Goater .fmc_typename = "aspeed.smc.ast2500-fmc", 16274af4eecSCédric Le Goater .spi_typename = aspeed_soc_ast2500_typenames, 163f986ee1dSJoel Stanley .wdts_num = 3, 164b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2500_irqmap, 165d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2500_memmap, 166ece09beeSCédric Le Goater .num_cpus = 1, 16774af4eecSCédric Le Goater }, 168b033271fSCédric Le Goater }; 169b033271fSCédric Le Goater 170b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 171b456b113SCédric Le Goater { 172b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 173b456b113SCédric Le Goater 174b456b113SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]); 175b456b113SCédric Le Goater } 176b456b113SCédric Le Goater 177ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 17843e3346eSAndrew Jeffery { 179ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 180b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 181dbcabeebSCédric Le Goater int i; 18243e3346eSAndrew Jeffery 183ece09beeSCédric Le Goater for (i = 0; i < sc->info->num_cpus; i++) { 184ece09beeSCédric Le Goater object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), 185ece09beeSCédric Le Goater sizeof(s->cpu[i]), sc->info->cpu_type, 186ece09beeSCédric Le Goater &error_abort, NULL); 187ece09beeSCédric Le Goater } 18843e3346eSAndrew Jeffery 1891b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu), 1901b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_SCU); 191334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 192b033271fSCédric Le Goater sc->info->silicon_rev); 193334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 194334973bbSAndrew Jeffery "hw-strap1", &error_abort); 195334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 196334973bbSAndrew Jeffery "hw-strap2", &error_abort); 197b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 198b6e70d1dSJoel Stanley "hw-prot-key", &error_abort); 1997c1c69bcSCédric Le Goater 2001b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic), 2011b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_VIC); 202e2a11ca8SCédric Le Goater 20375fb4577SJoel Stanley sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc), 20475fb4577SJoel Stanley TYPE_ASPEED_RTC); 20575fb4577SJoel Stanley 2061b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), 2071b0ad567SPhilippe Mathieu-Daudé sizeof(s->timerctrl), TYPE_ASPEED_TIMER); 2089b945a9eSCédric Le Goater object_property_add_const_link(OBJECT(&s->timerctrl), "scu", 2099b945a9eSCédric Le Goater OBJECT(&s->scu), &error_abort); 210e2a11ca8SCédric Le Goater 2111b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), 2121b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_I2C); 213e2a11ca8SCédric Le Goater 2141b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc), 2151b0ad567SPhilippe Mathieu-Daudé sc->info->fmc_typename); 21626d5df95SCédric Le Goater object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", 21726d5df95SCédric Le Goater &error_abort); 2187c1c69bcSCédric Le Goater 219dbcabeebSCédric Le Goater for (i = 0; i < sc->info->spis_num; i++) { 2201b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), 2211b0ad567SPhilippe Mathieu-Daudé sizeof(s->spi[i]), sc->info->spi_typename[i]); 222dbcabeebSCédric Le Goater } 223c2da8a8bSCédric Le Goater 2241b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), 2251b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_SDMC); 226c2da8a8bSCédric Le Goater qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev", 227b033271fSCédric Le Goater sc->info->silicon_rev); 228c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 229c6c7cfb0SCédric Le Goater "ram-size", &error_abort); 230ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 231ebe31c0aSCédric Le Goater "max-ram-size", &error_abort); 232013befe1SCédric Le Goater 233f986ee1dSJoel Stanley for (i = 0; i < sc->info->wdts_num; i++) { 2341b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), 2351b0ad567SPhilippe Mathieu-Daudé sizeof(s->wdt[i]), TYPE_ASPEED_WDT); 236429789ccSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev", 237429789ccSAndrew Jeffery sc->info->silicon_rev); 238f986ee1dSJoel Stanley } 239ea337c65SCédric Le Goater 24067340990SCédric Le Goater for (i = 0; i < ASPEED_MACS_NUM; i++) { 24167340990SCédric Le Goater sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]), 24267340990SCédric Le Goater sizeof(s->ftgmac100[i]), TYPE_FTGMAC100); 24367340990SCédric Le Goater } 244118c82e7SEddie James 245118c82e7SEddie James sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), 246118c82e7SEddie James TYPE_ASPEED_XDMA); 24743e3346eSAndrew Jeffery } 24843e3346eSAndrew Jeffery 249ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 25043e3346eSAndrew Jeffery { 25143e3346eSAndrew Jeffery int i; 252ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 253dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2547c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 25543e3346eSAndrew Jeffery 25643e3346eSAndrew Jeffery /* IO space */ 257d783d1feSCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->info->memmap[ASPEED_IOMEM], 258d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 25943e3346eSAndrew Jeffery 260ece09beeSCédric Le Goater if (s->num_cpus > sc->info->num_cpus) { 261ece09beeSCédric Le Goater warn_report("%s: invalid number of CPUs %d, using default %d", 262ece09beeSCédric Le Goater sc->info->name, s->num_cpus, sc->info->num_cpus); 263ece09beeSCédric Le Goater s->num_cpus = sc->info->num_cpus; 264ece09beeSCédric Le Goater } 265ece09beeSCédric Le Goater 2662d105bd6SCédric Le Goater /* CPU */ 267ece09beeSCédric Le Goater for (i = 0; i < s->num_cpus; i++) { 268ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2692d105bd6SCédric Le Goater if (err) { 2702d105bd6SCédric Le Goater error_propagate(errp, err); 2712d105bd6SCédric Le Goater return; 2722d105bd6SCédric Le Goater } 273ece09beeSCédric Le Goater } 2742d105bd6SCédric Le Goater 27574af4eecSCédric Le Goater /* SRAM */ 276a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 27774af4eecSCédric Le Goater sc->info->sram_size, &err); 27874af4eecSCédric Le Goater if (err) { 27974af4eecSCédric Le Goater error_propagate(errp, err); 28074af4eecSCédric Le Goater return; 28174af4eecSCédric Le Goater } 282d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 283d783d1feSCédric Le Goater sc->info->memmap[ASPEED_SRAM], &s->sram); 28474af4eecSCédric Le Goater 285e2a11ca8SCédric Le Goater /* SCU */ 286e2a11ca8SCédric Le Goater object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); 287e2a11ca8SCédric Le Goater if (err) { 288e2a11ca8SCédric Le Goater error_propagate(errp, err); 289e2a11ca8SCédric Le Goater return; 290e2a11ca8SCédric Le Goater } 291d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]); 292e2a11ca8SCédric Le Goater 29343e3346eSAndrew Jeffery /* VIC */ 29443e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); 29543e3346eSAndrew Jeffery if (err) { 29643e3346eSAndrew Jeffery error_propagate(errp, err); 29743e3346eSAndrew Jeffery return; 29843e3346eSAndrew Jeffery } 299d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]); 30043e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 3012d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 30243e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 3032d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 30443e3346eSAndrew Jeffery 30575fb4577SJoel Stanley /* RTC */ 30675fb4577SJoel Stanley object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); 30775fb4577SJoel Stanley if (err) { 30875fb4577SJoel Stanley error_propagate(errp, err); 30975fb4577SJoel Stanley return; 31075fb4577SJoel Stanley } 31175fb4577SJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->info->memmap[ASPEED_RTC]); 31275fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 31375fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 31475fb4577SJoel Stanley 31543e3346eSAndrew Jeffery /* Timer */ 31643e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); 31743e3346eSAndrew Jeffery if (err) { 31843e3346eSAndrew Jeffery error_propagate(errp, err); 31943e3346eSAndrew Jeffery return; 32043e3346eSAndrew Jeffery } 321d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 322d783d1feSCédric Le Goater sc->info->memmap[ASPEED_TIMER1]); 323b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 324b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 32543e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 32643e3346eSAndrew Jeffery } 32743e3346eSAndrew Jeffery 32843e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 3299bca0edbSPeter Maydell if (serial_hd(0)) { 330b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 331d783d1feSCédric Le Goater serial_mm_init(get_system_memory(), sc->info->memmap[ASPEED_UART5], 2, 3329bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 33343e3346eSAndrew Jeffery } 33416020011SCédric Le Goater 33516020011SCédric Le Goater /* I2C */ 33616020011SCédric Le Goater object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); 33716020011SCédric Le Goater if (err) { 33816020011SCédric Le Goater error_propagate(errp, err); 33916020011SCédric Le Goater return; 34016020011SCédric Le Goater } 341d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->info->memmap[ASPEED_I2C]); 34216020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 343b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3447c1c69bcSCédric Le Goater 34526d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3466da4433fSCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->info->memmap[ASPEED_SDRAM], 3476da4433fSCédric Le Goater "sdram-base", &err); 3486da4433fSCédric Le Goater if (err) { 3496da4433fSCédric Le Goater error_propagate(errp, err); 3506da4433fSCédric Le Goater return; 3516da4433fSCédric Le Goater } 35226d5df95SCédric Le Goater object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); 3537c1c69bcSCédric Le Goater if (err) { 3547c1c69bcSCédric Le Goater error_propagate(errp, err); 3557c1c69bcSCédric Le Goater return; 3567c1c69bcSCédric Le Goater } 357d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->info->memmap[ASPEED_FMC]); 358dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 359dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3600e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 361b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3627c1c69bcSCédric Le Goater 3637c1c69bcSCédric Le Goater /* SPI */ 364dbcabeebSCédric Le Goater for (i = 0; i < sc->info->spis_num; i++) { 365dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 366dbcabeebSCédric Le Goater object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 367dbcabeebSCédric Le Goater &local_err); 3687c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3697c1c69bcSCédric Le Goater if (err) { 3707c1c69bcSCédric Le Goater error_propagate(errp, err); 3717c1c69bcSCédric Le Goater return; 3727c1c69bcSCédric Le Goater } 373d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 374d783d1feSCédric Le Goater sc->info->memmap[ASPEED_SPI1 + i]); 375dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 376dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 377dbcabeebSCédric Le Goater } 378c2da8a8bSCédric Le Goater 379c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 380c2da8a8bSCédric Le Goater object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); 381c2da8a8bSCédric Le Goater if (err) { 382c2da8a8bSCédric Le Goater error_propagate(errp, err); 383c2da8a8bSCédric Le Goater return; 384c2da8a8bSCédric Le Goater } 385d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->info->memmap[ASPEED_SDMC]); 386013befe1SCédric Le Goater 387013befe1SCédric Le Goater /* Watch dog */ 388f986ee1dSJoel Stanley for (i = 0; i < sc->info->wdts_num; i++) { 389f986ee1dSJoel Stanley object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); 390013befe1SCédric Le Goater if (err) { 391013befe1SCédric Le Goater error_propagate(errp, err); 392013befe1SCédric Le Goater return; 393013befe1SCédric Le Goater } 394f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 395d783d1feSCédric Le Goater sc->info->memmap[ASPEED_WDT] + i * 0x20); 396f986ee1dSJoel Stanley } 397ea337c65SCédric Le Goater 398ea337c65SCédric Le Goater /* Net */ 39967340990SCédric Le Goater for (i = 0; i < nb_nics; i++) { 40067340990SCédric Le Goater qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]); 40167340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 40267340990SCédric Le Goater &err); 40367340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized", 404ea337c65SCédric Le Goater &local_err); 405ea337c65SCédric Le Goater error_propagate(&err, local_err); 406ea337c65SCédric Le Goater if (err) { 407ea337c65SCédric Le Goater error_propagate(errp, err); 408ea337c65SCédric Le Goater return; 409ea337c65SCédric Le Goater } 41067340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 41167340990SCédric Le Goater sc->info->memmap[ASPEED_ETH1 + i]); 41267340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 41367340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 41467340990SCédric Le Goater } 415118c82e7SEddie James 416118c82e7SEddie James /* XDMA */ 417118c82e7SEddie James object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err); 418118c82e7SEddie James if (err) { 419118c82e7SEddie James error_propagate(errp, err); 420118c82e7SEddie James return; 421118c82e7SEddie James } 422118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 423118c82e7SEddie James sc->info->memmap[ASPEED_XDMA]); 424118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 425118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 42643e3346eSAndrew Jeffery } 427ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 428ece09beeSCédric Le Goater DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), 429ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 430ece09beeSCédric Le Goater }; 43143e3346eSAndrew Jeffery 432ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 43343e3346eSAndrew Jeffery { 43443e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 435b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 43643e3346eSAndrew Jeffery 437b033271fSCédric Le Goater sc->info = (AspeedSoCInfo *) data; 438ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 439469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 440469f3da4SThomas Huth dc->user_creatable = false; 441ece09beeSCédric Le Goater dc->props = aspeed_soc_properties; 44243e3346eSAndrew Jeffery } 44343e3346eSAndrew Jeffery 444ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 445ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 446b033271fSCédric Le Goater .parent = TYPE_DEVICE, 447ff90606fSCédric Le Goater .instance_init = aspeed_soc_init, 448b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 449b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 450b033271fSCédric Le Goater .abstract = true, 45143e3346eSAndrew Jeffery }; 45243e3346eSAndrew Jeffery 453ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 45443e3346eSAndrew Jeffery { 455b033271fSCédric Le Goater int i; 456b033271fSCédric Le Goater 457ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 458b033271fSCédric Le Goater for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) { 459b033271fSCédric Le Goater TypeInfo ti = { 460b033271fSCédric Le Goater .name = aspeed_socs[i].name, 461b033271fSCédric Le Goater .parent = TYPE_ASPEED_SOC, 462b033271fSCédric Le Goater .class_init = aspeed_soc_class_init, 463b033271fSCédric Le Goater .class_data = (void *) &aspeed_socs[i], 464b033271fSCédric Le Goater }; 465b033271fSCédric Le Goater type_register(&ti); 466b033271fSCédric Le Goater } 46743e3346eSAndrew Jeffery } 46843e3346eSAndrew Jeffery 469ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 470