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 124b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 125b456b113SCédric Le Goater { 126b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 127b456b113SCédric Le Goater 12854ecafb7SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]); 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 165f7da1aa8SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); 166db873cc5SMarkus Armbruster object_initialize_child(obj, "i2c", &s->i2c, typename); 167e2a11ca8SCédric Le Goater 168811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 169db873cc5SMarkus Armbruster object_initialize_child(obj, "fmc", &s->fmc, typename); 170d2623129SMarkus Armbruster object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs"); 1717c1c69bcSCédric Le Goater 17254ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 173811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 174db873cc5SMarkus Armbruster object_initialize_child(obj, "spi[*]", &s->spi[i], typename); 175dbcabeebSCédric Le Goater } 176c2da8a8bSCédric Le Goater 177bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 178db873cc5SMarkus Armbruster object_initialize_child(obj, "ehci[*]", &s->ehci[i], 179db873cc5SMarkus Armbruster TYPE_PLATFORM_EHCI); 180bfdd34f1SGuenter Roeck } 181bfdd34f1SGuenter Roeck 1828e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 183db873cc5SMarkus Armbruster object_initialize_child(obj, "sdmc", &s->sdmc, typename); 184c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 185d2623129SMarkus Armbruster "ram-size"); 186ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 187d2623129SMarkus Armbruster "max-ram-size"); 188013befe1SCédric Le Goater 18954ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 1906112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 191db873cc5SMarkus Armbruster object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename); 192f986ee1dSJoel Stanley } 193ea337c65SCédric Le Goater 194d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 195db873cc5SMarkus Armbruster object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i], 196db873cc5SMarkus Armbruster TYPE_FTGMAC100); 19767340990SCédric Le Goater } 198118c82e7SEddie James 1998efbee28SCédric Le Goater snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname); 2008efbee28SCédric Le Goater object_initialize_child(obj, "xdma", &s->xdma, typename); 201fdcc7c06SRashmica Gupta 202811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 203db873cc5SMarkus Armbruster object_initialize_child(obj, "gpio", &s->gpio, typename); 2042bea128cSEddie James 205db873cc5SMarkus Armbruster object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI); 2062bea128cSEddie James 2075325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); 2080e2c24c6SAndrew Jeffery 2092bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2102bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2117089e0ccSMarkus Armbruster object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i], 2127089e0ccSMarkus Armbruster TYPE_SYSBUS_SDHCI); 2132bea128cSEddie James } 2142ecf1726SCédric Le Goater 2152ecf1726SCédric Le Goater object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); 216a3888d75SJoel Stanley 217a3888d75SJoel Stanley snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname); 218a3888d75SJoel Stanley object_initialize_child(obj, "hace", &s->hace, typename); 21943e3346eSAndrew Jeffery } 22043e3346eSAndrew Jeffery 221ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 22243e3346eSAndrew Jeffery { 22343e3346eSAndrew Jeffery int i; 224ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 225dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 226123327d1SMarkus Armbruster Error *err = NULL; 22743e3346eSAndrew Jeffery 22843e3346eSAndrew Jeffery /* IO space */ 229347df6f8SEduardo Habkost create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM], 230d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 23143e3346eSAndrew Jeffery 232514bcf6fSJoel Stanley /* Video engine stub */ 233347df6f8SEduardo Habkost create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO], 234514bcf6fSJoel Stanley 0x1000); 235514bcf6fSJoel Stanley 2362d105bd6SCédric Le Goater /* CPU */ 237b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 238668f62ecSMarkus Armbruster if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) { 2392d105bd6SCédric Le Goater return; 2402d105bd6SCédric Le Goater } 241ece09beeSCédric Le Goater } 2422d105bd6SCédric Le Goater 24374af4eecSCédric Le Goater /* SRAM */ 244a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 24554ecafb7SCédric Le Goater sc->sram_size, &err); 24674af4eecSCédric Le Goater if (err) { 24774af4eecSCédric Le Goater error_propagate(errp, err); 24874af4eecSCédric Le Goater return; 24974af4eecSCédric Le Goater } 250d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 251347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SRAM], &s->sram); 25274af4eecSCédric Le Goater 253e2a11ca8SCédric Le Goater /* SCU */ 254668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { 255e2a11ca8SCédric Le Goater return; 256e2a11ca8SCédric Le Goater } 257347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); 258e2a11ca8SCédric Le Goater 25943e3346eSAndrew Jeffery /* VIC */ 260668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) { 26143e3346eSAndrew Jeffery return; 26243e3346eSAndrew Jeffery } 263347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]); 26443e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2652d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 26643e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2672d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 26843e3346eSAndrew Jeffery 26975fb4577SJoel Stanley /* RTC */ 270668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) { 27175fb4577SJoel Stanley return; 27275fb4577SJoel Stanley } 273347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]); 27475fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 275347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_RTC)); 27675fb4577SJoel Stanley 27743e3346eSAndrew Jeffery /* Timer */ 2785325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), 2795325cc34SMarkus Armbruster &error_abort); 280668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) { 28143e3346eSAndrew Jeffery return; 28243e3346eSAndrew Jeffery } 283d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 284347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_TIMER1]); 285b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 286347df6f8SEduardo Habkost qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i); 28743e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 28843e3346eSAndrew Jeffery } 28943e3346eSAndrew Jeffery 2905d63d0c7SPeter Delevoryas /* UART - attach an 8250 to the IO space as our UART */ 2915d63d0c7SPeter Delevoryas serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2, 2925d63d0c7SPeter Delevoryas aspeed_soc_get_irq(s, s->uart_default), 38400, 293a6b2f1fcSPhilippe Mathieu-Daudé serial_hd(0), DEVICE_LITTLE_ENDIAN); 29416020011SCédric Le Goater 29516020011SCédric Le Goater /* I2C */ 2965325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr), 297c24d9716SMarkus Armbruster &error_abort); 298668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { 29916020011SCédric Le Goater return; 30016020011SCédric Le Goater } 301347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]); 30216020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 303347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_I2C)); 3047c1c69bcSCédric Le Goater 30526d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3065325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr), 307c24d9716SMarkus Armbruster &error_abort); 308668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) { 3097c1c69bcSCédric Le Goater return; 3107c1c69bcSCédric Le Goater } 311347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]); 312dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 313dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3140e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 315347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_FMC)); 3167c1c69bcSCédric Le Goater 3177c1c69bcSCédric Le Goater /* SPI */ 31854ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 3195325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort); 320668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) { 3217c1c69bcSCédric Le Goater return; 3227c1c69bcSCédric Le Goater } 323d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 324347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SPI1 + i]); 325dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 326dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 327dbcabeebSCédric Le Goater } 328c2da8a8bSCédric Le Goater 329bfdd34f1SGuenter Roeck /* EHCI */ 330bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 331668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) { 332bfdd34f1SGuenter Roeck return; 333bfdd34f1SGuenter Roeck } 334bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 335347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_EHCI1 + i]); 336bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 337347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i)); 338bfdd34f1SGuenter Roeck } 339bfdd34f1SGuenter Roeck 340c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 341668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) { 342c2da8a8bSCédric Le Goater return; 343c2da8a8bSCédric Le Goater } 344347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]); 345013befe1SCédric Le Goater 346013befe1SCédric Le Goater /* Watch dog */ 34754ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3486112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3496112bd6dSCédric Le Goater 3505325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu), 3515325cc34SMarkus Armbruster &error_abort); 352668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { 353013befe1SCédric Le Goater return; 354013befe1SCédric Le Goater } 355f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 356347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_WDT] + i * awc->offset); 357f986ee1dSJoel Stanley } 358ea337c65SCédric Le Goater 359ea337c65SCédric Le Goater /* Net */ 360d3bad7e7SCédric Le Goater for (i = 0; i < sc->macs_num; i++) { 3615325cc34SMarkus Armbruster object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true, 3622255f6b7SMarkus Armbruster &error_abort); 363668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) { 364ea337c65SCédric Le Goater return; 365ea337c65SCédric Le Goater } 36667340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 367347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_ETH1 + i]); 36867340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 369347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i)); 37067340990SCédric Le Goater } 371118c82e7SEddie James 372118c82e7SEddie James /* XDMA */ 373668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) { 374118c82e7SEddie James return; 375118c82e7SEddie James } 376118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 377347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_XDMA]); 378118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 379347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_XDMA)); 380fdcc7c06SRashmica Gupta 381fdcc7c06SRashmica Gupta /* GPIO */ 382668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { 383fdcc7c06SRashmica Gupta return; 384fdcc7c06SRashmica Gupta } 385347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]); 386fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 387347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_GPIO)); 3882bea128cSEddie James 3892bea128cSEddie James /* SDHCI */ 390668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) { 3912bea128cSEddie James return; 3922bea128cSEddie James } 3932bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 394347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SDHCI]); 3952bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 396347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI)); 3972ecf1726SCédric Le Goater 3982ecf1726SCédric Le Goater /* LPC */ 3992ecf1726SCédric Le Goater if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) { 4002ecf1726SCédric Le Goater return; 4012ecf1726SCédric Le Goater } 4022ecf1726SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]); 403c59f781eSAndrew Jeffery 404c59f781eSAndrew Jeffery /* Connect the LPC IRQ to the VIC */ 4052ecf1726SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0, 4062ecf1726SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_DEV_LPC)); 407c59f781eSAndrew Jeffery 408c59f781eSAndrew Jeffery /* 409c59f781eSAndrew Jeffery * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the 410c59f781eSAndrew Jeffery * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by 411c59f781eSAndrew Jeffery * contrast, on the AST2600, the subdevice IRQs are connected straight to 412c59f781eSAndrew Jeffery * the GIC). 413c59f781eSAndrew Jeffery * 414c59f781eSAndrew Jeffery * LPC subdevice IRQ sources are offset from 1 because the shared IRQ output 415c59f781eSAndrew Jeffery * to the VIC is at offset 0. 416c59f781eSAndrew Jeffery */ 417c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1, 418c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_1)); 419c59f781eSAndrew Jeffery 420c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2, 421c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_2)); 422c59f781eSAndrew Jeffery 423c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3, 424c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_3)); 425c59f781eSAndrew Jeffery 426c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4, 427c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4)); 428a3888d75SJoel Stanley 429a3888d75SJoel Stanley /* HACE */ 430a3888d75SJoel Stanley object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr), 431a3888d75SJoel Stanley &error_abort); 432a3888d75SJoel Stanley if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) { 433a3888d75SJoel Stanley return; 434a3888d75SJoel Stanley } 435a3888d75SJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]); 436a3888d75SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0, 437a3888d75SJoel Stanley aspeed_soc_get_irq(s, ASPEED_DEV_HACE)); 43843e3346eSAndrew Jeffery } 439ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 44095b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 44195b56e17SCédric Le Goater MemoryRegion *), 4425d63d0c7SPeter Delevoryas DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default, 4435d63d0c7SPeter Delevoryas ASPEED_DEV_UART5), 444ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 445ece09beeSCédric Le Goater }; 44643e3346eSAndrew Jeffery 447ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 44843e3346eSAndrew Jeffery { 44943e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 45043e3346eSAndrew Jeffery 451ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 452469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 453469f3da4SThomas Huth dc->user_creatable = false; 4544f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 45543e3346eSAndrew Jeffery } 45643e3346eSAndrew Jeffery 457ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 458ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 459b033271fSCédric Le Goater .parent = TYPE_DEVICE, 460b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 461b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 46254ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 463b033271fSCédric Le Goater .abstract = true, 46443e3346eSAndrew Jeffery }; 46543e3346eSAndrew Jeffery 46654ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 46754ecafb7SCédric Le Goater { 46854ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 46954ecafb7SCédric Le Goater 47054ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 47154ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 47254ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 47354ecafb7SCédric Le Goater sc->sram_size = 0x8000; 47454ecafb7SCédric Le Goater sc->spis_num = 1; 475bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 47654ecafb7SCédric Le Goater sc->wdts_num = 2; 477d300db02SJoel Stanley sc->macs_num = 2; 47854ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 47954ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 48054ecafb7SCédric Le Goater sc->num_cpus = 1; 48154ecafb7SCédric Le Goater } 48254ecafb7SCédric Le Goater 48354ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 48454ecafb7SCédric Le Goater .name = "ast2400-a1", 48554ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 48654ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 48754ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 48854ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 48954ecafb7SCédric Le Goater }; 49054ecafb7SCédric Le Goater 49154ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 49254ecafb7SCédric Le Goater { 49354ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 49454ecafb7SCédric Le Goater 49554ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 49654ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 49754ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 49854ecafb7SCédric Le Goater sc->sram_size = 0x9000; 49954ecafb7SCédric Le Goater sc->spis_num = 2; 500bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 50154ecafb7SCédric Le Goater sc->wdts_num = 3; 502d300db02SJoel Stanley sc->macs_num = 2; 50354ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 50454ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 50554ecafb7SCédric Le Goater sc->num_cpus = 1; 50654ecafb7SCédric Le Goater } 50754ecafb7SCédric Le Goater 50854ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 50954ecafb7SCédric Le Goater .name = "ast2500-a1", 51054ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 51154ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 51254ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 51354ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 51454ecafb7SCédric Le Goater }; 515ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 51643e3346eSAndrew Jeffery { 517ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 51854ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 51954ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 520b033271fSCédric Le Goater }; 52143e3346eSAndrew Jeffery 522ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 523