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" 2546517dd4SMarkus Armbruster #include "sysemu/sysemu.h" 2643e3346eSAndrew Jeffery 27ff90606fSCédric Le Goater #define ASPEED_SOC_IOMEM_SIZE 0x00200000 28d783d1feSCédric Le Goater 29d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2400_memmap[] = { 30d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 31d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 32d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 33d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 34d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 35d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 36118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 37d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 38d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 392bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 40d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 41d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 42d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 43d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 44d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 45d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 46d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 47d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 48d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 49d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 50d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 51d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 52d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 53d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x40000000, 54d783d1feSCédric Le Goater }; 55d783d1feSCédric Le Goater 56d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 57d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 58d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 59d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 60d783d1feSCédric Le Goater [ASPEED_SPI2] = 0x1E631000, 61d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 62d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 63d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 64118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 65d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 66d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 672bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 68d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 69d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 70d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 71d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 72d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 73d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 74d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 75d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 76d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 77d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 78d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 79d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 80d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 81d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x80000000, 82d783d1feSCédric Le Goater }; 8343e3346eSAndrew Jeffery 84b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 85b456b113SCédric Le Goater [ASPEED_UART1] = 9, 86b456b113SCédric Le Goater [ASPEED_UART2] = 32, 87b456b113SCédric Le Goater [ASPEED_UART3] = 33, 88b456b113SCédric Le Goater [ASPEED_UART4] = 34, 89b456b113SCédric Le Goater [ASPEED_UART5] = 10, 90b456b113SCédric Le Goater [ASPEED_VUART] = 8, 91b456b113SCédric Le Goater [ASPEED_FMC] = 19, 92b456b113SCédric Le Goater [ASPEED_SDMC] = 0, 93b456b113SCédric Le Goater [ASPEED_SCU] = 21, 94b456b113SCédric Le Goater [ASPEED_ADC] = 31, 95b456b113SCédric Le Goater [ASPEED_GPIO] = 20, 96b456b113SCédric Le Goater [ASPEED_RTC] = 22, 97b456b113SCédric Le Goater [ASPEED_TIMER1] = 16, 98b456b113SCédric Le Goater [ASPEED_TIMER2] = 17, 99b456b113SCédric Le Goater [ASPEED_TIMER3] = 18, 100b456b113SCédric Le Goater [ASPEED_TIMER4] = 35, 101b456b113SCédric Le Goater [ASPEED_TIMER5] = 36, 102b456b113SCédric Le Goater [ASPEED_TIMER6] = 37, 103b456b113SCédric Le Goater [ASPEED_TIMER7] = 38, 104b456b113SCédric Le Goater [ASPEED_TIMER8] = 39, 105b456b113SCédric Le Goater [ASPEED_WDT] = 27, 106b456b113SCédric Le Goater [ASPEED_PWM] = 28, 107b456b113SCédric Le Goater [ASPEED_LPC] = 8, 108b456b113SCédric Le Goater [ASPEED_IBT] = 8, /* LPC */ 109b456b113SCédric Le Goater [ASPEED_I2C] = 12, 110b456b113SCédric Le Goater [ASPEED_ETH1] = 2, 111b456b113SCédric Le Goater [ASPEED_ETH2] = 3, 112118c82e7SEddie James [ASPEED_XDMA] = 6, 1132bea128cSEddie James [ASPEED_SDHCI] = 26, 114b456b113SCédric Le Goater }; 11543e3346eSAndrew Jeffery 116b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 117b456b113SCédric Le Goater 118b033271fSCédric Le Goater static const AspeedSoCInfo aspeed_socs[] = { 11974af4eecSCédric Le Goater { 1206efbac90SCédric Le Goater .name = "ast2400-a1", 121ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm926"), 1226efbac90SCédric Le Goater .silicon_rev = AST2400_A1_SILICON_REV, 1236efbac90SCédric Le Goater .sram_size = 0x8000, 1246efbac90SCédric Le Goater .spis_num = 1, 125f986ee1dSJoel Stanley .wdts_num = 2, 126b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2400_irqmap, 127d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2400_memmap, 128ece09beeSCédric Le Goater .num_cpus = 1, 1296efbac90SCédric Le Goater }, { 13074af4eecSCédric Le Goater .name = "ast2500-a1", 131ba1ba5ccSIgor Mammedov .cpu_type = ARM_CPU_TYPE_NAME("arm1176"), 13274af4eecSCédric Le Goater .silicon_rev = AST2500_A1_SILICON_REV, 13374af4eecSCédric Le Goater .sram_size = 0x9000, 13474af4eecSCédric Le Goater .spis_num = 2, 135f986ee1dSJoel Stanley .wdts_num = 3, 136b456b113SCédric Le Goater .irqmap = aspeed_soc_ast2500_irqmap, 137d783d1feSCédric Le Goater .memmap = aspeed_soc_ast2500_memmap, 138ece09beeSCédric Le Goater .num_cpus = 1, 13974af4eecSCédric Le Goater }, 140b033271fSCédric Le Goater }; 141b033271fSCédric Le Goater 142b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 143b456b113SCédric Le Goater { 144b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 145b456b113SCédric Le Goater 146b456b113SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]); 147b456b113SCédric Le Goater } 148b456b113SCédric Le Goater 149ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 15043e3346eSAndrew Jeffery { 151ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 152b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 153dbcabeebSCédric Le Goater int i; 154811a5b1dSCédric Le Goater char socname[8]; 155811a5b1dSCédric Le Goater char typename[64]; 156811a5b1dSCédric Le Goater 157811a5b1dSCédric Le Goater if (sscanf(sc->info->name, "%7s", socname) != 1) { 158811a5b1dSCédric Le Goater g_assert_not_reached(); 159811a5b1dSCédric Le Goater } 16043e3346eSAndrew Jeffery 161ece09beeSCédric Le Goater for (i = 0; i < sc->info->num_cpus; i++) { 162ece09beeSCédric Le Goater object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), 163ece09beeSCédric Le Goater sizeof(s->cpu[i]), sc->info->cpu_type, 164ece09beeSCédric Le Goater &error_abort, NULL); 165ece09beeSCédric Le Goater } 16643e3346eSAndrew Jeffery 1679a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 1681b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu), 1699a937f6cSCédric Le Goater typename); 170334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 171b033271fSCédric Le Goater sc->info->silicon_rev); 172334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 173334973bbSAndrew Jeffery "hw-strap1", &error_abort); 174334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 175334973bbSAndrew Jeffery "hw-strap2", &error_abort); 176b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 177b6e70d1dSJoel Stanley "hw-prot-key", &error_abort); 1787c1c69bcSCédric Le Goater 1791b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic), 1801b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_VIC); 181e2a11ca8SCédric Le Goater 18275fb4577SJoel Stanley sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc), 18375fb4577SJoel Stanley TYPE_ASPEED_RTC); 18475fb4577SJoel Stanley 18572d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 1861b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), 18772d96f8eSCédric Le Goater sizeof(s->timerctrl), typename); 1889b945a9eSCédric Le Goater object_property_add_const_link(OBJECT(&s->timerctrl), "scu", 1899b945a9eSCédric Le Goater OBJECT(&s->scu), &error_abort); 190e2a11ca8SCédric Le Goater 1911b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), 1921b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_I2C); 193e2a11ca8SCédric Le Goater 194811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 1951b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc), 196811a5b1dSCédric Le Goater typename); 19726d5df95SCédric Le Goater object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", 19826d5df95SCédric Le Goater &error_abort); 199c4e1f0b4SCédric Le Goater object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", 200c4e1f0b4SCédric Le Goater &error_abort); 2017c1c69bcSCédric Le Goater 202dbcabeebSCédric Le Goater for (i = 0; i < sc->info->spis_num; i++) { 203811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 2041b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), 205811a5b1dSCédric Le Goater sizeof(s->spi[i]), typename); 206dbcabeebSCédric Le Goater } 207c2da8a8bSCédric Le Goater 2081b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), 2091b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_SDMC); 210c2da8a8bSCédric Le Goater qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev", 211b033271fSCédric Le Goater sc->info->silicon_rev); 212c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 213c6c7cfb0SCédric Le Goater "ram-size", &error_abort); 214ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 215ebe31c0aSCédric Le Goater "max-ram-size", &error_abort); 216013befe1SCédric Le Goater 217f986ee1dSJoel Stanley for (i = 0; i < sc->info->wdts_num; i++) { 2181b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), 2191b0ad567SPhilippe Mathieu-Daudé sizeof(s->wdt[i]), TYPE_ASPEED_WDT); 220429789ccSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev", 221429789ccSAndrew Jeffery sc->info->silicon_rev); 2223059c2f5SJoel Stanley object_property_add_const_link(OBJECT(&s->wdt[i]), "scu", 2233059c2f5SJoel Stanley OBJECT(&s->scu), &error_abort); 224f986ee1dSJoel Stanley } 225ea337c65SCédric Le Goater 22667340990SCédric Le Goater for (i = 0; i < ASPEED_MACS_NUM; i++) { 22767340990SCédric Le Goater sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]), 22867340990SCédric Le Goater sizeof(s->ftgmac100[i]), TYPE_FTGMAC100); 22967340990SCédric Le Goater } 230118c82e7SEddie James 231118c82e7SEddie James sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), 232118c82e7SEddie James TYPE_ASPEED_XDMA); 233fdcc7c06SRashmica Gupta 234811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 235fdcc7c06SRashmica Gupta sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio), 236811a5b1dSCédric Le Goater typename); 2372bea128cSEddie James 2382bea128cSEddie James sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci), 2392bea128cSEddie James TYPE_ASPEED_SDHCI); 2402bea128cSEddie James 2412bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2422bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2432bea128cSEddie James sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]), 2442bea128cSEddie James sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI); 2452bea128cSEddie James } 24643e3346eSAndrew Jeffery } 24743e3346eSAndrew Jeffery 248ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 24943e3346eSAndrew Jeffery { 25043e3346eSAndrew Jeffery int i; 251ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 252dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2537c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 25443e3346eSAndrew Jeffery 25543e3346eSAndrew Jeffery /* IO space */ 256d783d1feSCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->info->memmap[ASPEED_IOMEM], 257d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 25843e3346eSAndrew Jeffery 259ece09beeSCédric Le Goater if (s->num_cpus > sc->info->num_cpus) { 260ece09beeSCédric Le Goater warn_report("%s: invalid number of CPUs %d, using default %d", 261ece09beeSCédric Le Goater sc->info->name, s->num_cpus, sc->info->num_cpus); 262ece09beeSCédric Le Goater s->num_cpus = sc->info->num_cpus; 263ece09beeSCédric Le Goater } 264ece09beeSCédric Le Goater 2652d105bd6SCédric Le Goater /* CPU */ 266ece09beeSCédric Le Goater for (i = 0; i < s->num_cpus; i++) { 267ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2682d105bd6SCédric Le Goater if (err) { 2692d105bd6SCédric Le Goater error_propagate(errp, err); 2702d105bd6SCédric Le Goater return; 2712d105bd6SCédric Le Goater } 272ece09beeSCédric Le Goater } 2732d105bd6SCédric Le Goater 27474af4eecSCédric Le Goater /* SRAM */ 275a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 27674af4eecSCédric Le Goater sc->info->sram_size, &err); 27774af4eecSCédric Le Goater if (err) { 27874af4eecSCédric Le Goater error_propagate(errp, err); 27974af4eecSCédric Le Goater return; 28074af4eecSCédric Le Goater } 281d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 282d783d1feSCédric Le Goater sc->info->memmap[ASPEED_SRAM], &s->sram); 28374af4eecSCédric Le Goater 284e2a11ca8SCédric Le Goater /* SCU */ 285e2a11ca8SCédric Le Goater object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); 286e2a11ca8SCédric Le Goater if (err) { 287e2a11ca8SCédric Le Goater error_propagate(errp, err); 288e2a11ca8SCédric Le Goater return; 289e2a11ca8SCédric Le Goater } 290d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]); 291e2a11ca8SCédric Le Goater 29243e3346eSAndrew Jeffery /* VIC */ 29343e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); 29443e3346eSAndrew Jeffery if (err) { 29543e3346eSAndrew Jeffery error_propagate(errp, err); 29643e3346eSAndrew Jeffery return; 29743e3346eSAndrew Jeffery } 298d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]); 29943e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 3002d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 30143e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 3022d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 30343e3346eSAndrew Jeffery 30475fb4577SJoel Stanley /* RTC */ 30575fb4577SJoel Stanley object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); 30675fb4577SJoel Stanley if (err) { 30775fb4577SJoel Stanley error_propagate(errp, err); 30875fb4577SJoel Stanley return; 30975fb4577SJoel Stanley } 31075fb4577SJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->info->memmap[ASPEED_RTC]); 31175fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 31275fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 31375fb4577SJoel Stanley 31443e3346eSAndrew Jeffery /* Timer */ 31543e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); 31643e3346eSAndrew Jeffery if (err) { 31743e3346eSAndrew Jeffery error_propagate(errp, err); 31843e3346eSAndrew Jeffery return; 31943e3346eSAndrew Jeffery } 320d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 321d783d1feSCédric Le Goater sc->info->memmap[ASPEED_TIMER1]); 322b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 323b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 32443e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 32543e3346eSAndrew Jeffery } 32643e3346eSAndrew Jeffery 32743e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 3289bca0edbSPeter Maydell if (serial_hd(0)) { 329b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 330d783d1feSCédric Le Goater serial_mm_init(get_system_memory(), sc->info->memmap[ASPEED_UART5], 2, 3319bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 33243e3346eSAndrew Jeffery } 33316020011SCédric Le Goater 33416020011SCédric Le Goater /* I2C */ 33516020011SCédric Le Goater object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); 33616020011SCédric Le Goater if (err) { 33716020011SCédric Le Goater error_propagate(errp, err); 33816020011SCédric Le Goater return; 33916020011SCédric Le Goater } 340d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->info->memmap[ASPEED_I2C]); 34116020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 342b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3437c1c69bcSCédric Le Goater 34426d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3456da4433fSCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->info->memmap[ASPEED_SDRAM], 3466da4433fSCédric Le Goater "sdram-base", &err); 3476da4433fSCédric Le Goater if (err) { 3486da4433fSCédric Le Goater error_propagate(errp, err); 3496da4433fSCédric Le Goater return; 3506da4433fSCédric Le Goater } 35126d5df95SCédric Le Goater object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); 3527c1c69bcSCédric Le Goater if (err) { 3537c1c69bcSCédric Le Goater error_propagate(errp, err); 3547c1c69bcSCédric Le Goater return; 3557c1c69bcSCédric Le Goater } 356d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->info->memmap[ASPEED_FMC]); 357dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 358dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3590e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 360b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3617c1c69bcSCédric Le Goater 3627c1c69bcSCédric Le Goater /* SPI */ 363dbcabeebSCédric Le Goater for (i = 0; i < sc->info->spis_num; i++) { 364dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 365dbcabeebSCédric Le Goater object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 366dbcabeebSCédric Le Goater &local_err); 3677c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3687c1c69bcSCédric Le Goater if (err) { 3697c1c69bcSCédric Le Goater error_propagate(errp, err); 3707c1c69bcSCédric Le Goater return; 3717c1c69bcSCédric Le Goater } 372d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 373d783d1feSCédric Le Goater sc->info->memmap[ASPEED_SPI1 + i]); 374dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 375dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 376dbcabeebSCédric Le Goater } 377c2da8a8bSCédric Le Goater 378c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 379c2da8a8bSCédric Le Goater object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); 380c2da8a8bSCédric Le Goater if (err) { 381c2da8a8bSCédric Le Goater error_propagate(errp, err); 382c2da8a8bSCédric Le Goater return; 383c2da8a8bSCédric Le Goater } 384d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->info->memmap[ASPEED_SDMC]); 385013befe1SCédric Le Goater 386013befe1SCédric Le Goater /* Watch dog */ 387f986ee1dSJoel Stanley for (i = 0; i < sc->info->wdts_num; i++) { 388f986ee1dSJoel Stanley object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); 389013befe1SCédric Le Goater if (err) { 390013befe1SCédric Le Goater error_propagate(errp, err); 391013befe1SCédric Le Goater return; 392013befe1SCédric Le Goater } 393f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 394d783d1feSCédric Le Goater sc->info->memmap[ASPEED_WDT] + i * 0x20); 395f986ee1dSJoel Stanley } 396ea337c65SCédric Le Goater 397ea337c65SCédric Le Goater /* Net */ 39867340990SCédric Le Goater for (i = 0; i < nb_nics; i++) { 39967340990SCédric Le Goater qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]); 40067340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 40167340990SCédric Le Goater &err); 40267340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized", 403ea337c65SCédric Le Goater &local_err); 404ea337c65SCédric Le Goater error_propagate(&err, local_err); 405ea337c65SCédric Le Goater if (err) { 406ea337c65SCédric Le Goater error_propagate(errp, err); 407ea337c65SCédric Le Goater return; 408ea337c65SCédric Le Goater } 40967340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 41067340990SCédric Le Goater sc->info->memmap[ASPEED_ETH1 + i]); 41167340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 41267340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 41367340990SCédric Le Goater } 414118c82e7SEddie James 415118c82e7SEddie James /* XDMA */ 416118c82e7SEddie James object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err); 417118c82e7SEddie James if (err) { 418118c82e7SEddie James error_propagate(errp, err); 419118c82e7SEddie James return; 420118c82e7SEddie James } 421118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 422118c82e7SEddie James sc->info->memmap[ASPEED_XDMA]); 423118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 424118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 425fdcc7c06SRashmica Gupta 426fdcc7c06SRashmica Gupta /* GPIO */ 427fdcc7c06SRashmica Gupta object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err); 428fdcc7c06SRashmica Gupta if (err) { 429fdcc7c06SRashmica Gupta error_propagate(errp, err); 430fdcc7c06SRashmica Gupta return; 431fdcc7c06SRashmica Gupta } 432fdcc7c06SRashmica Gupta sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->info->memmap[ASPEED_GPIO]); 433fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 434fdcc7c06SRashmica Gupta aspeed_soc_get_irq(s, ASPEED_GPIO)); 4352bea128cSEddie James 4362bea128cSEddie James /* SDHCI */ 4372bea128cSEddie James object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err); 4382bea128cSEddie James if (err) { 4392bea128cSEddie James error_propagate(errp, err); 4402bea128cSEddie James return; 4412bea128cSEddie James } 4422bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 4432bea128cSEddie James sc->info->memmap[ASPEED_SDHCI]); 4442bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 4452bea128cSEddie James aspeed_soc_get_irq(s, ASPEED_SDHCI)); 44643e3346eSAndrew Jeffery } 447ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 448ece09beeSCédric Le Goater DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), 449ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 450ece09beeSCédric Le Goater }; 45143e3346eSAndrew Jeffery 452ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 45343e3346eSAndrew Jeffery { 45443e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 455b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 45643e3346eSAndrew Jeffery 457b033271fSCédric Le Goater sc->info = (AspeedSoCInfo *) data; 458ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 459469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 460469f3da4SThomas Huth dc->user_creatable = false; 461ece09beeSCédric Le Goater dc->props = aspeed_soc_properties; 46243e3346eSAndrew Jeffery } 46343e3346eSAndrew Jeffery 464ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 465ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 466b033271fSCédric Le Goater .parent = TYPE_DEVICE, 467ff90606fSCédric Le Goater .instance_init = aspeed_soc_init, 468b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 469b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 470b033271fSCédric Le Goater .abstract = true, 47143e3346eSAndrew Jeffery }; 47243e3346eSAndrew Jeffery 473ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 47443e3346eSAndrew Jeffery { 475b033271fSCédric Le Goater int i; 476b033271fSCédric Le Goater 477ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 478b033271fSCédric Le Goater for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) { 479b033271fSCédric Le Goater TypeInfo ti = { 480b033271fSCédric Le Goater .name = aspeed_socs[i].name, 481b033271fSCédric Le Goater .parent = TYPE_ASPEED_SOC, 482b033271fSCédric Le Goater .class_init = aspeed_soc_class_init, 483b033271fSCédric Le Goater .class_data = (void *) &aspeed_socs[i], 484b033271fSCédric Le Goater }; 485b033271fSCédric Le Goater type_register(&ti); 486b033271fSCédric Le Goater } 48743e3346eSAndrew Jeffery } 48843e3346eSAndrew Jeffery 489ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 490