From d2b3eaefb4d7ae274ff85001f03d8b1a87ea3a7f Mon Sep 17 00:00:00 2001 From: Peter Delevoryas Date: Thu, 14 Jul 2022 16:24:38 +0200 Subject: aspeed: Refactor UART init for multi-SoC machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change moves the code that connects the SoC UART's to serial_hd's to the machine. It makes each UART a proper child member of the SoC, and then allows the machine to selectively initialize the chardev for each UART with a serial_hd. This should preserve backwards compatibility, but also allow multi-SoC boards to completely change the wiring of serial devices from the command line to specific SoC UART's. This also removes the uart-default property from the SoC, since the SoC doesn't need to know what UART is the "default" on the machine anymore. I tested this using the images and commands from the previous refactoring, and another test image for the ast1030: wget https://github.com/facebook/openbmc/releases/download/v2021.49.0/fuji.mtd wget https://github.com/facebook/openbmc/releases/download/v2021.49.0/wedge100.mtd wget https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.13.01/Y35BCL.elf Fuji uses UART1: qemu-system-arm -machine fuji-bmc \ -drive file=fuji.mtd,format=raw,if=mtd \ -nographic ast2600-evb uses uart-default=UART5: qemu-system-arm -machine ast2600-evb \ -drive file=fuji.mtd,format=raw,if=mtd \ -serial null -serial mon:stdio -display none Wedge100 uses UART3: qemu-system-arm -machine palmetto-bmc \ -drive file=wedge100.mtd,format=raw,if=mtd \ -serial null -serial null -serial null \ -serial mon:stdio -display none AST1030 EVB uses UART5: qemu-system-arm -machine ast1030-evb \ -kernel Y35BCL.elf -nographic Fixes: 6827ff20b2975 ("hw: aspeed: Init all UART's with serial devices") Signed-off-by: Peter Delevoryas Reviewed-by: Cédric Le Goater Message-Id: <20220705191400.41632-4-peter@pjd.dev> Signed-off-by: Cédric Le Goater --- hw/arm/aspeed_soc.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'hw/arm/aspeed_soc.c') diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index 0bb6a2f092..b05b9dd416 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -208,6 +208,10 @@ static void aspeed_soc_init(Object *obj) TYPE_FTGMAC100); } + for (i = 0; i < sc->uarts_num; i++) { + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM); + } + snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname); object_initialize_child(obj, "xdma", &s->xdma, typename); @@ -315,7 +319,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) aspeed_soc_get_irq(s, ASPEED_DEV_ADC)); /* UART */ - aspeed_soc_uart_init(s); + if (!aspeed_soc_uart_realize(s, errp)) { + return; + } /* I2C */ object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr), @@ -482,8 +488,6 @@ static Property aspeed_soc_properties[] = { MemoryRegion *), DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION, MemoryRegion *), - DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default, - ASPEED_DEV_UART5), DEFINE_PROP_END_OF_LIST(), }; @@ -573,23 +577,37 @@ qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev) return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev); } -void aspeed_soc_uart_init(AspeedSoCState *s) +bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp) { AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); - int i, uart; - - /* Attach an 8250 to the IO space as our UART */ - serial_mm_init(s->memory, sc->memmap[s->uart_default], 2, - aspeed_soc_get_irq(s, s->uart_default), 38400, - serial_hd(0), DEVICE_LITTLE_ENDIAN); - for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) { - if (uart == s->uart_default) { - uart++; + SerialMM *smm; + + for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) { + smm = &s->uart[i]; + + /* Chardev property is set by the machine. */ + qdev_prop_set_uint8(DEVICE(smm), "regshift", 2); + qdev_prop_set_uint32(DEVICE(smm), "baudbase", 38400); + qdev_set_legacy_instance_id(DEVICE(smm), sc->memmap[uart], 2); + qdev_prop_set_uint8(DEVICE(smm), "endianness", DEVICE_LITTLE_ENDIAN); + if (!sysbus_realize(SYS_BUS_DEVICE(smm), errp)) { + return false; } - serial_mm_init(s->memory, sc->memmap[uart], 2, - aspeed_soc_get_irq(s, uart), 38400, - serial_hd(i), DEVICE_LITTLE_ENDIAN); + + sysbus_connect_irq(SYS_BUS_DEVICE(smm), 0, aspeed_soc_get_irq(s, uart)); + aspeed_mmio_map(s, SYS_BUS_DEVICE(smm), 0, sc->memmap[uart]); } + + return true; +} + +void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr) +{ + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + int i = dev - ASPEED_DEV_UART1; + + g_assert(0 <= i && i < ARRAY_SIZE(s->uart) && i < sc->uarts_num); + qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr); } /* -- cgit 1.4.1