143e3346eSAndrew Jeffery /* 2ff90606fSCédric Le Goater * ASPEED SoC family 343e3346eSAndrew Jeffery * 443e3346eSAndrew Jeffery * Andrew Jeffery <andrew@aj.id.au> 543e3346eSAndrew Jeffery * Jeremy Kerr <jk@ozlabs.org> 643e3346eSAndrew Jeffery * 743e3346eSAndrew Jeffery * Copyright 2016 IBM Corp. 843e3346eSAndrew Jeffery * 943e3346eSAndrew Jeffery * This code is licensed under the GPL version 2 or later. See 1043e3346eSAndrew Jeffery * the COPYING file in the top-level directory. 1143e3346eSAndrew Jeffery */ 1243e3346eSAndrew Jeffery 1343e3346eSAndrew Jeffery #include "qemu/osdep.h" 14da34e65cSMarkus Armbruster #include "qapi/error.h" 154771d756SPaolo Bonzini #include "cpu.h" 1643e3346eSAndrew Jeffery #include "exec/address-spaces.h" 17c7c3c9f8SPhilippe Mathieu-Daudé #include "hw/misc/unimp.h" 1800442402SCédric Le Goater #include "hw/arm/aspeed_soc.h" 1943e3346eSAndrew Jeffery #include "hw/char/serial.h" 2003dd024fSPaolo Bonzini #include "qemu/log.h" 210b8fa32fSMarkus Armbruster #include "qemu/module.h" 22ece09beeSCédric Le Goater #include "qemu/error-report.h" 2316020011SCédric Le Goater #include "hw/i2c/aspeed_i2c.h" 24ea337c65SCédric Le Goater #include "net/net.h" 2546517dd4SMarkus Armbruster #include "sysemu/sysemu.h" 2643e3346eSAndrew Jeffery 27ff90606fSCédric Le Goater #define ASPEED_SOC_IOMEM_SIZE 0x00200000 28d783d1feSCédric Le Goater 29d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2400_memmap[] = { 30d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 31d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 32d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 33bfdd34f1SGuenter Roeck [ASPEED_EHCI1] = 0x1E6A1000, 34d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 35d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 36d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 37118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 38514bcf6fSJoel Stanley [ASPEED_VIDEO] = 0x1E700000, 39d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 40d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 412bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 42d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 43d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 44d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 45d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 46d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 47d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 48d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 49d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 50d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 51d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 52d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 53d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 54d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 55d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x40000000, 56d783d1feSCédric Le Goater }; 57d783d1feSCédric Le Goater 58d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 59d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 60d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 61d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 62d783d1feSCédric Le Goater [ASPEED_SPI2] = 0x1E631000, 63bfdd34f1SGuenter Roeck [ASPEED_EHCI1] = 0x1E6A1000, 64bfdd34f1SGuenter Roeck [ASPEED_EHCI2] = 0x1E6A3000, 65d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 66d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 67d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 68118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 69d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 70514bcf6fSJoel Stanley [ASPEED_VIDEO] = 0x1E700000, 71d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 722bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 73d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 74d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 75d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 76d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 77d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 78d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 79d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 80d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 81d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 82d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 83d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 84d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 85d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 86d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x80000000, 87d783d1feSCédric Le Goater }; 8843e3346eSAndrew Jeffery 89b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 90b456b113SCédric Le Goater [ASPEED_UART1] = 9, 91b456b113SCédric Le Goater [ASPEED_UART2] = 32, 92b456b113SCédric Le Goater [ASPEED_UART3] = 33, 93b456b113SCédric Le Goater [ASPEED_UART4] = 34, 94b456b113SCédric Le Goater [ASPEED_UART5] = 10, 95b456b113SCédric Le Goater [ASPEED_VUART] = 8, 96b456b113SCédric Le Goater [ASPEED_FMC] = 19, 97bfdd34f1SGuenter Roeck [ASPEED_EHCI1] = 5, 98bfdd34f1SGuenter Roeck [ASPEED_EHCI2] = 13, 99b456b113SCédric Le Goater [ASPEED_SDMC] = 0, 100b456b113SCédric Le Goater [ASPEED_SCU] = 21, 101b456b113SCédric Le Goater [ASPEED_ADC] = 31, 102b456b113SCédric Le Goater [ASPEED_GPIO] = 20, 103b456b113SCédric Le Goater [ASPEED_RTC] = 22, 104b456b113SCédric Le Goater [ASPEED_TIMER1] = 16, 105b456b113SCédric Le Goater [ASPEED_TIMER2] = 17, 106b456b113SCédric Le Goater [ASPEED_TIMER3] = 18, 107b456b113SCédric Le Goater [ASPEED_TIMER4] = 35, 108b456b113SCédric Le Goater [ASPEED_TIMER5] = 36, 109b456b113SCédric Le Goater [ASPEED_TIMER6] = 37, 110b456b113SCédric Le Goater [ASPEED_TIMER7] = 38, 111b456b113SCédric Le Goater [ASPEED_TIMER8] = 39, 112b456b113SCédric Le Goater [ASPEED_WDT] = 27, 113b456b113SCédric Le Goater [ASPEED_PWM] = 28, 114b456b113SCédric Le Goater [ASPEED_LPC] = 8, 115b456b113SCédric Le Goater [ASPEED_IBT] = 8, /* LPC */ 116b456b113SCédric Le Goater [ASPEED_I2C] = 12, 117b456b113SCédric Le Goater [ASPEED_ETH1] = 2, 118b456b113SCédric Le Goater [ASPEED_ETH2] = 3, 119118c82e7SEddie James [ASPEED_XDMA] = 6, 1202bea128cSEddie James [ASPEED_SDHCI] = 26, 121b456b113SCédric Le Goater }; 12243e3346eSAndrew Jeffery 123b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 124b456b113SCédric Le Goater 125b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 126b456b113SCédric Le Goater { 127b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 128b456b113SCédric Le Goater 12954ecafb7SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]); 130b456b113SCédric Le Goater } 131b456b113SCédric Le Goater 132ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 13343e3346eSAndrew Jeffery { 134ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 135b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 136dbcabeebSCédric Le Goater int i; 137811a5b1dSCédric Le Goater char socname[8]; 138811a5b1dSCédric Le Goater char typename[64]; 139811a5b1dSCédric Le Goater 14054ecafb7SCédric Le Goater if (sscanf(sc->name, "%7s", socname) != 1) { 141811a5b1dSCédric Le Goater g_assert_not_reached(); 142811a5b1dSCédric Le Goater } 14343e3346eSAndrew Jeffery 14454ecafb7SCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 1459fc7fc4dSMarkus Armbruster object_initialize_child(obj, "cpu[*]", &s->cpu[i], sc->cpu_type); 146ece09beeSCédric Le Goater } 14743e3346eSAndrew Jeffery 1489a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 149db873cc5SMarkus Armbruster object_initialize_child(obj, "scu", &s->scu, typename); 150334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 15154ecafb7SCédric Le Goater sc->silicon_rev); 152334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 153d2623129SMarkus Armbruster "hw-strap1"); 154334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 155d2623129SMarkus Armbruster "hw-strap2"); 156b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 157d2623129SMarkus Armbruster "hw-prot-key"); 1587c1c69bcSCédric Le Goater 159db873cc5SMarkus Armbruster object_initialize_child(obj, "vic", &s->vic, TYPE_ASPEED_VIC); 160e2a11ca8SCédric Le Goater 161db873cc5SMarkus Armbruster object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC); 16275fb4577SJoel Stanley 16372d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 164db873cc5SMarkus Armbruster object_initialize_child(obj, "timerctrl", &s->timerctrl, typename); 165e2a11ca8SCédric Le Goater 166f7da1aa8SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); 167db873cc5SMarkus Armbruster object_initialize_child(obj, "i2c", &s->i2c, typename); 168e2a11ca8SCédric Le Goater 169811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 170db873cc5SMarkus Armbruster object_initialize_child(obj, "fmc", &s->fmc, typename); 171d2623129SMarkus Armbruster object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs"); 1727c1c69bcSCédric Le Goater 17354ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 174811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 175db873cc5SMarkus Armbruster object_initialize_child(obj, "spi[*]", &s->spi[i], typename); 176dbcabeebSCédric Le Goater } 177c2da8a8bSCédric Le Goater 178bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 179db873cc5SMarkus Armbruster object_initialize_child(obj, "ehci[*]", &s->ehci[i], 180db873cc5SMarkus Armbruster TYPE_PLATFORM_EHCI); 181bfdd34f1SGuenter Roeck } 182bfdd34f1SGuenter Roeck 1838e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 184db873cc5SMarkus Armbruster object_initialize_child(obj, "sdmc", &s->sdmc, typename); 185c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 186d2623129SMarkus Armbruster "ram-size"); 187ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 188d2623129SMarkus Armbruster "max-ram-size"); 189013befe1SCédric Le Goater 19054ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 1916112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 192db873cc5SMarkus Armbruster object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename); 193f986ee1dSJoel Stanley } 194ea337c65SCédric Le Goater 195d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 196db873cc5SMarkus Armbruster object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i], 197db873cc5SMarkus Armbruster TYPE_FTGMAC100); 19867340990SCédric Le Goater } 199118c82e7SEddie James 200db873cc5SMarkus Armbruster object_initialize_child(obj, "xdma", &s->xdma, TYPE_ASPEED_XDMA); 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 2070e2c24c6SAndrew Jeffery object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &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) { 2119bdee7f4SMarkus Armbruster sysbus_init_child_obj(obj, "sdhci[*]", &s->sdhci.slots[i], 2122bea128cSEddie James sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI); 2132bea128cSEddie James } 21443e3346eSAndrew Jeffery } 21543e3346eSAndrew Jeffery 216ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 21743e3346eSAndrew Jeffery { 21843e3346eSAndrew Jeffery int i; 219ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 220dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2217c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 22243e3346eSAndrew Jeffery 22343e3346eSAndrew Jeffery /* IO space */ 22454ecafb7SCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM], 225d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 22643e3346eSAndrew Jeffery 227514bcf6fSJoel Stanley /* Video engine stub */ 228514bcf6fSJoel Stanley create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO], 229514bcf6fSJoel Stanley 0x1000); 230514bcf6fSJoel Stanley 2312d105bd6SCédric Le Goater /* CPU */ 232b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 233ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2342d105bd6SCédric Le Goater if (err) { 2352d105bd6SCédric Le Goater error_propagate(errp, err); 2362d105bd6SCédric Le Goater return; 2372d105bd6SCédric Le Goater } 238ece09beeSCédric Le Goater } 2392d105bd6SCédric Le Goater 24074af4eecSCédric Le Goater /* SRAM */ 241a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 24254ecafb7SCédric Le Goater sc->sram_size, &err); 24374af4eecSCédric Le Goater if (err) { 24474af4eecSCédric Le Goater error_propagate(errp, err); 24574af4eecSCédric Le Goater return; 24674af4eecSCédric Le Goater } 247d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 24854ecafb7SCédric Le Goater sc->memmap[ASPEED_SRAM], &s->sram); 24974af4eecSCédric Le Goater 250e2a11ca8SCédric Le Goater /* SCU */ 251db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->scu), &err); 252e2a11ca8SCédric Le Goater if (err) { 253e2a11ca8SCédric Le Goater error_propagate(errp, err); 254e2a11ca8SCédric Le Goater return; 255e2a11ca8SCédric Le Goater } 25654ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_SCU]); 257e2a11ca8SCédric Le Goater 25843e3346eSAndrew Jeffery /* VIC */ 259db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->vic), &err); 26043e3346eSAndrew Jeffery if (err) { 26143e3346eSAndrew Jeffery error_propagate(errp, err); 26243e3346eSAndrew Jeffery return; 26343e3346eSAndrew Jeffery } 26454ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_VIC]); 26543e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2662d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 26743e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2682d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 26943e3346eSAndrew Jeffery 27075fb4577SJoel Stanley /* RTC */ 271db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &err); 27275fb4577SJoel Stanley if (err) { 27375fb4577SJoel Stanley error_propagate(errp, err); 27475fb4577SJoel Stanley return; 27575fb4577SJoel Stanley } 27654ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_RTC]); 27775fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 27875fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 27975fb4577SJoel Stanley 28043e3346eSAndrew Jeffery /* Timer */ 2812ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->timerctrl), 2822ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 283db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), &err); 28443e3346eSAndrew Jeffery if (err) { 28543e3346eSAndrew Jeffery error_propagate(errp, err); 28643e3346eSAndrew Jeffery return; 28743e3346eSAndrew Jeffery } 288d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 28954ecafb7SCédric Le Goater sc->memmap[ASPEED_TIMER1]); 290b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 291b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 29243e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 29343e3346eSAndrew Jeffery } 29443e3346eSAndrew Jeffery 29543e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 2969bca0edbSPeter Maydell if (serial_hd(0)) { 297b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 29854ecafb7SCédric Le Goater serial_mm_init(get_system_memory(), sc->memmap[ASPEED_UART5], 2, 2999bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 30043e3346eSAndrew Jeffery } 30116020011SCédric Le Goater 30216020011SCédric Le Goater /* I2C */ 303545d6befSCédric Le Goater object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err); 304545d6befSCédric Le Goater if (err) { 305545d6befSCédric Le Goater error_propagate(errp, err); 306545d6befSCédric Le Goater return; 307545d6befSCédric Le Goater } 308db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->i2c), &err); 30916020011SCédric Le Goater if (err) { 31016020011SCédric Le Goater error_propagate(errp, err); 31116020011SCédric Le Goater return; 31216020011SCédric Le Goater } 31354ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_I2C]); 31416020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 315b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3167c1c69bcSCédric Le Goater 31726d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 31895b56e17SCédric Le Goater object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err); 31995b56e17SCédric Le Goater if (err) { 32095b56e17SCédric Le Goater error_propagate(errp, err); 32195b56e17SCédric Le Goater return; 32295b56e17SCédric Le Goater } 32354ecafb7SCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], 3246da4433fSCédric Le Goater "sdram-base", &err); 3256da4433fSCédric Le Goater if (err) { 3266da4433fSCédric Le Goater error_propagate(errp, err); 3276da4433fSCédric Le Goater return; 3286da4433fSCédric Le Goater } 329db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->fmc), &err); 3307c1c69bcSCédric Le Goater if (err) { 3317c1c69bcSCédric Le Goater error_propagate(errp, err); 3327c1c69bcSCédric Le Goater return; 3337c1c69bcSCédric Le Goater } 33454ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_FMC]); 335dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 336dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3370e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 338b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3397c1c69bcSCédric Le Goater 3407c1c69bcSCédric Le Goater /* SPI */ 34154ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 342dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 343db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &local_err); 3447c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3457c1c69bcSCédric Le Goater if (err) { 3467c1c69bcSCédric Le Goater error_propagate(errp, err); 3477c1c69bcSCédric Le Goater return; 3487c1c69bcSCédric Le Goater } 349d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 35054ecafb7SCédric Le Goater sc->memmap[ASPEED_SPI1 + i]); 351dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 352dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 353dbcabeebSCédric Le Goater } 354c2da8a8bSCédric Le Goater 355bfdd34f1SGuenter Roeck /* EHCI */ 356bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 357db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), &err); 358bfdd34f1SGuenter Roeck if (err) { 359bfdd34f1SGuenter Roeck error_propagate(errp, err); 360bfdd34f1SGuenter Roeck return; 361bfdd34f1SGuenter Roeck } 362bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 363bfdd34f1SGuenter Roeck sc->memmap[ASPEED_EHCI1 + i]); 364bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 365bfdd34f1SGuenter Roeck aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); 366bfdd34f1SGuenter Roeck } 367bfdd34f1SGuenter Roeck 368c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 369db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), &err); 370c2da8a8bSCédric Le Goater if (err) { 371c2da8a8bSCédric Le Goater error_propagate(errp, err); 372c2da8a8bSCédric Le Goater return; 373c2da8a8bSCédric Le Goater } 37454ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_SDMC]); 375013befe1SCédric Le Goater 376013befe1SCédric Le Goater /* Watch dog */ 37754ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3786112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3796112bd6dSCédric Le Goater 3802ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->wdt[i]), 3812ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 382db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &err); 383013befe1SCédric Le Goater if (err) { 384013befe1SCédric Le Goater error_propagate(errp, err); 385013befe1SCédric Le Goater return; 386013befe1SCédric Le Goater } 387f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 38854ecafb7SCédric Le Goater sc->memmap[ASPEED_WDT] + i * awc->offset); 389f986ee1dSJoel Stanley } 390ea337c65SCédric Le Goater 391ea337c65SCédric Le Goater /* Net */ 392d3bad7e7SCédric Le Goater for (i = 0; i < sc->macs_num; i++) { 39367340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 39467340990SCédric Le Goater &err); 395db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), &local_err); 396ea337c65SCédric Le Goater error_propagate(&err, local_err); 397ea337c65SCédric Le Goater if (err) { 398ea337c65SCédric Le Goater error_propagate(errp, err); 399ea337c65SCédric Le Goater return; 400ea337c65SCédric Le Goater } 40167340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 40254ecafb7SCédric Le Goater sc->memmap[ASPEED_ETH1 + i]); 40367340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 40467340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 40567340990SCédric Le Goater } 406118c82e7SEddie James 407118c82e7SEddie James /* XDMA */ 408db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->xdma), &err); 409118c82e7SEddie James if (err) { 410118c82e7SEddie James error_propagate(errp, err); 411118c82e7SEddie James return; 412118c82e7SEddie James } 413118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 41454ecafb7SCédric Le Goater sc->memmap[ASPEED_XDMA]); 415118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 416118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 417fdcc7c06SRashmica Gupta 418fdcc7c06SRashmica Gupta /* GPIO */ 419db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err); 420fdcc7c06SRashmica Gupta if (err) { 421fdcc7c06SRashmica Gupta error_propagate(errp, err); 422fdcc7c06SRashmica Gupta return; 423fdcc7c06SRashmica Gupta } 42454ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_GPIO]); 425fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 426fdcc7c06SRashmica Gupta aspeed_soc_get_irq(s, ASPEED_GPIO)); 4272bea128cSEddie James 4282bea128cSEddie James /* SDHCI */ 429db873cc5SMarkus Armbruster sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), &err); 4302bea128cSEddie James if (err) { 4312bea128cSEddie James error_propagate(errp, err); 4322bea128cSEddie James return; 4332bea128cSEddie James } 4342bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 43554ecafb7SCédric Le Goater sc->memmap[ASPEED_SDHCI]); 4362bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 4372bea128cSEddie James aspeed_soc_get_irq(s, ASPEED_SDHCI)); 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 *), 442ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 443ece09beeSCédric Le Goater }; 44443e3346eSAndrew Jeffery 445ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 44643e3346eSAndrew Jeffery { 44743e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 44843e3346eSAndrew Jeffery 449ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 450469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 451469f3da4SThomas Huth dc->user_creatable = false; 4524f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 45343e3346eSAndrew Jeffery } 45443e3346eSAndrew Jeffery 455ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 456ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 457b033271fSCédric Le Goater .parent = TYPE_DEVICE, 458b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 459b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 46054ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 461b033271fSCédric Le Goater .abstract = true, 46243e3346eSAndrew Jeffery }; 46343e3346eSAndrew Jeffery 46454ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 46554ecafb7SCédric Le Goater { 46654ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 46754ecafb7SCédric Le Goater 46854ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 46954ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 47054ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 47154ecafb7SCédric Le Goater sc->sram_size = 0x8000; 47254ecafb7SCédric Le Goater sc->spis_num = 1; 473bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 47454ecafb7SCédric Le Goater sc->wdts_num = 2; 475d300db02SJoel Stanley sc->macs_num = 2; 47654ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 47754ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 47854ecafb7SCédric Le Goater sc->num_cpus = 1; 47954ecafb7SCédric Le Goater } 48054ecafb7SCédric Le Goater 48154ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 48254ecafb7SCédric Le Goater .name = "ast2400-a1", 48354ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 48454ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 48554ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 48654ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 48754ecafb7SCédric Le Goater }; 48854ecafb7SCédric Le Goater 48954ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 49054ecafb7SCédric Le Goater { 49154ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 49254ecafb7SCédric Le Goater 49354ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 49454ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 49554ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 49654ecafb7SCédric Le Goater sc->sram_size = 0x9000; 49754ecafb7SCédric Le Goater sc->spis_num = 2; 498bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 49954ecafb7SCédric Le Goater sc->wdts_num = 3; 500d300db02SJoel Stanley sc->macs_num = 2; 50154ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 50254ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 50354ecafb7SCédric Le Goater sc->num_cpus = 1; 50454ecafb7SCédric Le Goater } 50554ecafb7SCédric Le Goater 50654ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 50754ecafb7SCédric Le Goater .name = "ast2500-a1", 50854ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 50954ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 51054ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 51154ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 51254ecafb7SCédric Le Goater }; 513ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 51443e3346eSAndrew Jeffery { 515ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 51654ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 51754ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 518b033271fSCédric Le Goater }; 51943e3346eSAndrew Jeffery 520ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 521