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[] = { 30347df6f8SEduardo Habkost [ASPEED_DEV_IOMEM] = 0x1E600000, 31347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 0x1E620000, 32347df6f8SEduardo Habkost [ASPEED_DEV_SPI1] = 0x1E630000, 33347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 0x1E6A1000, 34347df6f8SEduardo Habkost [ASPEED_DEV_VIC] = 0x1E6C0000, 35347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0x1E6E0000, 36347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 0x1E6E2000, 37a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 0x1E6E3000, 38347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 39347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 40347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 41347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 42347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 43347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 44347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 45347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 46347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 47347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 48347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 49347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 50347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 51347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 52347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 53347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 54347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 55347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 56347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x40000000, 57d783d1feSCédric Le Goater }; 58d783d1feSCédric Le Goater 59d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 60347df6f8SEduardo Habkost [ASPEED_DEV_IOMEM] = 0x1E600000, 61347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 0x1E620000, 62347df6f8SEduardo Habkost [ASPEED_DEV_SPI1] = 0x1E630000, 63347df6f8SEduardo Habkost [ASPEED_DEV_SPI2] = 0x1E631000, 64347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 0x1E6A1000, 65347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 0x1E6A3000, 66347df6f8SEduardo Habkost [ASPEED_DEV_VIC] = 0x1E6C0000, 67347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0x1E6E0000, 68347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 0x1E6E2000, 69a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 0x1E6E3000, 70347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 71347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 72347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 73347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 74347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 75347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 76347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 77347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 78347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 79347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 80347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 81347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 82347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 83347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 84347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 85347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 86347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 87347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 88347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x80000000, 89d783d1feSCédric Le Goater }; 9043e3346eSAndrew Jeffery 91b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 92347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 9, 93347df6f8SEduardo Habkost [ASPEED_DEV_UART2] = 32, 94347df6f8SEduardo Habkost [ASPEED_DEV_UART3] = 33, 95347df6f8SEduardo Habkost [ASPEED_DEV_UART4] = 34, 96347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 10, 97347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 8, 98347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 19, 99347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 5, 100347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 13, 101347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0, 102347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 21, 103347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 31, 104347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 20, 105347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 22, 106347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 16, 107347df6f8SEduardo Habkost [ASPEED_DEV_TIMER2] = 17, 108347df6f8SEduardo Habkost [ASPEED_DEV_TIMER3] = 18, 109347df6f8SEduardo Habkost [ASPEED_DEV_TIMER4] = 35, 110347df6f8SEduardo Habkost [ASPEED_DEV_TIMER5] = 36, 111347df6f8SEduardo Habkost [ASPEED_DEV_TIMER6] = 37, 112347df6f8SEduardo Habkost [ASPEED_DEV_TIMER7] = 38, 113347df6f8SEduardo Habkost [ASPEED_DEV_TIMER8] = 39, 114347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 27, 115347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 28, 116347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 8, 117347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 12, 118347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 2, 119347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 3, 120347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 6, 121347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 26, 122a3888d75SJoel Stanley [ASPEED_DEV_HACE] = 4, 123b456b113SCédric Le Goater }; 12443e3346eSAndrew Jeffery 125b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 126b456b113SCédric Le Goater 127b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 128b456b113SCédric Le Goater { 129b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 130b456b113SCédric Le Goater 13154ecafb7SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]); 132b456b113SCédric Le Goater } 133b456b113SCédric Le Goater 134ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 13543e3346eSAndrew Jeffery { 136ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 137b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 138dbcabeebSCédric Le Goater int i; 139811a5b1dSCédric Le Goater char socname[8]; 140811a5b1dSCédric Le Goater char typename[64]; 141811a5b1dSCédric Le Goater 14254ecafb7SCédric Le Goater if (sscanf(sc->name, "%7s", socname) != 1) { 143811a5b1dSCédric Le Goater g_assert_not_reached(); 144811a5b1dSCédric Le Goater } 14543e3346eSAndrew Jeffery 14654ecafb7SCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 1479fc7fc4dSMarkus Armbruster object_initialize_child(obj, "cpu[*]", &s->cpu[i], sc->cpu_type); 148ece09beeSCédric Le Goater } 14943e3346eSAndrew Jeffery 1509a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 151db873cc5SMarkus Armbruster object_initialize_child(obj, "scu", &s->scu, typename); 152334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 15354ecafb7SCédric Le Goater sc->silicon_rev); 154334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 155d2623129SMarkus Armbruster "hw-strap1"); 156334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 157d2623129SMarkus Armbruster "hw-strap2"); 158b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 159d2623129SMarkus Armbruster "hw-prot-key"); 1607c1c69bcSCédric Le Goater 161db873cc5SMarkus Armbruster object_initialize_child(obj, "vic", &s->vic, TYPE_ASPEED_VIC); 162e2a11ca8SCédric Le Goater 163db873cc5SMarkus Armbruster object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC); 16475fb4577SJoel Stanley 16572d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 166db873cc5SMarkus Armbruster object_initialize_child(obj, "timerctrl", &s->timerctrl, typename); 167e2a11ca8SCédric Le Goater 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); 173d2623129SMarkus Armbruster object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs"); 1747c1c69bcSCédric Le Goater 17554ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 176811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 177db873cc5SMarkus Armbruster object_initialize_child(obj, "spi[*]", &s->spi[i], typename); 178dbcabeebSCédric Le Goater } 179c2da8a8bSCédric Le Goater 180bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 181db873cc5SMarkus Armbruster object_initialize_child(obj, "ehci[*]", &s->ehci[i], 182db873cc5SMarkus Armbruster TYPE_PLATFORM_EHCI); 183bfdd34f1SGuenter Roeck } 184bfdd34f1SGuenter Roeck 1858e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 186db873cc5SMarkus Armbruster object_initialize_child(obj, "sdmc", &s->sdmc, typename); 187c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 188d2623129SMarkus Armbruster "ram-size"); 189ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 190d2623129SMarkus Armbruster "max-ram-size"); 191013befe1SCédric Le Goater 19254ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 1936112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 194db873cc5SMarkus Armbruster object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename); 195f986ee1dSJoel Stanley } 196ea337c65SCédric Le Goater 197d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 198db873cc5SMarkus Armbruster object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i], 199db873cc5SMarkus Armbruster TYPE_FTGMAC100); 20067340990SCédric Le Goater } 201118c82e7SEddie James 2028efbee28SCédric Le Goater snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname); 2038efbee28SCédric Le Goater object_initialize_child(obj, "xdma", &s->xdma, typename); 204fdcc7c06SRashmica Gupta 205811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 206db873cc5SMarkus Armbruster object_initialize_child(obj, "gpio", &s->gpio, typename); 2072bea128cSEddie James 208db873cc5SMarkus Armbruster object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI); 2092bea128cSEddie James 2105325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); 2110e2c24c6SAndrew Jeffery 2122bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2132bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2147089e0ccSMarkus Armbruster object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i], 2157089e0ccSMarkus Armbruster TYPE_SYSBUS_SDHCI); 2162bea128cSEddie James } 2172ecf1726SCédric Le Goater 2182ecf1726SCédric Le Goater object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); 219a3888d75SJoel Stanley 220a3888d75SJoel Stanley snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname); 221a3888d75SJoel Stanley object_initialize_child(obj, "hace", &s->hace, typename); 22243e3346eSAndrew Jeffery } 22343e3346eSAndrew Jeffery 224ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 22543e3346eSAndrew Jeffery { 22643e3346eSAndrew Jeffery int i; 227ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 228dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 229123327d1SMarkus Armbruster Error *err = NULL; 23043e3346eSAndrew Jeffery 23143e3346eSAndrew Jeffery /* IO space */ 232347df6f8SEduardo Habkost create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM], 233d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 23443e3346eSAndrew Jeffery 235514bcf6fSJoel Stanley /* Video engine stub */ 236347df6f8SEduardo Habkost create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO], 237514bcf6fSJoel Stanley 0x1000); 238514bcf6fSJoel Stanley 2392d105bd6SCédric Le Goater /* CPU */ 240b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 241668f62ecSMarkus Armbruster if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) { 2422d105bd6SCédric Le Goater return; 2432d105bd6SCédric Le Goater } 244ece09beeSCédric Le Goater } 2452d105bd6SCédric Le Goater 24674af4eecSCédric Le Goater /* SRAM */ 247a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 24854ecafb7SCédric Le Goater sc->sram_size, &err); 24974af4eecSCédric Le Goater if (err) { 25074af4eecSCédric Le Goater error_propagate(errp, err); 25174af4eecSCédric Le Goater return; 25274af4eecSCédric Le Goater } 253d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 254347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SRAM], &s->sram); 25574af4eecSCédric Le Goater 256e2a11ca8SCédric Le Goater /* SCU */ 257668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { 258e2a11ca8SCédric Le Goater return; 259e2a11ca8SCédric Le Goater } 260347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); 261e2a11ca8SCédric Le Goater 26243e3346eSAndrew Jeffery /* VIC */ 263668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) { 26443e3346eSAndrew Jeffery return; 26543e3346eSAndrew Jeffery } 266347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]); 26743e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2682d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 26943e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2702d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 27143e3346eSAndrew Jeffery 27275fb4577SJoel Stanley /* RTC */ 273668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) { 27475fb4577SJoel Stanley return; 27575fb4577SJoel Stanley } 276347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]); 27775fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 278347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_RTC)); 27975fb4577SJoel Stanley 28043e3346eSAndrew Jeffery /* Timer */ 2815325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), 2825325cc34SMarkus Armbruster &error_abort); 283668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) { 28443e3346eSAndrew Jeffery return; 28543e3346eSAndrew Jeffery } 286d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 287347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_TIMER1]); 288b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 289347df6f8SEduardo Habkost qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i); 29043e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 29143e3346eSAndrew Jeffery } 29243e3346eSAndrew Jeffery 29343e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 294347df6f8SEduardo Habkost serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2, 295a6b2f1fcSPhilippe Mathieu-Daudé aspeed_soc_get_irq(s, ASPEED_DEV_UART5), 38400, 296a6b2f1fcSPhilippe Mathieu-Daudé serial_hd(0), DEVICE_LITTLE_ENDIAN); 29716020011SCédric Le Goater 29816020011SCédric Le Goater /* I2C */ 2995325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr), 300c24d9716SMarkus Armbruster &error_abort); 301668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { 30216020011SCédric Le Goater return; 30316020011SCédric Le Goater } 304347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]); 30516020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 306347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_I2C)); 3077c1c69bcSCédric Le Goater 30826d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3095325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr), 310c24d9716SMarkus Armbruster &error_abort); 311668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) { 3127c1c69bcSCédric Le Goater return; 3137c1c69bcSCédric Le Goater } 314347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]); 315dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 316dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3170e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 318347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_FMC)); 3197c1c69bcSCédric Le Goater 3207c1c69bcSCédric Le Goater /* SPI */ 32154ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 3225325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort); 323668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) { 3247c1c69bcSCédric Le Goater return; 3257c1c69bcSCédric Le Goater } 326d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 327347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SPI1 + i]); 328dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 329dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 330dbcabeebSCédric Le Goater } 331c2da8a8bSCédric Le Goater 332bfdd34f1SGuenter Roeck /* EHCI */ 333bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 334668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) { 335bfdd34f1SGuenter Roeck return; 336bfdd34f1SGuenter Roeck } 337bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 338347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_EHCI1 + i]); 339bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 340347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i)); 341bfdd34f1SGuenter Roeck } 342bfdd34f1SGuenter Roeck 343c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 344668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) { 345c2da8a8bSCédric Le Goater return; 346c2da8a8bSCédric Le Goater } 347347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]); 348013befe1SCédric Le Goater 349013befe1SCédric Le Goater /* Watch dog */ 35054ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3516112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3526112bd6dSCédric Le Goater 3535325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu), 3545325cc34SMarkus Armbruster &error_abort); 355668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { 356013befe1SCédric Le Goater return; 357013befe1SCédric Le Goater } 358f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 359347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_WDT] + i * awc->offset); 360f986ee1dSJoel Stanley } 361ea337c65SCédric Le Goater 362ea337c65SCédric Le Goater /* Net */ 363d3bad7e7SCédric Le Goater for (i = 0; i < sc->macs_num; i++) { 3645325cc34SMarkus Armbruster object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true, 3652255f6b7SMarkus Armbruster &error_abort); 366668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) { 367ea337c65SCédric Le Goater return; 368ea337c65SCédric Le Goater } 36967340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 370347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_ETH1 + i]); 37167340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 372347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i)); 37367340990SCédric Le Goater } 374118c82e7SEddie James 375118c82e7SEddie James /* XDMA */ 376668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) { 377118c82e7SEddie James return; 378118c82e7SEddie James } 379118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 380347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_XDMA]); 381118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 382347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_XDMA)); 383fdcc7c06SRashmica Gupta 384fdcc7c06SRashmica Gupta /* GPIO */ 385668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { 386fdcc7c06SRashmica Gupta return; 387fdcc7c06SRashmica Gupta } 388347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]); 389fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 390347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_GPIO)); 3912bea128cSEddie James 3922bea128cSEddie James /* SDHCI */ 393668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) { 3942bea128cSEddie James return; 3952bea128cSEddie James } 3962bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 397347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SDHCI]); 3982bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 399347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI)); 4002ecf1726SCédric Le Goater 4012ecf1726SCédric Le Goater /* LPC */ 4022ecf1726SCédric Le Goater if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) { 4032ecf1726SCédric Le Goater return; 4042ecf1726SCédric Le Goater } 4052ecf1726SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]); 406c59f781eSAndrew Jeffery 407c59f781eSAndrew Jeffery /* Connect the LPC IRQ to the VIC */ 4082ecf1726SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0, 4092ecf1726SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_DEV_LPC)); 410c59f781eSAndrew Jeffery 411c59f781eSAndrew Jeffery /* 412c59f781eSAndrew Jeffery * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the 413c59f781eSAndrew Jeffery * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by 414c59f781eSAndrew Jeffery * contrast, on the AST2600, the subdevice IRQs are connected straight to 415c59f781eSAndrew Jeffery * the GIC). 416c59f781eSAndrew Jeffery * 417c59f781eSAndrew Jeffery * LPC subdevice IRQ sources are offset from 1 because the shared IRQ output 418c59f781eSAndrew Jeffery * to the VIC is at offset 0. 419c59f781eSAndrew Jeffery */ 420c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1, 421c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_1)); 422c59f781eSAndrew Jeffery 423c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2, 424c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_2)); 425c59f781eSAndrew Jeffery 426c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3, 427c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_3)); 428c59f781eSAndrew Jeffery 429c59f781eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4, 430c59f781eSAndrew Jeffery qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4)); 431a3888d75SJoel Stanley 432a3888d75SJoel Stanley /* HACE */ 433a3888d75SJoel Stanley object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr), 434a3888d75SJoel Stanley &error_abort); 435a3888d75SJoel Stanley if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) { 436a3888d75SJoel Stanley return; 437a3888d75SJoel Stanley } 438a3888d75SJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]); 439a3888d75SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0, 440a3888d75SJoel Stanley aspeed_soc_get_irq(s, ASPEED_DEV_HACE)); 44143e3346eSAndrew Jeffery } 442ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 44395b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 44495b56e17SCédric Le Goater MemoryRegion *), 445ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 446ece09beeSCédric Le Goater }; 44743e3346eSAndrew Jeffery 448ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 44943e3346eSAndrew Jeffery { 45043e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 45143e3346eSAndrew Jeffery 452ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 453469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 454469f3da4SThomas Huth dc->user_creatable = false; 4554f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 45643e3346eSAndrew Jeffery } 45743e3346eSAndrew Jeffery 458ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 459ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 460b033271fSCédric Le Goater .parent = TYPE_DEVICE, 461b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 462b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 46354ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 464b033271fSCédric Le Goater .abstract = true, 46543e3346eSAndrew Jeffery }; 46643e3346eSAndrew Jeffery 46754ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 46854ecafb7SCédric Le Goater { 46954ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 47054ecafb7SCédric Le Goater 47154ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 47254ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 47354ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 47454ecafb7SCédric Le Goater sc->sram_size = 0x8000; 47554ecafb7SCédric Le Goater sc->spis_num = 1; 476bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 47754ecafb7SCédric Le Goater sc->wdts_num = 2; 478d300db02SJoel Stanley sc->macs_num = 2; 47954ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 48054ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 48154ecafb7SCédric Le Goater sc->num_cpus = 1; 48254ecafb7SCédric Le Goater } 48354ecafb7SCédric Le Goater 48454ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 48554ecafb7SCédric Le Goater .name = "ast2400-a1", 48654ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 48754ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 48854ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 48954ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 49054ecafb7SCédric Le Goater }; 49154ecafb7SCédric Le Goater 49254ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 49354ecafb7SCédric Le Goater { 49454ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 49554ecafb7SCédric Le Goater 49654ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 49754ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 49854ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 49954ecafb7SCédric Le Goater sc->sram_size = 0x9000; 50054ecafb7SCédric Le Goater sc->spis_num = 2; 501bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 50254ecafb7SCédric Le Goater sc->wdts_num = 3; 503d300db02SJoel Stanley sc->macs_num = 2; 50454ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 50554ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 50654ecafb7SCédric Le Goater sc->num_cpus = 1; 50754ecafb7SCédric Le Goater } 50854ecafb7SCédric Le Goater 50954ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 51054ecafb7SCédric Le Goater .name = "ast2500-a1", 51154ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 51254ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 51354ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 51454ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 51554ecafb7SCédric Le Goater }; 516ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 51743e3346eSAndrew Jeffery { 518ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 51954ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 52054ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 521b033271fSCédric Le Goater }; 52243e3346eSAndrew Jeffery 523ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 524