x86: serial: Add a coreboot serial driver
authorSimon Glass <sjg@chromium.org>
Fri, 20 Dec 2019 00:58:20 +0000 (17:58 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Mon, 3 Feb 2020 17:19:25 +0000 (01:19 +0800)
Coreboot can provide information about the serial device in use on a
platform. Add a driver that uses this information to produce a working
UART.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/serial_coreboot.c [new file with mode: 0644]

index 1147654082efbc1c062e1d3301121c2a882a65db..cd2e098883f7acc2bf67c4f4088f8a72e7807f12 100644 (file)
@@ -542,6 +542,17 @@ config BCM6345_SERIAL
        help
          Select this to enable UART on BCM6345 SoCs.
 
+config COREBOOT_SERIAL
+       bool "Coreboot UART support"
+       depends on DM_SERIAL
+       default y if SYS_COREBOOT
+       select SYS_NS16550
+       help
+         Select this to enable a ns16550-style UART where the platform data
+         comes from the coreboot 'sysinfo' tables. This allows U-Boot to have
+         a serial console on any platform without needing to change the
+         device tree, etc.
+
 config FSL_LINFLEXUART
        bool "Freescale Linflex UART support"
        depends on DM_SERIAL
index 06ee30697deb0d5e486ba0f155a99327b7623ac5..76b1811510d138b075b722125cc2f11e86b7bcad 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
 obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
+obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
 obj-$(CONFIG_EFI_APP) += serial_efi.o
 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
 obj-$(CONFIG_MCFUART) += mcfuart.o
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644 (file)
index 0000000..ccab347
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * UART support for U-Boot when launched from Coreboot
+ *
+ * Copyright 2019 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+#include <asm/arch/sysinfo.h>
+
+static int coreboot_ofdata_to_platdata(struct udevice *dev)
+{
+       struct ns16550_platdata *plat = dev_get_platdata(dev);
+       struct cb_serial *cb_info = lib_sysinfo.serial;
+
+       plat->base = cb_info->baseaddr;
+       plat->reg_shift = cb_info->regwidth == 4 ? 2 : 0;
+       plat->reg_width = cb_info->regwidth;
+       plat->clock = cb_info->input_hertz;
+       plat->fcr = UART_FCR_DEFVAL;
+       plat->flags = 0;
+       if (cb_info->type == CB_SERIAL_TYPE_IO_MAPPED)
+               plat->flags |= NS16550_FLAG_IO;
+
+       return 0;
+}
+
+static const struct udevice_id coreboot_serial_ids[] = {
+       { .compatible = "coreboot-serial" },
+       { },
+};
+
+U_BOOT_DRIVER(coreboot_uart) = {
+       .name   = "coreboot_uart",
+       .id     = UCLASS_SERIAL,
+       .of_match       = coreboot_serial_ids,
+       .priv_auto_alloc_size = sizeof(struct NS16550),
+       .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+       .ofdata_to_platdata  = coreboot_ofdata_to_platdata,
+       .probe  = ns16550_serial_probe,
+       .ops    = &ns16550_serial_ops,
+       .flags  = DM_FLAG_PRE_RELOC,
+};