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), 156d2623129SMarkus Armbruster "hw-strap1"); 157334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 158d2623129SMarkus Armbruster "hw-strap2"); 159b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 160d2623129SMarkus Armbruster "hw-prot-key"); 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); 179d2623129SMarkus Armbruster object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs"); 1807c1c69bcSCédric Le Goater 18154ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 182811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 1831b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), 184811a5b1dSCédric Le Goater sizeof(s->spi[i]), typename); 185dbcabeebSCédric Le Goater } 186c2da8a8bSCédric Le Goater 187bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 188bfdd34f1SGuenter Roeck sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]), 189bfdd34f1SGuenter Roeck sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI); 190bfdd34f1SGuenter Roeck } 191bfdd34f1SGuenter Roeck 1928e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 1931b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), 1948e00d1a9SCédric Le Goater typename); 195c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 196d2623129SMarkus Armbruster "ram-size"); 197ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 198d2623129SMarkus Armbruster "max-ram-size"); 199013befe1SCédric Le Goater 20054ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 2016112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 2021b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), 2036112bd6dSCédric Le Goater sizeof(s->wdt[i]), typename); 204f986ee1dSJoel Stanley } 205ea337c65SCédric Le Goater 206d300db02SJoel Stanley for (i = 0; i < sc->macs_num; i++) { 20767340990SCédric Le Goater sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]), 20867340990SCédric Le Goater sizeof(s->ftgmac100[i]), TYPE_FTGMAC100); 20967340990SCédric Le Goater } 210118c82e7SEddie James 211118c82e7SEddie James sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), 212118c82e7SEddie James TYPE_ASPEED_XDMA); 213fdcc7c06SRashmica Gupta 214811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 215fdcc7c06SRashmica Gupta sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio), 216811a5b1dSCédric Le Goater typename); 2172bea128cSEddie James 2182bea128cSEddie James sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci), 2192bea128cSEddie James TYPE_ASPEED_SDHCI); 2202bea128cSEddie James 2210e2c24c6SAndrew Jeffery object_property_set_int(OBJECT(&s->sdhci), 2, "num-slots", &error_abort); 2220e2c24c6SAndrew Jeffery 2232bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2242bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2252bea128cSEddie James sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]), 2262bea128cSEddie James sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI); 2272bea128cSEddie James } 22843e3346eSAndrew Jeffery } 22943e3346eSAndrew Jeffery 230ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 23143e3346eSAndrew Jeffery { 23243e3346eSAndrew Jeffery int i; 233ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 234dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2357c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 23643e3346eSAndrew Jeffery 23743e3346eSAndrew Jeffery /* IO space */ 23854ecafb7SCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM], 239d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 24043e3346eSAndrew Jeffery 241514bcf6fSJoel Stanley /* Video engine stub */ 242514bcf6fSJoel Stanley create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO], 243514bcf6fSJoel Stanley 0x1000); 244514bcf6fSJoel Stanley 2452d105bd6SCédric Le Goater /* CPU */ 246b7f1a0cbSCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 247ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2482d105bd6SCédric Le Goater if (err) { 2492d105bd6SCédric Le Goater error_propagate(errp, err); 2502d105bd6SCédric Le Goater return; 2512d105bd6SCédric Le Goater } 252ece09beeSCédric Le Goater } 2532d105bd6SCédric Le Goater 25474af4eecSCédric Le Goater /* SRAM */ 255a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 25654ecafb7SCédric Le Goater sc->sram_size, &err); 25774af4eecSCédric Le Goater if (err) { 25874af4eecSCédric Le Goater error_propagate(errp, err); 25974af4eecSCédric Le Goater return; 26074af4eecSCédric Le Goater } 261d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 26254ecafb7SCédric Le Goater sc->memmap[ASPEED_SRAM], &s->sram); 26374af4eecSCédric Le Goater 264e2a11ca8SCédric Le Goater /* SCU */ 265e2a11ca8SCédric Le Goater object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); 266e2a11ca8SCédric Le Goater if (err) { 267e2a11ca8SCédric Le Goater error_propagate(errp, err); 268e2a11ca8SCédric Le Goater return; 269e2a11ca8SCédric Le Goater } 27054ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_SCU]); 271e2a11ca8SCédric Le Goater 27243e3346eSAndrew Jeffery /* VIC */ 27343e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); 27443e3346eSAndrew Jeffery if (err) { 27543e3346eSAndrew Jeffery error_propagate(errp, err); 27643e3346eSAndrew Jeffery return; 27743e3346eSAndrew Jeffery } 27854ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_VIC]); 27943e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2802d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 28143e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2822d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 28343e3346eSAndrew Jeffery 28475fb4577SJoel Stanley /* RTC */ 28575fb4577SJoel Stanley object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); 28675fb4577SJoel Stanley if (err) { 28775fb4577SJoel Stanley error_propagate(errp, err); 28875fb4577SJoel Stanley return; 28975fb4577SJoel Stanley } 29054ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_RTC]); 29175fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 29275fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 29375fb4577SJoel Stanley 29443e3346eSAndrew Jeffery /* Timer */ 2952ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->timerctrl), 2962ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 29743e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); 29843e3346eSAndrew Jeffery if (err) { 29943e3346eSAndrew Jeffery error_propagate(errp, err); 30043e3346eSAndrew Jeffery return; 30143e3346eSAndrew Jeffery } 302d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 30354ecafb7SCédric Le Goater sc->memmap[ASPEED_TIMER1]); 304b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 305b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 30643e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 30743e3346eSAndrew Jeffery } 30843e3346eSAndrew Jeffery 30943e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 3109bca0edbSPeter Maydell if (serial_hd(0)) { 311b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 31254ecafb7SCédric Le Goater serial_mm_init(get_system_memory(), sc->memmap[ASPEED_UART5], 2, 3139bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 31443e3346eSAndrew Jeffery } 31516020011SCédric Le Goater 31616020011SCédric Le Goater /* I2C */ 317545d6befSCédric Le Goater object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err); 318545d6befSCédric Le Goater if (err) { 319545d6befSCédric Le Goater error_propagate(errp, err); 320545d6befSCédric Le Goater return; 321545d6befSCédric Le Goater } 32216020011SCédric Le Goater object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); 32316020011SCédric Le Goater if (err) { 32416020011SCédric Le Goater error_propagate(errp, err); 32516020011SCédric Le Goater return; 32616020011SCédric Le Goater } 32754ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_I2C]); 32816020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 329b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3307c1c69bcSCédric Le Goater 33126d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 33295b56e17SCédric Le Goater object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err); 33395b56e17SCédric Le Goater if (err) { 33495b56e17SCédric Le Goater error_propagate(errp, err); 33595b56e17SCédric Le Goater return; 33695b56e17SCédric Le Goater } 33754ecafb7SCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], 3386da4433fSCédric Le Goater "sdram-base", &err); 3396da4433fSCédric Le Goater if (err) { 3406da4433fSCédric Le Goater error_propagate(errp, err); 3416da4433fSCédric Le Goater return; 3426da4433fSCédric Le Goater } 34326d5df95SCédric Le Goater object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); 3447c1c69bcSCédric Le Goater if (err) { 3457c1c69bcSCédric Le Goater error_propagate(errp, err); 3467c1c69bcSCédric Le Goater return; 3477c1c69bcSCédric Le Goater } 34854ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_FMC]); 349dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 350dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3510e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 352b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3537c1c69bcSCédric Le Goater 3547c1c69bcSCédric Le Goater /* SPI */ 35554ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 356dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 357dbcabeebSCédric Le Goater object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 358dbcabeebSCédric Le Goater &local_err); 3597c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3607c1c69bcSCédric Le Goater if (err) { 3617c1c69bcSCédric Le Goater error_propagate(errp, err); 3627c1c69bcSCédric Le Goater return; 3637c1c69bcSCédric Le Goater } 364d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 36554ecafb7SCédric Le Goater sc->memmap[ASPEED_SPI1 + i]); 366dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 367dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 368dbcabeebSCédric Le Goater } 369c2da8a8bSCédric Le Goater 370bfdd34f1SGuenter Roeck /* EHCI */ 371bfdd34f1SGuenter Roeck for (i = 0; i < sc->ehcis_num; i++) { 372bfdd34f1SGuenter Roeck object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized", &err); 373bfdd34f1SGuenter Roeck if (err) { 374bfdd34f1SGuenter Roeck error_propagate(errp, err); 375bfdd34f1SGuenter Roeck return; 376bfdd34f1SGuenter Roeck } 377bfdd34f1SGuenter Roeck sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0, 378bfdd34f1SGuenter Roeck sc->memmap[ASPEED_EHCI1 + i]); 379bfdd34f1SGuenter Roeck sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, 380bfdd34f1SGuenter Roeck aspeed_soc_get_irq(s, ASPEED_EHCI1 + i)); 381bfdd34f1SGuenter Roeck } 382bfdd34f1SGuenter Roeck 383c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 384c2da8a8bSCédric Le Goater object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); 385c2da8a8bSCédric Le Goater if (err) { 386c2da8a8bSCédric Le Goater error_propagate(errp, err); 387c2da8a8bSCédric Le Goater return; 388c2da8a8bSCédric Le Goater } 38954ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_SDMC]); 390013befe1SCédric Le Goater 391013befe1SCédric Le Goater /* Watch dog */ 39254ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3936112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3946112bd6dSCédric Le Goater 3952ec11f23SCédric Le Goater object_property_set_link(OBJECT(&s->wdt[i]), 3962ec11f23SCédric Le Goater OBJECT(&s->scu), "scu", &error_abort); 397f986ee1dSJoel Stanley object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); 398013befe1SCédric Le Goater if (err) { 399013befe1SCédric Le Goater error_propagate(errp, err); 400013befe1SCédric Le Goater return; 401013befe1SCédric Le Goater } 402f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 40354ecafb7SCédric Le Goater sc->memmap[ASPEED_WDT] + i * awc->offset); 404f986ee1dSJoel Stanley } 405ea337c65SCédric Le Goater 406ea337c65SCédric Le Goater /* Net */ 407d3bad7e7SCédric Le Goater for (i = 0; i < sc->macs_num; i++) { 40867340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 40967340990SCédric Le Goater &err); 41067340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized", 411ea337c65SCédric Le Goater &local_err); 412ea337c65SCédric Le Goater error_propagate(&err, local_err); 413ea337c65SCédric Le Goater if (err) { 414ea337c65SCédric Le Goater error_propagate(errp, err); 415ea337c65SCédric Le Goater return; 416ea337c65SCédric Le Goater } 41767340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 41854ecafb7SCédric Le Goater sc->memmap[ASPEED_ETH1 + i]); 41967340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 42067340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 42167340990SCédric Le Goater } 422118c82e7SEddie James 423118c82e7SEddie James /* XDMA */ 424118c82e7SEddie James object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err); 425118c82e7SEddie James if (err) { 426118c82e7SEddie James error_propagate(errp, err); 427118c82e7SEddie James return; 428118c82e7SEddie James } 429118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 43054ecafb7SCédric Le Goater sc->memmap[ASPEED_XDMA]); 431118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 432118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 433fdcc7c06SRashmica Gupta 434fdcc7c06SRashmica Gupta /* GPIO */ 435fdcc7c06SRashmica Gupta object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err); 436fdcc7c06SRashmica Gupta if (err) { 437fdcc7c06SRashmica Gupta error_propagate(errp, err); 438fdcc7c06SRashmica Gupta return; 439fdcc7c06SRashmica Gupta } 44054ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_GPIO]); 441fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 442fdcc7c06SRashmica Gupta aspeed_soc_get_irq(s, ASPEED_GPIO)); 4432bea128cSEddie James 4442bea128cSEddie James /* SDHCI */ 4452bea128cSEddie James object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err); 4462bea128cSEddie James if (err) { 4472bea128cSEddie James error_propagate(errp, err); 4482bea128cSEddie James return; 4492bea128cSEddie James } 4502bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 45154ecafb7SCédric Le Goater sc->memmap[ASPEED_SDHCI]); 4522bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 4532bea128cSEddie James aspeed_soc_get_irq(s, ASPEED_SDHCI)); 45443e3346eSAndrew Jeffery } 455ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 45695b56e17SCédric Le Goater DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, 45795b56e17SCédric Le Goater MemoryRegion *), 458ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 459ece09beeSCédric Le Goater }; 46043e3346eSAndrew Jeffery 461ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 46243e3346eSAndrew Jeffery { 46343e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 46443e3346eSAndrew Jeffery 465ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 466469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 467469f3da4SThomas Huth dc->user_creatable = false; 4684f67d30bSMarc-André Lureau device_class_set_props(dc, aspeed_soc_properties); 46943e3346eSAndrew Jeffery } 47043e3346eSAndrew Jeffery 471ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 472ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 473b033271fSCédric Le Goater .parent = TYPE_DEVICE, 474b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 475b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 47654ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 477b033271fSCédric Le Goater .abstract = true, 47843e3346eSAndrew Jeffery }; 47943e3346eSAndrew Jeffery 48054ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 48154ecafb7SCédric Le Goater { 48254ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 48354ecafb7SCédric Le Goater 48454ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 48554ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 48654ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 48754ecafb7SCédric Le Goater sc->sram_size = 0x8000; 48854ecafb7SCédric Le Goater sc->spis_num = 1; 489bfdd34f1SGuenter Roeck sc->ehcis_num = 1; 49054ecafb7SCédric Le Goater sc->wdts_num = 2; 491d300db02SJoel Stanley sc->macs_num = 2; 49254ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 49354ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 49454ecafb7SCédric Le Goater sc->num_cpus = 1; 49554ecafb7SCédric Le Goater } 49654ecafb7SCédric Le Goater 49754ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 49854ecafb7SCédric Le Goater .name = "ast2400-a1", 49954ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 50054ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 50154ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 50254ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 50354ecafb7SCédric Le Goater }; 50454ecafb7SCédric Le Goater 50554ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 50654ecafb7SCédric Le Goater { 50754ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 50854ecafb7SCédric Le Goater 50954ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 51054ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 51154ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 51254ecafb7SCédric Le Goater sc->sram_size = 0x9000; 51354ecafb7SCédric Le Goater sc->spis_num = 2; 514bfdd34f1SGuenter Roeck sc->ehcis_num = 2; 51554ecafb7SCédric Le Goater sc->wdts_num = 3; 516d300db02SJoel Stanley sc->macs_num = 2; 51754ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 51854ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 51954ecafb7SCédric Le Goater sc->num_cpus = 1; 52054ecafb7SCédric Le Goater } 52154ecafb7SCédric Le Goater 52254ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 52354ecafb7SCédric Le Goater .name = "ast2500-a1", 52454ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 52554ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 52654ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 52754ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 52854ecafb7SCédric Le Goater }; 529ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 53043e3346eSAndrew Jeffery { 531ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 53254ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 53354ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 534b033271fSCédric Le Goater }; 53543e3346eSAndrew Jeffery 536ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 537