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, 37347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 38347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 39347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 40347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 41347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 42347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 43347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 44347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 45347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 46347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 47347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 48347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 49347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 50347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 51347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 52347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 53347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 54347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 55347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x40000000, 56d783d1feSCédric Le Goater }; 57d783d1feSCédric Le Goater 58d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 59347df6f8SEduardo Habkost [ASPEED_DEV_IOMEM] = 0x1E600000, 60347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 0x1E620000, 61347df6f8SEduardo Habkost [ASPEED_DEV_SPI1] = 0x1E630000, 62347df6f8SEduardo Habkost [ASPEED_DEV_SPI2] = 0x1E631000, 63347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 0x1E6A1000, 64347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 0x1E6A3000, 65347df6f8SEduardo Habkost [ASPEED_DEV_VIC] = 0x1E6C0000, 66347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0x1E6E0000, 67347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 0x1E6E2000, 68347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 0x1E6E7000, 69347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 0x1E6E9000, 70347df6f8SEduardo Habkost [ASPEED_DEV_VIDEO] = 0x1E700000, 71347df6f8SEduardo Habkost [ASPEED_DEV_SRAM] = 0x1E720000, 72347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 0x1E740000, 73347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 0x1E780000, 74347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 0x1E781000, 75347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 0x1E782000, 76347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 0x1E785000, 77347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 0x1E786000, 78347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 0x1E789000, 79347df6f8SEduardo Habkost [ASPEED_DEV_IBT] = 0x1E789140, 80347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 0x1E78A000, 81347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 0x1E660000, 82347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 0x1E680000, 83347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 0x1E783000, 84347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 0x1E784000, 85347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 0x1E787000, 86347df6f8SEduardo Habkost [ASPEED_DEV_SDRAM] = 0x80000000, 87d783d1feSCédric Le Goater }; 8843e3346eSAndrew Jeffery 89b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 90347df6f8SEduardo Habkost [ASPEED_DEV_UART1] = 9, 91347df6f8SEduardo Habkost [ASPEED_DEV_UART2] = 32, 92347df6f8SEduardo Habkost [ASPEED_DEV_UART3] = 33, 93347df6f8SEduardo Habkost [ASPEED_DEV_UART4] = 34, 94347df6f8SEduardo Habkost [ASPEED_DEV_UART5] = 10, 95347df6f8SEduardo Habkost [ASPEED_DEV_VUART] = 8, 96347df6f8SEduardo Habkost [ASPEED_DEV_FMC] = 19, 97347df6f8SEduardo Habkost [ASPEED_DEV_EHCI1] = 5, 98347df6f8SEduardo Habkost [ASPEED_DEV_EHCI2] = 13, 99347df6f8SEduardo Habkost [ASPEED_DEV_SDMC] = 0, 100347df6f8SEduardo Habkost [ASPEED_DEV_SCU] = 21, 101347df6f8SEduardo Habkost [ASPEED_DEV_ADC] = 31, 102347df6f8SEduardo Habkost [ASPEED_DEV_GPIO] = 20, 103347df6f8SEduardo Habkost [ASPEED_DEV_RTC] = 22, 104347df6f8SEduardo Habkost [ASPEED_DEV_TIMER1] = 16, 105347df6f8SEduardo Habkost [ASPEED_DEV_TIMER2] = 17, 106347df6f8SEduardo Habkost [ASPEED_DEV_TIMER3] = 18, 107347df6f8SEduardo Habkost [ASPEED_DEV_TIMER4] = 35, 108347df6f8SEduardo Habkost [ASPEED_DEV_TIMER5] = 36, 109347df6f8SEduardo Habkost [ASPEED_DEV_TIMER6] = 37, 110347df6f8SEduardo Habkost [ASPEED_DEV_TIMER7] = 38, 111347df6f8SEduardo Habkost [ASPEED_DEV_TIMER8] = 39, 112347df6f8SEduardo Habkost [ASPEED_DEV_WDT] = 27, 113347df6f8SEduardo Habkost [ASPEED_DEV_PWM] = 28, 114347df6f8SEduardo Habkost [ASPEED_DEV_LPC] = 8, 115347df6f8SEduardo Habkost [ASPEED_DEV_I2C] = 12, 116347df6f8SEduardo Habkost [ASPEED_DEV_ETH1] = 2, 117347df6f8SEduardo Habkost [ASPEED_DEV_ETH2] = 3, 118347df6f8SEduardo Habkost [ASPEED_DEV_XDMA] = 6, 119347df6f8SEduardo Habkost [ASPEED_DEV_SDHCI] = 26, 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 199db873cc5SMarkus Armbruster object_initialize_child(obj, "xdma", &s->xdma, TYPE_ASPEED_XDMA); 200fdcc7c06SRashmica Gupta 201811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 202db873cc5SMarkus Armbruster object_initialize_child(obj, "gpio", &s->gpio, typename); 2032bea128cSEddie James 204db873cc5SMarkus Armbruster object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI); 2052bea128cSEddie James 2065325cc34SMarkus Armbruster object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); 2070e2c24c6SAndrew Jeffery 2082bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2092bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2107089e0ccSMarkus Armbruster object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i], 2117089e0ccSMarkus Armbruster TYPE_SYSBUS_SDHCI); 2122bea128cSEddie James } 2132ecf1726SCédric Le Goater 2142ecf1726SCédric Le Goater object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); 21543e3346eSAndrew Jeffery } 21643e3346eSAndrew Jeffery 217ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 21843e3346eSAndrew Jeffery { 21943e3346eSAndrew Jeffery int i; 220ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 221dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 222123327d1SMarkus Armbruster Error *err = NULL; 22343e3346eSAndrew Jeffery 22443e3346eSAndrew Jeffery /* IO space */ 225347df6f8SEduardo Habkost create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM], 226d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 22743e3346eSAndrew Jeffery 228514bcf6fSJoel Stanley /* Video engine stub */ 229347df6f8SEduardo Habkost create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO], 230514bcf6fSJoel Stanley 0x1000); 231514bcf6fSJoel Stanley 2322d105bd6SCédric Le Goater /* CPU */ 233b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 234668f62ecSMarkus Armbruster if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) { 2352d105bd6SCédric Le Goater return; 2362d105bd6SCédric Le Goater } 237ece09beeSCédric Le Goater } 2382d105bd6SCédric Le Goater 23974af4eecSCédric Le Goater /* SRAM */ 240a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 24154ecafb7SCédric Le Goater sc->sram_size, &err); 24274af4eecSCédric Le Goater if (err) { 24374af4eecSCédric Le Goater error_propagate(errp, err); 24474af4eecSCédric Le Goater return; 24574af4eecSCédric Le Goater } 246d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 247347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SRAM], &s->sram); 24874af4eecSCédric Le Goater 249e2a11ca8SCédric Le Goater /* SCU */ 250668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { 251e2a11ca8SCédric Le Goater return; 252e2a11ca8SCédric Le Goater } 253347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); 254e2a11ca8SCédric Le Goater 25543e3346eSAndrew Jeffery /* VIC */ 256668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) { 25743e3346eSAndrew Jeffery return; 25843e3346eSAndrew Jeffery } 259347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]); 26043e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2612d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 26243e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2632d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 26443e3346eSAndrew Jeffery 26575fb4577SJoel Stanley /* RTC */ 266668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) { 26775fb4577SJoel Stanley return; 26875fb4577SJoel Stanley } 269347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]); 27075fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 271347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_RTC)); 27275fb4577SJoel Stanley 27343e3346eSAndrew Jeffery /* Timer */ 2745325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), 2755325cc34SMarkus Armbruster &error_abort); 276668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) { 27743e3346eSAndrew Jeffery return; 27843e3346eSAndrew Jeffery } 279d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 280347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_TIMER1]); 281b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 282347df6f8SEduardo Habkost qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i); 28343e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 28443e3346eSAndrew Jeffery } 28543e3346eSAndrew Jeffery 28643e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 287347df6f8SEduardo Habkost serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2, 288a6b2f1fcSPhilippe Mathieu-Daudé aspeed_soc_get_irq(s, ASPEED_DEV_UART5), 38400, 289a6b2f1fcSPhilippe Mathieu-Daudé serial_hd(0), DEVICE_LITTLE_ENDIAN); 29016020011SCédric Le Goater 29116020011SCédric Le Goater /* I2C */ 2925325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr), 293c24d9716SMarkus Armbruster &error_abort); 294668f62ecSMarkus Armbruster if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { 29516020011SCédric Le Goater return; 29616020011SCédric Le Goater } 297347df6f8SEduardo Habkost sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]); 29816020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 299347df6f8SEduardo Habkost aspeed_soc_get_irq(s, ASPEED_DEV_I2C)); 3007c1c69bcSCédric Le Goater 30126d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 3025325cc34SMarkus Armbruster object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr), 303c24d9716SMarkus Armbruster &error_abort); 304778a2dc5SMarkus Armbruster if (!object_property_set_int(OBJECT(&s->fmc), "sdram-base", 305347df6f8SEduardo Habkost sc->memmap[ASPEED_DEV_SDRAM], errp)) { 3066da4433fSCédric Le Goater return; 3076da4433fSCédric Le Goater } 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)); 42843e3346eSAndrew Jeffery } 429ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 43095b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 43195b56e17SCédric Le Goater MemoryRegion *), 432ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 433ece09beeSCédric Le Goater }; 43443e3346eSAndrew Jeffery 435ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 43643e3346eSAndrew Jeffery { 43743e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 43843e3346eSAndrew Jeffery 439ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 440469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 441469f3da4SThomas Huth dc->user_creatable = false; 4424f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 44343e3346eSAndrew Jeffery } 44443e3346eSAndrew Jeffery 445ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 446ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 447b033271fSCédric Le Goater .parent = TYPE_DEVICE, 448b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 449b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 45054ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 451b033271fSCédric Le Goater .abstract = true, 45243e3346eSAndrew Jeffery }; 45343e3346eSAndrew Jeffery 45454ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 45554ecafb7SCédric Le Goater { 45654ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 45754ecafb7SCédric Le Goater 45854ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 45954ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 46054ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 46154ecafb7SCédric Le Goater sc->sram_size = 0x8000; 46254ecafb7SCédric Le Goater sc->spis_num = 1; 463bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 46454ecafb7SCédric Le Goater sc->wdts_num = 2; 465d300db02SJoel Stanley sc->macs_num = 2; 46654ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 46754ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 46854ecafb7SCédric Le Goater sc->num_cpus = 1; 46954ecafb7SCédric Le Goater } 47054ecafb7SCédric Le Goater 47154ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 47254ecafb7SCédric Le Goater .name = "ast2400-a1", 47354ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 47454ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 47554ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 47654ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 47754ecafb7SCédric Le Goater }; 47854ecafb7SCédric Le Goater 47954ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 48054ecafb7SCédric Le Goater { 48154ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 48254ecafb7SCédric Le Goater 48354ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 48454ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 48554ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 48654ecafb7SCédric Le Goater sc->sram_size = 0x9000; 48754ecafb7SCédric Le Goater sc->spis_num = 2; 488bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 48954ecafb7SCédric Le Goater sc->wdts_num = 3; 490d300db02SJoel Stanley sc->macs_num = 2; 49154ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 49254ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 49354ecafb7SCédric Le Goater sc->num_cpus = 1; 49454ecafb7SCédric Le Goater } 49554ecafb7SCédric Le Goater 49654ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 49754ecafb7SCédric Le Goater .name = "ast2500-a1", 49854ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 49954ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 50054ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 50154ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 50254ecafb7SCédric Le Goater }; 503ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 50443e3346eSAndrew Jeffery { 505ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 50654ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 50754ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 508b033271fSCédric Le Goater }; 50943e3346eSAndrew Jeffery 510ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 511