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, 33d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 34d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 35d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 36118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 37d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 38d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 392bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 40d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 41d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 42d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 43d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 44d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 45d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 46d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 47d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 48d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 49d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 50d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 51d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 52d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 53d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x40000000, 54d783d1feSCédric Le Goater }; 55d783d1feSCédric Le Goater 56d783d1feSCédric Le Goater static const hwaddr aspeed_soc_ast2500_memmap[] = { 57d783d1feSCédric Le Goater [ASPEED_IOMEM] = 0x1E600000, 58d783d1feSCédric Le Goater [ASPEED_FMC] = 0x1E620000, 59d783d1feSCédric Le Goater [ASPEED_SPI1] = 0x1E630000, 60d783d1feSCédric Le Goater [ASPEED_SPI2] = 0x1E631000, 61d783d1feSCédric Le Goater [ASPEED_VIC] = 0x1E6C0000, 62d783d1feSCédric Le Goater [ASPEED_SDMC] = 0x1E6E0000, 63d783d1feSCédric Le Goater [ASPEED_SCU] = 0x1E6E2000, 64118c82e7SEddie James [ASPEED_XDMA] = 0x1E6E7000, 65d783d1feSCédric Le Goater [ASPEED_ADC] = 0x1E6E9000, 66d783d1feSCédric Le Goater [ASPEED_SRAM] = 0x1E720000, 672bea128cSEddie James [ASPEED_SDHCI] = 0x1E740000, 68d783d1feSCédric Le Goater [ASPEED_GPIO] = 0x1E780000, 69d783d1feSCédric Le Goater [ASPEED_RTC] = 0x1E781000, 70d783d1feSCédric Le Goater [ASPEED_TIMER1] = 0x1E782000, 71d783d1feSCédric Le Goater [ASPEED_WDT] = 0x1E785000, 72d783d1feSCédric Le Goater [ASPEED_PWM] = 0x1E786000, 73d783d1feSCédric Le Goater [ASPEED_LPC] = 0x1E789000, 74d783d1feSCédric Le Goater [ASPEED_IBT] = 0x1E789140, 75d783d1feSCédric Le Goater [ASPEED_I2C] = 0x1E78A000, 76d783d1feSCédric Le Goater [ASPEED_ETH1] = 0x1E660000, 77d783d1feSCédric Le Goater [ASPEED_ETH2] = 0x1E680000, 78d783d1feSCédric Le Goater [ASPEED_UART1] = 0x1E783000, 79d783d1feSCédric Le Goater [ASPEED_UART5] = 0x1E784000, 80d783d1feSCédric Le Goater [ASPEED_VUART] = 0x1E787000, 81d783d1feSCédric Le Goater [ASPEED_SDRAM] = 0x80000000, 82d783d1feSCédric Le Goater }; 8343e3346eSAndrew Jeffery 84b456b113SCédric Le Goater static const int aspeed_soc_ast2400_irqmap[] = { 85b456b113SCédric Le Goater [ASPEED_UART1] = 9, 86b456b113SCédric Le Goater [ASPEED_UART2] = 32, 87b456b113SCédric Le Goater [ASPEED_UART3] = 33, 88b456b113SCédric Le Goater [ASPEED_UART4] = 34, 89b456b113SCédric Le Goater [ASPEED_UART5] = 10, 90b456b113SCédric Le Goater [ASPEED_VUART] = 8, 91b456b113SCédric Le Goater [ASPEED_FMC] = 19, 92b456b113SCédric Le Goater [ASPEED_SDMC] = 0, 93b456b113SCédric Le Goater [ASPEED_SCU] = 21, 94b456b113SCédric Le Goater [ASPEED_ADC] = 31, 95b456b113SCédric Le Goater [ASPEED_GPIO] = 20, 96b456b113SCédric Le Goater [ASPEED_RTC] = 22, 97b456b113SCédric Le Goater [ASPEED_TIMER1] = 16, 98b456b113SCédric Le Goater [ASPEED_TIMER2] = 17, 99b456b113SCédric Le Goater [ASPEED_TIMER3] = 18, 100b456b113SCédric Le Goater [ASPEED_TIMER4] = 35, 101b456b113SCédric Le Goater [ASPEED_TIMER5] = 36, 102b456b113SCédric Le Goater [ASPEED_TIMER6] = 37, 103b456b113SCédric Le Goater [ASPEED_TIMER7] = 38, 104b456b113SCédric Le Goater [ASPEED_TIMER8] = 39, 105b456b113SCédric Le Goater [ASPEED_WDT] = 27, 106b456b113SCédric Le Goater [ASPEED_PWM] = 28, 107b456b113SCédric Le Goater [ASPEED_LPC] = 8, 108b456b113SCédric Le Goater [ASPEED_IBT] = 8, /* LPC */ 109b456b113SCédric Le Goater [ASPEED_I2C] = 12, 110b456b113SCédric Le Goater [ASPEED_ETH1] = 2, 111b456b113SCédric Le Goater [ASPEED_ETH2] = 3, 112118c82e7SEddie James [ASPEED_XDMA] = 6, 1132bea128cSEddie James [ASPEED_SDHCI] = 26, 114b456b113SCédric Le Goater }; 11543e3346eSAndrew Jeffery 116b456b113SCédric Le Goater #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap 117b456b113SCédric Le Goater 118b456b113SCédric Le Goater static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) 119b456b113SCédric Le Goater { 120b456b113SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 121b456b113SCédric Le Goater 12254ecafb7SCédric Le Goater return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]); 123b456b113SCédric Le Goater } 124b456b113SCédric Le Goater 125ff90606fSCédric Le Goater static void aspeed_soc_init(Object *obj) 12643e3346eSAndrew Jeffery { 127ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(obj); 128b033271fSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 129dbcabeebSCédric Le Goater int i; 130811a5b1dSCédric Le Goater char socname[8]; 131811a5b1dSCédric Le Goater char typename[64]; 132811a5b1dSCédric Le Goater 13354ecafb7SCédric Le Goater if (sscanf(sc->name, "%7s", socname) != 1) { 134811a5b1dSCédric Le Goater g_assert_not_reached(); 135811a5b1dSCédric Le Goater } 13643e3346eSAndrew Jeffery 13754ecafb7SCédric Le Goater for (i = 0; i < sc->num_cpus; i++) { 138ece09beeSCédric Le Goater object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]), 13954ecafb7SCédric Le Goater sizeof(s->cpu[i]), sc->cpu_type, 140ece09beeSCédric Le Goater &error_abort, NULL); 141ece09beeSCédric Le Goater } 14243e3346eSAndrew Jeffery 1439a937f6cSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname); 1441b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu), 1459a937f6cSCédric Le Goater typename); 146334973bbSAndrew Jeffery qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", 14754ecafb7SCédric Le Goater sc->silicon_rev); 148334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), 149334973bbSAndrew Jeffery "hw-strap1", &error_abort); 150334973bbSAndrew Jeffery object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), 151334973bbSAndrew Jeffery "hw-strap2", &error_abort); 152b6e70d1dSJoel Stanley object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), 153b6e70d1dSJoel Stanley "hw-prot-key", &error_abort); 1547c1c69bcSCédric Le Goater 1551b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic), 1561b0ad567SPhilippe Mathieu-Daudé TYPE_ASPEED_VIC); 157e2a11ca8SCédric Le Goater 15875fb4577SJoel Stanley sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc), 15975fb4577SJoel Stanley TYPE_ASPEED_RTC); 16075fb4577SJoel Stanley 16172d96f8eSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname); 1621b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl), 16372d96f8eSCédric Le Goater sizeof(s->timerctrl), typename); 1649b945a9eSCédric Le Goater object_property_add_const_link(OBJECT(&s->timerctrl), "scu", 1659b945a9eSCédric Le Goater OBJECT(&s->scu), &error_abort); 166e2a11ca8SCédric Le Goater 167f7da1aa8SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname); 1681b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c), 169f7da1aa8SCédric Le Goater typename); 170e2a11ca8SCédric Le Goater 171811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname); 1721b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc), 173811a5b1dSCédric Le Goater typename); 17426d5df95SCédric Le Goater object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", 17526d5df95SCédric Le Goater &error_abort); 176c4e1f0b4SCédric Le Goater object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram", 177c4e1f0b4SCédric Le Goater &error_abort); 1787c1c69bcSCédric Le Goater 17954ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 180811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname); 1811b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]), 182811a5b1dSCédric Le Goater sizeof(s->spi[i]), typename); 183dbcabeebSCédric Le Goater } 184c2da8a8bSCédric Le Goater 1858e00d1a9SCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); 1861b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc), 1878e00d1a9SCédric Le Goater typename); 188c6c7cfb0SCédric Le Goater object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), 189c6c7cfb0SCédric Le Goater "ram-size", &error_abort); 190ebe31c0aSCédric Le Goater object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc), 191ebe31c0aSCédric Le Goater "max-ram-size", &error_abort); 192013befe1SCédric Le Goater 19354ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 1946112bd6dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname); 1951b0ad567SPhilippe Mathieu-Daudé sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]), 1966112bd6dSCédric Le Goater sizeof(s->wdt[i]), typename); 1973059c2f5SJoel Stanley object_property_add_const_link(OBJECT(&s->wdt[i]), "scu", 1983059c2f5SJoel Stanley OBJECT(&s->scu), &error_abort); 199f986ee1dSJoel Stanley } 200ea337c65SCédric Le Goater 20167340990SCédric Le Goater for (i = 0; i < ASPEED_MACS_NUM; i++) { 20267340990SCédric Le Goater sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]), 20367340990SCédric Le Goater sizeof(s->ftgmac100[i]), TYPE_FTGMAC100); 20467340990SCédric Le Goater } 205118c82e7SEddie James 206118c82e7SEddie James sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma), 207118c82e7SEddie James TYPE_ASPEED_XDMA); 208fdcc7c06SRashmica Gupta 209811a5b1dSCédric Le Goater snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); 210fdcc7c06SRashmica Gupta sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio), 211811a5b1dSCédric Le Goater typename); 2122bea128cSEddie James 2132bea128cSEddie James sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci), 2142bea128cSEddie James TYPE_ASPEED_SDHCI); 2152bea128cSEddie James 2162bea128cSEddie James /* Init sd card slot class here so that they're under the correct parent */ 2172bea128cSEddie James for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) { 2182bea128cSEddie James sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]), 2192bea128cSEddie James sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI); 2202bea128cSEddie James } 22143e3346eSAndrew Jeffery } 22243e3346eSAndrew Jeffery 223ff90606fSCédric Le Goater static void aspeed_soc_realize(DeviceState *dev, Error **errp) 22443e3346eSAndrew Jeffery { 22543e3346eSAndrew Jeffery int i; 226ff90606fSCédric Le Goater AspeedSoCState *s = ASPEED_SOC(dev); 227dbcabeebSCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); 2287c1c69bcSCédric Le Goater Error *err = NULL, *local_err = NULL; 22943e3346eSAndrew Jeffery 23043e3346eSAndrew Jeffery /* IO space */ 23154ecafb7SCédric Le Goater create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM], 232d783d1feSCédric Le Goater ASPEED_SOC_IOMEM_SIZE); 23343e3346eSAndrew Jeffery 23454ecafb7SCédric Le Goater if (s->num_cpus > sc->num_cpus) { 235ece09beeSCédric Le Goater warn_report("%s: invalid number of CPUs %d, using default %d", 23654ecafb7SCédric Le Goater sc->name, s->num_cpus, sc->num_cpus); 23754ecafb7SCédric Le Goater s->num_cpus = sc->num_cpus; 238ece09beeSCédric Le Goater } 239ece09beeSCédric Le Goater 2402d105bd6SCédric Le Goater /* CPU */ 241ece09beeSCédric Le Goater for (i = 0; i < s->num_cpus; i++) { 242ece09beeSCédric Le Goater object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err); 2432d105bd6SCédric Le Goater if (err) { 2442d105bd6SCédric Le Goater error_propagate(errp, err); 2452d105bd6SCédric Le Goater return; 2462d105bd6SCédric Le Goater } 247ece09beeSCédric Le Goater } 2482d105bd6SCédric Le Goater 24974af4eecSCédric Le Goater /* SRAM */ 250a2e9989cSPeter Maydell memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", 25154ecafb7SCédric Le Goater sc->sram_size, &err); 25274af4eecSCédric Le Goater if (err) { 25374af4eecSCédric Le Goater error_propagate(errp, err); 25474af4eecSCédric Le Goater return; 25574af4eecSCédric Le Goater } 256d783d1feSCédric Le Goater memory_region_add_subregion(get_system_memory(), 25754ecafb7SCédric Le Goater sc->memmap[ASPEED_SRAM], &s->sram); 25874af4eecSCédric Le Goater 259e2a11ca8SCédric Le Goater /* SCU */ 260e2a11ca8SCédric Le Goater object_property_set_bool(OBJECT(&s->scu), true, "realized", &err); 261e2a11ca8SCédric Le Goater if (err) { 262e2a11ca8SCédric Le Goater error_propagate(errp, err); 263e2a11ca8SCédric Le Goater return; 264e2a11ca8SCédric Le Goater } 26554ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_SCU]); 266e2a11ca8SCédric Le Goater 26743e3346eSAndrew Jeffery /* VIC */ 26843e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); 26943e3346eSAndrew Jeffery if (err) { 27043e3346eSAndrew Jeffery error_propagate(errp, err); 27143e3346eSAndrew Jeffery return; 27243e3346eSAndrew Jeffery } 27354ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_VIC]); 27443e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, 2752d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 27643e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, 2772d105bd6SCédric Le Goater qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 27843e3346eSAndrew Jeffery 27975fb4577SJoel Stanley /* RTC */ 28075fb4577SJoel Stanley object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err); 28175fb4577SJoel Stanley if (err) { 28275fb4577SJoel Stanley error_propagate(errp, err); 28375fb4577SJoel Stanley return; 28475fb4577SJoel Stanley } 28554ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_RTC]); 28675fb4577SJoel Stanley sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, 28775fb4577SJoel Stanley aspeed_soc_get_irq(s, ASPEED_RTC)); 28875fb4577SJoel Stanley 28943e3346eSAndrew Jeffery /* Timer */ 29043e3346eSAndrew Jeffery object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); 29143e3346eSAndrew Jeffery if (err) { 29243e3346eSAndrew Jeffery error_propagate(errp, err); 29343e3346eSAndrew Jeffery return; 29443e3346eSAndrew Jeffery } 295d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, 29654ecafb7SCédric Le Goater sc->memmap[ASPEED_TIMER1]); 297b456b113SCédric Le Goater for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 298b456b113SCédric Le Goater qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i); 29943e3346eSAndrew Jeffery sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq); 30043e3346eSAndrew Jeffery } 30143e3346eSAndrew Jeffery 30243e3346eSAndrew Jeffery /* UART - attach an 8250 to the IO space as our UART5 */ 3039bca0edbSPeter Maydell if (serial_hd(0)) { 304b456b113SCédric Le Goater qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5); 30554ecafb7SCédric Le Goater serial_mm_init(get_system_memory(), sc->memmap[ASPEED_UART5], 2, 3069bca0edbSPeter Maydell uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN); 30743e3346eSAndrew Jeffery } 30816020011SCédric Le Goater 30916020011SCédric Le Goater /* I2C */ 31016020011SCédric Le Goater object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err); 31116020011SCédric Le Goater if (err) { 31216020011SCédric Le Goater error_propagate(errp, err); 31316020011SCédric Le Goater return; 31416020011SCédric Le Goater } 31554ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_I2C]); 31616020011SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, 317b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_I2C)); 3187c1c69bcSCédric Le Goater 31926d5df95SCédric Le Goater /* FMC, The number of CS is set at the board level */ 32054ecafb7SCédric Le Goater object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM], 3216da4433fSCédric Le Goater "sdram-base", &err); 3226da4433fSCédric Le Goater if (err) { 3236da4433fSCédric Le Goater error_propagate(errp, err); 3246da4433fSCédric Le Goater return; 3256da4433fSCédric Le Goater } 32626d5df95SCédric Le Goater object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); 3277c1c69bcSCédric Le Goater if (err) { 3287c1c69bcSCédric Le Goater error_propagate(errp, err); 3297c1c69bcSCédric Le Goater return; 3307c1c69bcSCédric Le Goater } 33154ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_FMC]); 332dcb83444SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1, 333dcb83444SCédric Le Goater s->fmc.ctrl->flash_window_base); 3340e5803dfSCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0, 335b456b113SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_FMC)); 3367c1c69bcSCédric Le Goater 3377c1c69bcSCédric Le Goater /* SPI */ 33854ecafb7SCédric Le Goater for (i = 0; i < sc->spis_num; i++) { 339dbcabeebSCédric Le Goater object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err); 340dbcabeebSCédric Le Goater object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 341dbcabeebSCédric Le Goater &local_err); 3427c1c69bcSCédric Le Goater error_propagate(&err, local_err); 3437c1c69bcSCédric Le Goater if (err) { 3447c1c69bcSCédric Le Goater error_propagate(errp, err); 3457c1c69bcSCédric Le Goater return; 3467c1c69bcSCédric Le Goater } 347d783d1feSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 34854ecafb7SCédric Le Goater sc->memmap[ASPEED_SPI1 + i]); 349dbcabeebSCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1, 350dbcabeebSCédric Le Goater s->spi[i].ctrl->flash_window_base); 351dbcabeebSCédric Le Goater } 352c2da8a8bSCédric Le Goater 353c2da8a8bSCédric Le Goater /* SDMC - SDRAM Memory Controller */ 354c2da8a8bSCédric Le Goater object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err); 355c2da8a8bSCédric Le Goater if (err) { 356c2da8a8bSCédric Le Goater error_propagate(errp, err); 357c2da8a8bSCédric Le Goater return; 358c2da8a8bSCédric Le Goater } 35954ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_SDMC]); 360013befe1SCédric Le Goater 361013befe1SCédric Le Goater /* Watch dog */ 36254ecafb7SCédric Le Goater for (i = 0; i < sc->wdts_num; i++) { 3636112bd6dSCédric Le Goater AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); 3646112bd6dSCédric Le Goater 365f986ee1dSJoel Stanley object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err); 366013befe1SCédric Le Goater if (err) { 367013befe1SCédric Le Goater error_propagate(errp, err); 368013befe1SCédric Le Goater return; 369013befe1SCédric Le Goater } 370f986ee1dSJoel Stanley sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 37154ecafb7SCédric Le Goater sc->memmap[ASPEED_WDT] + i * awc->offset); 372f986ee1dSJoel Stanley } 373ea337c65SCédric Le Goater 374ea337c65SCédric Le Goater /* Net */ 37567340990SCédric Le Goater for (i = 0; i < nb_nics; i++) { 37667340990SCédric Le Goater qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]); 37767340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed", 37867340990SCédric Le Goater &err); 37967340990SCédric Le Goater object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized", 380ea337c65SCédric Le Goater &local_err); 381ea337c65SCédric Le Goater error_propagate(&err, local_err); 382ea337c65SCédric Le Goater if (err) { 383ea337c65SCédric Le Goater error_propagate(errp, err); 384ea337c65SCédric Le Goater return; 385ea337c65SCédric Le Goater } 38667340990SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 38754ecafb7SCédric Le Goater sc->memmap[ASPEED_ETH1 + i]); 38867340990SCédric Le Goater sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0, 38967340990SCédric Le Goater aspeed_soc_get_irq(s, ASPEED_ETH1 + i)); 39067340990SCédric Le Goater } 391118c82e7SEddie James 392118c82e7SEddie James /* XDMA */ 393118c82e7SEddie James object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err); 394118c82e7SEddie James if (err) { 395118c82e7SEddie James error_propagate(errp, err); 396118c82e7SEddie James return; 397118c82e7SEddie James } 398118c82e7SEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0, 39954ecafb7SCédric Le Goater sc->memmap[ASPEED_XDMA]); 400118c82e7SEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0, 401118c82e7SEddie James aspeed_soc_get_irq(s, ASPEED_XDMA)); 402fdcc7c06SRashmica Gupta 403fdcc7c06SRashmica Gupta /* GPIO */ 404fdcc7c06SRashmica Gupta object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err); 405fdcc7c06SRashmica Gupta if (err) { 406fdcc7c06SRashmica Gupta error_propagate(errp, err); 407fdcc7c06SRashmica Gupta return; 408fdcc7c06SRashmica Gupta } 40954ecafb7SCédric Le Goater sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_GPIO]); 410fdcc7c06SRashmica Gupta sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, 411fdcc7c06SRashmica Gupta aspeed_soc_get_irq(s, ASPEED_GPIO)); 4122bea128cSEddie James 4132bea128cSEddie James /* SDHCI */ 4142bea128cSEddie James object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err); 4152bea128cSEddie James if (err) { 4162bea128cSEddie James error_propagate(errp, err); 4172bea128cSEddie James return; 4182bea128cSEddie James } 4192bea128cSEddie James sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0, 42054ecafb7SCédric Le Goater sc->memmap[ASPEED_SDHCI]); 4212bea128cSEddie James sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, 4222bea128cSEddie James aspeed_soc_get_irq(s, ASPEED_SDHCI)); 42343e3346eSAndrew Jeffery } 424ece09beeSCédric Le Goater static Property aspeed_soc_properties[] = { 425ece09beeSCédric Le Goater DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0), 426ece09beeSCédric Le Goater DEFINE_PROP_END_OF_LIST(), 427ece09beeSCédric Le Goater }; 42843e3346eSAndrew Jeffery 429ff90606fSCédric Le Goater static void aspeed_soc_class_init(ObjectClass *oc, void *data) 43043e3346eSAndrew Jeffery { 43143e3346eSAndrew Jeffery DeviceClass *dc = DEVICE_CLASS(oc); 43243e3346eSAndrew Jeffery 433ff90606fSCédric Le Goater dc->realize = aspeed_soc_realize; 434469f3da4SThomas Huth /* Reason: Uses serial_hds and nd_table in realize() directly */ 435469f3da4SThomas Huth dc->user_creatable = false; 436ece09beeSCédric Le Goater dc->props = aspeed_soc_properties; 43743e3346eSAndrew Jeffery } 43843e3346eSAndrew Jeffery 439ff90606fSCédric Le Goater static const TypeInfo aspeed_soc_type_info = { 440ff90606fSCédric Le Goater .name = TYPE_ASPEED_SOC, 441b033271fSCédric Le Goater .parent = TYPE_DEVICE, 442b033271fSCédric Le Goater .instance_size = sizeof(AspeedSoCState), 443b033271fSCédric Le Goater .class_size = sizeof(AspeedSoCClass), 44454ecafb7SCédric Le Goater .class_init = aspeed_soc_class_init, 445b033271fSCédric Le Goater .abstract = true, 44643e3346eSAndrew Jeffery }; 44743e3346eSAndrew Jeffery 44854ecafb7SCédric Le Goater static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) 44954ecafb7SCédric Le Goater { 45054ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 45154ecafb7SCédric Le Goater 45254ecafb7SCédric Le Goater sc->name = "ast2400-a1"; 45354ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm926"); 45454ecafb7SCédric Le Goater sc->silicon_rev = AST2400_A1_SILICON_REV; 45554ecafb7SCédric Le Goater sc->sram_size = 0x8000; 45654ecafb7SCédric Le Goater sc->spis_num = 1; 45754ecafb7SCédric Le Goater sc->wdts_num = 2; 45854ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2400_irqmap; 45954ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2400_memmap; 46054ecafb7SCédric Le Goater sc->num_cpus = 1; 46154ecafb7SCédric Le Goater } 46254ecafb7SCédric Le Goater 46354ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2400_type_info = { 46454ecafb7SCédric Le Goater .name = "ast2400-a1", 46554ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 46654ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 46754ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 46854ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2400_class_init, 46954ecafb7SCédric Le Goater }; 47054ecafb7SCédric Le Goater 47154ecafb7SCédric Le Goater static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) 47254ecafb7SCédric Le Goater { 47354ecafb7SCédric Le Goater AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); 47454ecafb7SCédric Le Goater 47554ecafb7SCédric Le Goater sc->name = "ast2500-a1"; 47654ecafb7SCédric Le Goater sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176"); 47754ecafb7SCédric Le Goater sc->silicon_rev = AST2500_A1_SILICON_REV; 47854ecafb7SCédric Le Goater sc->sram_size = 0x9000; 47954ecafb7SCédric Le Goater sc->spis_num = 2; 48054ecafb7SCédric Le Goater sc->wdts_num = 3; 48154ecafb7SCédric Le Goater sc->irqmap = aspeed_soc_ast2500_irqmap; 48254ecafb7SCédric Le Goater sc->memmap = aspeed_soc_ast2500_memmap; 48354ecafb7SCédric Le Goater sc->num_cpus = 1; 48454ecafb7SCédric Le Goater } 48554ecafb7SCédric Le Goater 48654ecafb7SCédric Le Goater static const TypeInfo aspeed_soc_ast2500_type_info = { 48754ecafb7SCédric Le Goater .name = "ast2500-a1", 48854ecafb7SCédric Le Goater .parent = TYPE_ASPEED_SOC, 48954ecafb7SCédric Le Goater .instance_init = aspeed_soc_init, 49054ecafb7SCédric Le Goater .instance_size = sizeof(AspeedSoCState), 49154ecafb7SCédric Le Goater .class_init = aspeed_soc_ast2500_class_init, 49254ecafb7SCédric Le Goater }; 493ff90606fSCédric Le Goater static void aspeed_soc_register_types(void) 49443e3346eSAndrew Jeffery { 495ff90606fSCédric Le Goater type_register_static(&aspeed_soc_type_info); 49654ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2400_type_info); 49754ecafb7SCédric Le Goater type_register_static(&aspeed_soc_ast2500_type_info); 498b033271fSCédric Le Goater }; 49943e3346eSAndrew Jeffery 500ff90606fSCédric Le Goater type_init(aspeed_soc_register_types) 501