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++) { 145ece09beeSCédric Le Goater object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), 14654ecafb7SCédric Le Goater sizeof(s->cpu[i]), sc->cpu_type, 147ece09beeSCédric Le Goater &error_abort, NULL); 148ece09beeSCédric Le Goater } 14943e3346eSAndrew Jeffery 1509a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 1511b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu), 1529a937f6cSCédric Le Goater typename); 153334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 15454ecafb7SCédric Le Goater sc->silicon_rev); 155334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 156334973bbSAndrew Jeffery "hw-strap1", &error_abort); 157334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 158334973bbSAndrew Jeffery "hw-strap2", &error_abort); 159b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 160b6e70d1dSJoel Stanley "hw-prot-key", &error_abort); 1617c1c69bcSCédric Le Goater 1621b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic), 1631b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_VIC); 164e2a11ca8SCédric Le Goater 16575fb4577SJoel Stanley sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc), 16675fb4577SJoel Stanley TYPE_ASPEED_RTC); 16775fb4577SJoel Stanley 16872d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 1691b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), 17072d96f8eSCédric Le Goater sizeof(s->timerctrl), typename); 171e2a11ca8SCédric Le Goater 172f7da1aa8SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); 1731b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), 174f7da1aa8SCédric Le Goater typename); 175e2a11ca8SCédric Le Goater 176811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 1771b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc), 178811a5b1dSCédric Le Goater typename); 17926d5df95SCédric Le Goater object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", 18026d5df95SCédric Le Goater &error_abort); 1817c1c69bcSCédric Le Goater 18254ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 183811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 1841b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), 185811a5b1dSCédric Le Goater sizeof(s->spi[i]), typename); 186dbcabeebSCédric Le Goater } 187c2da8a8bSCédric Le Goater 188bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 189bfdd34f1SGuenter Roeck sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), 190bfdd34f1SGuenter Roeck sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); 191bfdd34f1SGuenter Roeck } 192bfdd34f1SGuenter Roeck 1938e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 1941b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), 1958e00d1a9SCédric Le Goater typename); 196c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 197c6c7cfb0SCédric Le Goater "ram-size", &error_abort); 198ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 199ebe31c0aSCédric Le Goater "max-ram-size", &error_abort); 200013befe1SCédric Le Goater 20154ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 2026112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 2031b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), 2046112bd6dSCédric Le Goater sizeof(s->wdt[i]), typename); 205f986ee1dSJoel Stanley } 206ea337c65SCédric Le Goater 207d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 20867340990SCédric Le Goater sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]), 20967340990SCédric Le Goater sizeof(s->ftgmac100[i]), TYPE_FTGMAC100); 21067340990SCédric Le Goater } 211118c82e7SEddie James 212118c82e7SEddie James sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), 213118c82e7SEddie James TYPE_ASPEED_XDMA); 214fdcc7c06SRashmica Gupta 215811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 216fdcc7c06SRashmica Gupta sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio), 217811a5b1dSCédric Le Goater typename); 2182bea128cSEddie James 2192bea128cSEddie James sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci), 2202bea128cSEddie James TYPE_ASPEED_SDHCI); 2212bea128cSEddie James 2220e2c24c6SAndrew Jeffery object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort); 2230e2c24c6SAndrew Jeffery 2242bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2252bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2262bea128cSEddie James sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]), 2272bea128cSEddie James sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI); 2282bea128cSEddie James } 22943e3346eSAndrew Jeffery } 23043e3346eSAndrew Jeffery 231ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 23243e3346eSAndrew Jeffery { 23343e3346eSAndrew Jeffery int i; 234ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 235dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2367c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 23743e3346eSAndrew Jeffery 23843e3346eSAndrew Jeffery /* IO space */ 23954ecafb7SCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM], 240d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 24143e3346eSAndrew Jeffery 242514bcf6fSJoel Stanley /* Video engine stub */ 243514bcf6fSJoel Stanley create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO], 244514bcf6fSJoel Stanley 0x1000); 245514bcf6fSJoel Stanley 24654ecafb7SCédric Le Goater if (s->num_cpus > sc->num_cpus) { 247ece09beeSCédric Le Goater warn_report("%s: invalid number of CPUs %d, using default %d", 24854ecafb7SCédric Le Goater sc->name, s->num_cpus, sc->num_cpus); 24954ecafb7SCédric Le Goater s->num_cpus = sc->num_cpus; 250ece09beeSCédric Le Goater } 251ece09beeSCédric Le Goater 2522d105bd6SCédric Le Goater /* CPU */ 253ece09beeSCédric Le Goater for (i = 0; i < s->num_cpus; i++) { 254ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2552d105bd6SCédric Le Goater if (err) { 2562d105bd6SCédric Le Goater error_propagate(errp, err); 2572d105bd6SCédric Le Goater return; 2582d105bd6SCédric Le Goater } 259ece09beeSCédric Le Goater } 2602d105bd6SCédric Le Goater 26174af4eecSCédric Le Goater /* SRAM */ 262a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 26354ecafb7SCédric Le Goater sc->sram_size, &err); 26474af4eecSCédric Le Goater if (err) { 26574af4eecSCédric Le Goater error_propagate(errp, err); 26674af4eecSCédric Le Goater return; 26774af4eecSCédric Le Goater } 268d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 26954ecafb7SCédric Le Goater sc->memmap[ASPEED_SRAM], &s->sram); 27074af4eecSCédric Le Goater 271e2a11ca8SCédric Le Goater /* SCU */ 272e2a11ca8SCédric Le Goater object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); 273e2a11ca8SCédric Le Goater if (err) { 274e2a11ca8SCédric Le Goater error_propagate(errp, err); 275e2a11ca8SCédric Le Goater return; 276e2a11ca8SCédric Le Goater } 27754ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_SCU]); 278e2a11ca8SCédric Le Goater 27943e3346eSAndrew Jeffery /* VIC */ 28043e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); 28143e3346eSAndrew Jeffery if (err) { 28243e3346eSAndrew Jeffery error_propagate(errp, err); 28343e3346eSAndrew Jeffery return; 28443e3346eSAndrew Jeffery } 28554ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_VIC]); 28643e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2872d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 28843e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2892d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 29043e3346eSAndrew Jeffery 29175fb4577SJoel Stanley /* RTC */ 29275fb4577SJoel Stanley object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); 29375fb4577SJoel Stanley if (err) { 29475fb4577SJoel Stanley error_propagate(errp, err); 29575fb4577SJoel Stanley return; 29675fb4577SJoel Stanley } 29754ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_RTC]); 29875fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 29975fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 30075fb4577SJoel Stanley 30143e3346eSAndrew Jeffery /* Timer */ 3022ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->timerctrl), 3032ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 30443e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); 30543e3346eSAndrew Jeffery if (err) { 30643e3346eSAndrew Jeffery error_propagate(errp, err); 30743e3346eSAndrew Jeffery return; 30843e3346eSAndrew Jeffery } 309d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 31054ecafb7SCédric Le Goater sc->memmap[ASPEED_TIMER1]); 311b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 312b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 31343e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 31443e3346eSAndrew Jeffery } 31543e3346eSAndrew Jeffery 31643e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 3179bca0edbSPeter Maydell if (serial_hd(0)) { 318b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 31954ecafb7SCédric Le Goater serial_mm_init(get_system_memory(), sc->memmap[ASPEED_UART5], 2, 3209bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 32143e3346eSAndrew Jeffery } 32216020011SCédric Le Goater 32316020011SCédric Le Goater /* I2C */ 324545d6befSCédric Le Goater object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err); 325545d6befSCédric Le Goater if (err) { 326545d6befSCédric Le Goater error_propagate(errp, err); 327545d6befSCédric Le Goater return; 328545d6befSCédric Le Goater } 32916020011SCédric Le Goater object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); 33016020011SCédric Le Goater if (err) { 33116020011SCédric Le Goater error_propagate(errp, err); 33216020011SCédric Le Goater return; 33316020011SCédric Le Goater } 33454ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_I2C]); 33516020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 336b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3377c1c69bcSCédric Le Goater 33826d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 33995b56e17SCédric Le Goater object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err); 34095b56e17SCédric Le Goater if (err) { 34195b56e17SCédric Le Goater error_propagate(errp, err); 34295b56e17SCédric Le Goater return; 34395b56e17SCédric Le Goater } 34454ecafb7SCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], 3456da4433fSCédric Le Goater "sdram-base", &err); 3466da4433fSCédric Le Goater if (err) { 3476da4433fSCédric Le Goater error_propagate(errp, err); 3486da4433fSCédric Le Goater return; 3496da4433fSCédric Le Goater } 35026d5df95SCédric Le Goater object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); 3517c1c69bcSCédric Le Goater if (err) { 3527c1c69bcSCédric Le Goater error_propagate(errp, err); 3537c1c69bcSCédric Le Goater return; 3547c1c69bcSCédric Le Goater } 35554ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_FMC]); 356dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 357dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3580e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 359b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3607c1c69bcSCédric Le Goater 3617c1c69bcSCédric Le Goater /* SPI */ 36254ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 363dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 364dbcabeebSCédric Le Goater object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 365dbcabeebSCédric Le Goater &local_err); 3667c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3677c1c69bcSCédric Le Goater if (err) { 3687c1c69bcSCédric Le Goater error_propagate(errp, err); 3697c1c69bcSCédric Le Goater return; 3707c1c69bcSCédric Le Goater } 371d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 37254ecafb7SCédric Le Goater sc->memmap[ASPEED_SPI1 + i]); 373dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 374dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 375dbcabeebSCédric Le Goater } 376c2da8a8bSCédric Le Goater 377bfdd34f1SGuenter Roeck /* EHCI */ 378bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 379bfdd34f1SGuenter Roeck object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); 380bfdd34f1SGuenter Roeck if (err) { 381bfdd34f1SGuenter Roeck error_propagate(errp, err); 382bfdd34f1SGuenter Roeck return; 383bfdd34f1SGuenter Roeck } 384bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 385bfdd34f1SGuenter Roeck sc->memmap[ASPEED_EHCI1 + i]); 386bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 387bfdd34f1SGuenter Roeck aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); 388bfdd34f1SGuenter Roeck } 389bfdd34f1SGuenter Roeck 390c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 391c2da8a8bSCédric Le Goater object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); 392c2da8a8bSCédric Le Goater if (err) { 393c2da8a8bSCédric Le Goater error_propagate(errp, err); 394c2da8a8bSCédric Le Goater return; 395c2da8a8bSCédric Le Goater } 39654ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_SDMC]); 397013befe1SCédric Le Goater 398013befe1SCédric Le Goater /* Watch dog */ 39954ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 4006112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 4016112bd6dSCédric Le Goater 4022ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->wdt[i]), 4032ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 404f986ee1dSJoel Stanley object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); 405013befe1SCédric Le Goater if (err) { 406013befe1SCédric Le Goater error_propagate(errp, err); 407013befe1SCédric Le Goater return; 408013befe1SCédric Le Goater } 409f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 41054ecafb7SCédric Le Goater sc->memmap[ASPEED_WDT] + i * awc->offset); 411f986ee1dSJoel Stanley } 412ea337c65SCédric Le Goater 413ea337c65SCédric Le Goater /* Net */ 414d300db02SJoel Stanley for (i = 0; i < nb_nics && i < sc->macs_num; i++) { 41567340990SCédric Le Goater qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]); 41667340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 41767340990SCédric Le Goater &err); 41867340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized", 419ea337c65SCédric Le Goater &local_err); 420ea337c65SCédric Le Goater error_propagate(&err, local_err); 421ea337c65SCédric Le Goater if (err) { 422ea337c65SCédric Le Goater error_propagate(errp, err); 423ea337c65SCédric Le Goater return; 424ea337c65SCédric Le Goater } 42567340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 42654ecafb7SCédric Le Goater sc->memmap[ASPEED_ETH1 + i]); 42767340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 42867340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 42967340990SCédric Le Goater } 430118c82e7SEddie James 431118c82e7SEddie James /* XDMA */ 432118c82e7SEddie James object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err); 433118c82e7SEddie James if (err) { 434118c82e7SEddie James error_propagate(errp, err); 435118c82e7SEddie James return; 436118c82e7SEddie James } 437118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 43854ecafb7SCédric Le Goater sc->memmap[ASPEED_XDMA]); 439118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 440118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 441fdcc7c06SRashmica Gupta 442fdcc7c06SRashmica Gupta /* GPIO */ 443fdcc7c06SRashmica Gupta object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err); 444fdcc7c06SRashmica Gupta if (err) { 445fdcc7c06SRashmica Gupta error_propagate(errp, err); 446fdcc7c06SRashmica Gupta return; 447fdcc7c06SRashmica Gupta } 44854ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_GPIO]); 449fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 450fdcc7c06SRashmica Gupta aspeed_soc_get_irq(s, ASPEED_GPIO)); 4512bea128cSEddie James 4522bea128cSEddie James /* SDHCI */ 4532bea128cSEddie James object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err); 4542bea128cSEddie James if (err) { 4552bea128cSEddie James error_propagate(errp, err); 4562bea128cSEddie James return; 4572bea128cSEddie James } 4582bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 45954ecafb7SCédric Le Goater sc->memmap[ASPEED_SDHCI]); 4602bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 4612bea128cSEddie James aspeed_soc_get_irq(s, ASPEED_SDHCI)); 46243e3346eSAndrew Jeffery } 463ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 464ece09beeSCédric Le Goater DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), 46595b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 46695b56e17SCédric Le Goater MemoryRegion *), 467ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 468ece09beeSCédric Le Goater }; 46943e3346eSAndrew Jeffery 470ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 47143e3346eSAndrew Jeffery { 47243e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 47343e3346eSAndrew Jeffery 474ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 475469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 476469f3da4SThomas Huth dc->user_creatable = false; 4774f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 47843e3346eSAndrew Jeffery } 47943e3346eSAndrew Jeffery 480ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 481ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 482b033271fSCédric Le Goater .parent = TYPE_DEVICE, 483b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 484b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 48554ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 486b033271fSCédric Le Goater .abstract = true, 48743e3346eSAndrew Jeffery }; 48843e3346eSAndrew Jeffery 48954ecafb7SCédric Le Goater static void aspeed_soc_ast2400_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 = "ast2400-a1"; 49454ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 49554ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 49654ecafb7SCédric Le Goater sc->sram_size = 0x8000; 49754ecafb7SCédric Le Goater sc->spis_num = 1; 498bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 49954ecafb7SCédric Le Goater sc->wdts_num = 2; 500d300db02SJoel Stanley sc->macs_num = 2; 50154ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 50254ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_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_ast2400_type_info = { 50754ecafb7SCédric Le Goater .name = "ast2400-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_ast2400_class_init, 51254ecafb7SCédric Le Goater }; 51354ecafb7SCédric Le Goater 51454ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 51554ecafb7SCédric Le Goater { 51654ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 51754ecafb7SCédric Le Goater 51854ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 51954ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 52054ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 52154ecafb7SCédric Le Goater sc->sram_size = 0x9000; 52254ecafb7SCédric Le Goater sc->spis_num = 2; 523bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 52454ecafb7SCédric Le Goater sc->wdts_num = 3; 525d300db02SJoel Stanley sc->macs_num = 2; 52654ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 52754ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 52854ecafb7SCédric Le Goater sc->num_cpus = 1; 52954ecafb7SCédric Le Goater } 53054ecafb7SCédric Le Goater 53154ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 53254ecafb7SCédric Le Goater .name = "ast2500-a1", 53354ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 53454ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 53554ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 53654ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 53754ecafb7SCédric Le Goater }; 538ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 53943e3346eSAndrew Jeffery { 540ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 54154ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 54254ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 543b033271fSCédric Le Goater }; 54443e3346eSAndrew Jeffery 545ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 546