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" 15c7c3c9f8SPhilippe Mathieu-Daudé #include "hw/misc/unimp.h" 1600442402SCédric Le Goater #include "hw/arm/aspeed_soc.h" 1743e3346eSAndrew Jeffery #include "hw/char/serial.h" 180b8fa32fSMarkus Armbruster #include "qemu/module.h" 19ece09beeSCédric Le Goater #include "qemu/error-report.h" 2016020011SCédric Le Goater #include "hw/i2c/aspeed_i2c.h" 21ea337c65SCédric Le Goater #include "net/net.h" 2246517dd4SMarkus Armbruster #include "sysemu/sysemu.h" 2343e3346eSAndrew Jeffery 24ff90606fSCédric Le Goater #define ASPEED_SOC_IOMEM_SIZE 0x00200000 25d783d1feSCédric Le Goater 26d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2400_memmap[] = { 27347df6f8SEduardo Habkost [ASPEED_DEV_IOMEM] = 0x1E600000, 28347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 0x1E620000, 29347df6f8SEduardo Habkost [ASPEED_DEV_SPI1] = 0x1E630000, 30347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 0x1E6A1000, 31347df6f8SEduardo Habkost [ASPEED_DEV_VIC] = 0x1E6C0000, 32347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0x1E6E0000, 33347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 0x1E6E2000, 34a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 0x1E6E3000, 35347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 36347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 37347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 38347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 39347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 40347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 41347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 42347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 43347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 44347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 45347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 46347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 47347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 48347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 49347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 50347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 51347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 52347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 53347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x40000000, 54d783d1feSCédric Le Goater }; 55d783d1feSCédric Le Goater 56d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 57347df6f8SEduardo Habkost [ASPEED_DEV_IOMEM] = 0x1E600000, 58347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 0x1E620000, 59347df6f8SEduardo Habkost [ASPEED_DEV_SPI1] = 0x1E630000, 60347df6f8SEduardo Habkost [ASPEED_DEV_SPI2] = 0x1E631000, 61347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 0x1E6A1000, 62347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 0x1E6A3000, 63347df6f8SEduardo Habkost [ASPEED_DEV_VIC] = 0x1E6C0000, 64347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0x1E6E0000, 65347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 0x1E6E2000, 66a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 0x1E6E3000, 67347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 68347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 69347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 70347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 71347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 72347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 73347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 74347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 75347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 76347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 77347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 78347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 79347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 80347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 81347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 82347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 83347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 84347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 85347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x80000000, 86d783d1feSCédric Le Goater }; 8743e3346eSAndrew Jeffery 88b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 89347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 9, 90347df6f8SEduardo Habkost [ASPEED_DEV_UART2] = 32, 91347df6f8SEduardo Habkost [ASPEED_DEV_UART3] = 33, 92347df6f8SEduardo Habkost [ASPEED_DEV_UART4] = 34, 93347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 10, 94347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 8, 95347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 19, 96347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 5, 97347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 13, 98347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0, 99347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 21, 100347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 31, 101347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 20, 102347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 22, 103347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 16, 104347df6f8SEduardo Habkost [ASPEED_DEV_TIMER2] = 17, 105347df6f8SEduardo Habkost [ASPEED_DEV_TIMER3] = 18, 106347df6f8SEduardo Habkost [ASPEED_DEV_TIMER4] = 35, 107347df6f8SEduardo Habkost [ASPEED_DEV_TIMER5] = 36, 108347df6f8SEduardo Habkost [ASPEED_DEV_TIMER6] = 37, 109347df6f8SEduardo Habkost [ASPEED_DEV_TIMER7] = 38, 110347df6f8SEduardo Habkost [ASPEED_DEV_TIMER8] = 39, 111347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 27, 112347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 28, 113347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 8, 114347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 12, 115347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 2, 116347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 3, 117347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 6, 118347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 26, 119a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 4, 120b456b113SCédric Le Goater }; 12143e3346eSAndrew Jeffery 122b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 123b456b113SCédric Le Goater 124699db715SCédric Le Goater static qemu_irq aspeed_soc_ast2400_get_irq(AspeedSoCState *s, int dev) 125b456b113SCédric Le Goater { 126b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 127b456b113SCédric Le Goater 128699db715SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[dev]); 129b456b113SCédric Le Goater } 130b456b113SCédric Le Goater 131ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 13243e3346eSAndrew Jeffery { 133ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 134b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 135dbcabeebSCédric Le Goater int i; 136811a5b1dSCédric Le Goater char socname[8]; 137811a5b1dSCédric Le Goater char typename[64]; 138811a5b1dSCédric Le Goater 13954ecafb7SCédric Le Goater if (sscanf(sc->name, "%7s", socname) != 1) { 140811a5b1dSCédric Le Goater g_assert_not_reached(); 141811a5b1dSCédric Le Goater } 14243e3346eSAndrew Jeffery 14354ecafb7SCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 1449fc7fc4dSMarkus Armbruster object_initialize_child(obj, "cpu[*]", &s->cpu[i], sc->cpu_type); 145ece09beeSCédric Le Goater } 14643e3346eSAndrew Jeffery 1479a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 148db873cc5SMarkus Armbruster object_initialize_child(obj, "scu", &s->scu, typename); 149334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 15054ecafb7SCédric Le Goater sc->silicon_rev); 151334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 152d2623129SMarkus Armbruster "hw-strap1"); 153334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 154d2623129SMarkus Armbruster "hw-strap2"); 155b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 156d2623129SMarkus Armbruster "hw-prot-key"); 1577c1c69bcSCédric Le Goater 158db873cc5SMarkus Armbruster object_initialize_child(obj, "vic", &s->vic, TYPE_ASPEED_VIC); 159e2a11ca8SCédric Le Goater 160db873cc5SMarkus Armbruster object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC); 16175fb4577SJoel Stanley 16272d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 163db873cc5SMarkus Armbruster object_initialize_child(obj, "timerctrl", &s->timerctrl, typename); 164e2a11ca8SCédric Le Goater 165199fd623SAndrew Jeffery snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname); 166199fd623SAndrew Jeffery object_initialize_child(obj, "adc", &s->adc, typename); 167199fd623SAndrew Jeffery 168f7da1aa8SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); 169db873cc5SMarkus Armbruster object_initialize_child(obj, "i2c", &s->i2c, typename); 170e2a11ca8SCédric Le Goater 171811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 172db873cc5SMarkus Armbruster object_initialize_child(obj, "fmc", &s->fmc, typename); 1737c1c69bcSCédric Le Goater 17454ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 175811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 176db873cc5SMarkus Armbruster object_initialize_child(obj, "spi[*]", &s->spi[i], typename); 177dbcabeebSCédric Le Goater } 178c2da8a8bSCédric Le Goater 179bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 180db873cc5SMarkus Armbruster object_initialize_child(obj, "ehci[*]", &s->ehci[i], 181db873cc5SMarkus Armbruster TYPE_PLATFORM_EHCI); 182bfdd34f1SGuenter Roeck } 183bfdd34f1SGuenter Roeck 1848e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 185db873cc5SMarkus Armbruster object_initialize_child(obj, "sdmc", &s->sdmc, typename); 186c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 187d2623129SMarkus Armbruster "ram-size"); 188ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 189d2623129SMarkus Armbruster "max-ram-size"); 190013befe1SCédric Le Goater 19154ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 1926112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 193db873cc5SMarkus Armbruster object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename); 194f986ee1dSJoel Stanley } 195ea337c65SCédric Le Goater 196d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 197db873cc5SMarkus Armbruster object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i], 198db873cc5SMarkus Armbruster TYPE_FTGMAC100); 19967340990SCédric Le Goater } 200118c82e7SEddie James 2018efbee28SCédric Le Goater snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname); 2028efbee28SCédric Le Goater object_initialize_child(obj, "xdma", &s->xdma, typename); 203fdcc7c06SRashmica Gupta 204811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 205db873cc5SMarkus Armbruster object_initialize_child(obj, "gpio", &s->gpio, typename); 2062bea128cSEddie James 207db873cc5SMarkus Armbruster object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI); 2082bea128cSEddie James 2095325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); 2100e2c24c6SAndrew Jeffery 2112bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2122bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2137089e0ccSMarkus Armbruster object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i], 2147089e0ccSMarkus Armbruster TYPE_SYSBUS_SDHCI); 2152bea128cSEddie James } 2162ecf1726SCédric Le Goater 2172ecf1726SCédric Le Goater object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); 218a3888d75SJoel Stanley 219a3888d75SJoel Stanley snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname); 220a3888d75SJoel Stanley object_initialize_child(obj, "hace", &s->hace, typename); 22143e3346eSAndrew Jeffery } 22243e3346eSAndrew Jeffery 223ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 22443e3346eSAndrew Jeffery { 22543e3346eSAndrew Jeffery int i; 226ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 227dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 228123327d1SMarkus Armbruster Error *err = NULL; 22943e3346eSAndrew Jeffery 23043e3346eSAndrew Jeffery /* IO space */ 231347df6f8SEduardo Habkost create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM], 232d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 23343e3346eSAndrew Jeffery 234514bcf6fSJoel Stanley /* Video engine stub */ 235347df6f8SEduardo Habkost create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO], 236514bcf6fSJoel Stanley 0x1000); 237514bcf6fSJoel Stanley 2382d105bd6SCédric Le Goater /* CPU */ 239b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 240668f62ecSMarkus Armbruster if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) { 2412d105bd6SCédric Le Goater return; 2422d105bd6SCédric Le Goater } 243ece09beeSCédric Le Goater } 2442d105bd6SCédric Le Goater 24574af4eecSCédric Le Goater /* SRAM */ 246a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 24754ecafb7SCédric Le Goater sc->sram_size, &err); 24874af4eecSCédric Le Goater if (err) { 24974af4eecSCédric Le Goater error_propagate(errp, err); 25074af4eecSCédric Le Goater return; 25174af4eecSCédric Le Goater } 252d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 253347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SRAM], &s->sram); 25474af4eecSCédric Le Goater 255e2a11ca8SCédric Le Goater /* SCU */ 256668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { 257e2a11ca8SCédric Le Goater return; 258e2a11ca8SCédric Le Goater } 259347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); 260e2a11ca8SCédric Le Goater 26143e3346eSAndrew Jeffery /* VIC */ 262668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) { 26343e3346eSAndrew Jeffery return; 26443e3346eSAndrew Jeffery } 265347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]); 26643e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2672d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 26843e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2692d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 27043e3346eSAndrew Jeffery 27175fb4577SJoel Stanley /* RTC */ 272668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) { 27375fb4577SJoel Stanley return; 27475fb4577SJoel Stanley } 275347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]); 27675fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 277347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_RTC)); 27875fb4577SJoel Stanley 27943e3346eSAndrew Jeffery /* Timer */ 2805325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), 2815325cc34SMarkus Armbruster &error_abort); 282668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) { 28343e3346eSAndrew Jeffery return; 28443e3346eSAndrew Jeffery } 285d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 286347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_TIMER1]); 287b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 288347df6f8SEduardo Habkost qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i); 28943e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 29043e3346eSAndrew Jeffery } 29143e3346eSAndrew Jeffery 292199fd623SAndrew Jeffery /* ADC */ 293199fd623SAndrew Jeffery if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) { 294199fd623SAndrew Jeffery return; 295199fd623SAndrew Jeffery } 296199fd623SAndrew Jeffery sysbus_mmio_map(SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]); 297199fd623SAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0, 298199fd623SAndrew Jeffery aspeed_soc_get_irq(s, ASPEED_DEV_ADC)); 299199fd623SAndrew Jeffery 3005d63d0c7SPeter Delevoryas /* UART - attach an 8250 to the IO space as our UART */ 3015d63d0c7SPeter Delevoryas serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2, 3025d63d0c7SPeter Delevoryas aspeed_soc_get_irq(s, s->uart_default), 38400, 303a6b2f1fcSPhilippe Mathieu-Daudé serial_hd(0), DEVICE_LITTLE_ENDIAN); 30416020011SCédric Le Goater 30516020011SCédric Le Goater /* I2C */ 3065325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr), 307c24d9716SMarkus Armbruster &error_abort); 308668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { 30916020011SCédric Le Goater return; 31016020011SCédric Le Goater } 311347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]); 31216020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 313347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_I2C)); 3147c1c69bcSCédric Le Goater 31526d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3165325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr), 317c24d9716SMarkus Armbruster &error_abort); 318668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) { 3197c1c69bcSCédric Le Goater return; 3207c1c69bcSCédric Le Goater } 321347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]); 322dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 32330b6852cSCédric Le Goater ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base); 3240e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 325347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_FMC)); 3267c1c69bcSCédric Le Goater 3277c1c69bcSCédric Le Goater /* SPI */ 32854ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 329668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) { 3307c1c69bcSCédric Le Goater return; 3317c1c69bcSCédric Le Goater } 332d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 333347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SPI1 + i]); 334dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 33530b6852cSCédric Le Goater ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base); 336dbcabeebSCédric Le Goater } 337c2da8a8bSCédric Le Goater 338bfdd34f1SGuenter Roeck /* EHCI */ 339bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 340668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) { 341bfdd34f1SGuenter Roeck return; 342bfdd34f1SGuenter Roeck } 343bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 344347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_EHCI1 + i]); 345bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 346347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i)); 347bfdd34f1SGuenter Roeck } 348bfdd34f1SGuenter Roeck 349c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 350668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) { 351c2da8a8bSCédric Le Goater return; 352c2da8a8bSCédric Le Goater } 353347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]); 354013befe1SCédric Le Goater 355013befe1SCédric Le Goater /* Watch dog */ 35654ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3576112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3586112bd6dSCédric Le Goater 3595325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu), 3605325cc34SMarkus Armbruster &error_abort); 361668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { 362013befe1SCédric Le Goater return; 363013befe1SCédric Le Goater } 364f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 365347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_WDT] + i * awc->offset); 366f986ee1dSJoel Stanley } 367ea337c65SCédric Le Goater 368ea337c65SCédric Le Goater /* Net */ 369d3bad7e7SCédric Le Goater for (i = 0; i < sc->macs_num; i++) { 3705325cc34SMarkus Armbruster object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true, 3712255f6b7SMarkus Armbruster &error_abort); 372668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) { 373ea337c65SCédric Le Goater return; 374ea337c65SCédric Le Goater } 37567340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 376347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_ETH1 + i]); 37767340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 378347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i)); 37967340990SCédric Le Goater } 380118c82e7SEddie James 381118c82e7SEddie James /* XDMA */ 382668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) { 383118c82e7SEddie James return; 384118c82e7SEddie James } 385118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 386347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_XDMA]); 387118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 388347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_XDMA)); 389fdcc7c06SRashmica Gupta 390fdcc7c06SRashmica Gupta /* GPIO */ 391668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { 392fdcc7c06SRashmica Gupta return; 393fdcc7c06SRashmica Gupta } 394347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]); 395fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 396347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_GPIO)); 3972bea128cSEddie James 3982bea128cSEddie James /* SDHCI */ 399668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) { 4002bea128cSEddie James return; 4012bea128cSEddie James } 4022bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 403347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SDHCI]); 4042bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 405347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI)); 4062ecf1726SCédric Le Goater 4072ecf1726SCédric Le Goater /* LPC */ 4082ecf1726SCédric Le Goater if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) { 4092ecf1726SCédric Le Goater return; 4102ecf1726SCédric Le Goater } 4112ecf1726SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]); 412c59f781eSAndrew Jeffery 413c59f781eSAndrew Jeffery /* Connect the LPC IRQ to the VIC */ 4142ecf1726SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0, 4152ecf1726SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_DEV_LPC)); 416c59f781eSAndrew Jeffery 417c59f781eSAndrew Jeffery /* 418c59f781eSAndrew Jeffery * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the 419c59f781eSAndrew Jeffery * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by 420c59f781eSAndrew Jeffery * contrast, on the AST2600, the subdevice IRQs are connected straight to 421c59f781eSAndrew Jeffery * the GIC). 422c59f781eSAndrew Jeffery * 423c59f781eSAndrew Jeffery * LPC subdevice IRQ sources are offset from 1 because the shared IRQ output 424c59f781eSAndrew Jeffery * to the VIC is at offset 0. 425c59f781eSAndrew Jeffery */ 426c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1, 427c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_1)); 428c59f781eSAndrew Jeffery 429c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2, 430c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_2)); 431c59f781eSAndrew Jeffery 432c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3, 433c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_3)); 434c59f781eSAndrew Jeffery 435c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4, 436c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4)); 437a3888d75SJoel Stanley 438a3888d75SJoel Stanley /* HACE */ 439a3888d75SJoel Stanley object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr), 440a3888d75SJoel Stanley &error_abort); 441a3888d75SJoel Stanley if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) { 442a3888d75SJoel Stanley return; 443a3888d75SJoel Stanley } 444a3888d75SJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]); 445a3888d75SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0, 446a3888d75SJoel Stanley aspeed_soc_get_irq(s, ASPEED_DEV_HACE)); 44743e3346eSAndrew Jeffery } 448ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 44995b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 45095b56e17SCédric Le Goater MemoryRegion *), 4515d63d0c7SPeter Delevoryas DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default, 4525d63d0c7SPeter Delevoryas ASPEED_DEV_UART5), 453ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 454ece09beeSCédric Le Goater }; 45543e3346eSAndrew Jeffery 456ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 45743e3346eSAndrew Jeffery { 45843e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 45943e3346eSAndrew Jeffery 460ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 461469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 462469f3da4SThomas Huth dc->user_creatable = false; 4634f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 46443e3346eSAndrew Jeffery } 46543e3346eSAndrew Jeffery 466ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 467ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 468b033271fSCédric Le Goater .parent = TYPE_DEVICE, 469b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 470b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 47154ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 472b033271fSCédric Le Goater .abstract = true, 47343e3346eSAndrew Jeffery }; 47443e3346eSAndrew Jeffery 47554ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 47654ecafb7SCédric Le Goater { 47754ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 47854ecafb7SCédric Le Goater 47954ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 48054ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 48154ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 48254ecafb7SCédric Le Goater sc->sram_size = 0x8000; 48354ecafb7SCédric Le Goater sc->spis_num = 1; 484bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 48554ecafb7SCédric Le Goater sc->wdts_num = 2; 486d300db02SJoel Stanley sc->macs_num = 2; 48754ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 48854ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 48954ecafb7SCédric Le Goater sc->num_cpus = 1; 490699db715SCédric Le Goater sc->get_irq = aspeed_soc_ast2400_get_irq; 49154ecafb7SCédric Le Goater } 49254ecafb7SCédric Le Goater 49354ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 49454ecafb7SCédric Le Goater .name = "ast2400-a1", 49554ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 49654ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 49754ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 49854ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 49954ecafb7SCédric Le Goater }; 50054ecafb7SCédric Le Goater 50154ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 50254ecafb7SCédric Le Goater { 50354ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 50454ecafb7SCédric Le Goater 50554ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 50654ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 50754ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 50854ecafb7SCédric Le Goater sc->sram_size = 0x9000; 50954ecafb7SCédric Le Goater sc->spis_num = 2; 510bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 51154ecafb7SCédric Le Goater sc->wdts_num = 3; 512d300db02SJoel Stanley sc->macs_num = 2; 51354ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 51454ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 51554ecafb7SCédric Le Goater sc->num_cpus = 1; 516699db715SCédric Le Goater sc->get_irq = aspeed_soc_ast2400_get_irq; 51754ecafb7SCédric Le Goater } 51854ecafb7SCédric Le Goater 51954ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 52054ecafb7SCédric Le Goater .name = "ast2500-a1", 52154ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 52254ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 52354ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 52454ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 52554ecafb7SCédric Le Goater }; 526ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 52743e3346eSAndrew Jeffery { 528ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 52954ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 53054ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 531b033271fSCédric Le Goater }; 53243e3346eSAndrew Jeffery 533699db715SCédric Le Goater type_init(aspeed_soc_register_types); 534699db715SCédric Le Goater 535699db715SCédric Le Goater qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev) 536699db715SCédric Le Goater { 537699db715SCédric Le Goater return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev); 538699db715SCédric Le Goater } 539