summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-02-04 11:36:49 -0500
committerTom Rini <trini@konsulko.com>2020-02-04 11:36:49 -0500
commitd4827fcd4c1b04c338e4019e412f495aa4231d24 (patch)
treeec6d55971a72f39069ed66a7ca836bdbead324bc /drivers
parentd861183dc531b74479f92bf4c8de8ad60a0a0d56 (diff)
parent9e0c131a32028547cc4834f238c614af2675c66d (diff)
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-x86
- Various minor fixes for x86 - Switch to ACPI mode on Intel edison - Support run-time configuration for NS16550 driver - Update coreboot and slimbootloader serial drivers to use NS16550 run-time configuration - ICH SPI driver fixes to hardware sequencing erase case - Move ITSS from Apollo Lake to a more generic location - Intel GPIO driver bug fixes - Move to vs2017-win2016 platform build host for Azure pipelines
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/intel_gpio.c10
-rw-r--r--drivers/pinctrl/intel/pinctrl.c2
-rw-r--r--drivers/serial/Kconfig32
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/ns16550.c79
-rw-r--r--drivers/serial/serial_coreboot.c46
-rw-r--r--drivers/spi/ich.c12
7 files changed, 158 insertions, 24 deletions
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index 4bf1c9ddc4..67b8b80b9d 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -39,9 +39,9 @@ static int intel_gpio_direction_output(struct udevice *dev, uint offset,
struct udevice *pinctrl = dev_get_parent(dev);
uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
- pcr_clrsetbits32(dev, config_offset,
+ pcr_clrsetbits32(pinctrl, config_offset,
PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
- PAD_CFG0_TX_DISABLE,
+ PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
(value ? PAD_CFG0_TX_STATE : 0));
@@ -59,9 +59,9 @@ static int intel_gpio_get_value(struct udevice *dev, uint offset)
if (!mode) {
rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE);
if (rx_tx == PAD_CFG0_TX_DISABLE)
- return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0;
+ return reg & PAD_CFG0_RX_STATE ? 1 : 0;
else if (rx_tx == PAD_CFG0_RX_DISABLE)
- return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0;
+ return reg & PAD_CFG0_TX_STATE ? 1 : 0;
}
return 0;
@@ -72,7 +72,7 @@ static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int value)
struct udevice *pinctrl = dev_get_parent(dev);
uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset);
- pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE,
+ pcr_clrsetbits32(pinctrl, config_offset, PAD_CFG0_TX_STATE,
value ? PAD_CFG0_TX_STATE : 0);
return 0;
diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c
index 4875a3b0b5..5bf5d8b0e2 100644
--- a/drivers/pinctrl/intel/pinctrl.c
+++ b/drivers/pinctrl/intel/pinctrl.c
@@ -25,7 +25,7 @@
#include <asm/intel_pinctrl.h>
#include <asm/intel_pinctrl_defs.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/itss.h>
+#include <asm/itss.h>
#include <dm/device-internal.h>
#include <dt-bindings/gpio/gpio.h>
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index bd95f70b61..cd2e098883 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -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
@@ -601,6 +612,27 @@ config SYS_NS16550
be used. It can be a constant or a function to get clock, eg,
get_serial_clock().
+config NS16550_DYNAMIC
+ bool "Allow NS16550 to be configured at runtime"
+ default y if SYS_COREBOOT || SYS_SLIMBOOTLOADER
+ help
+ Enable this option to allow device-tree control of the driver.
+
+ Normally this driver is controlled by the following options:
+
+ CONFIG_SYS_NS16550_PORT_MAPPED - indicates that port I/O is used for
+ access. If not enabled, then the UART is memory-mapped.
+ CONFIG_SYS_NS16550_MEM32 - if memory-mapped, indicates that 32-bit
+ access should be used (instead of 8-bit)
+ CONFIG_SYS_NS16550_REG_SIZE - indicates register width and also
+ endianness. If positive, big-endian access is used. If negative,
+ little-endian is used.
+
+ It is not a good practice for a driver to be statically configured,
+ since it prevents the same driver being used for different types of
+ UARTs in a system. This option avoids this problem at the cost of a
+ slightly increased code size.
+
config INTEL_MID_SERIAL
bool "Intel MID platform UART support"
depends on DM_SERIAL && OF_CONTROL
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 06ee30697d..76b1811510 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -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/ns16550.c b/drivers/serial/ns16550.c
index 9851663dc5..31f6cfe421 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -93,19 +93,79 @@ static inline int serial_in_shift(void *addr, int shift)
#define CONFIG_SYS_NS16550_CLK 0
#endif
+/*
+ * Use this #ifdef for now since many platforms don't define in(), out(),
+ * out_le32(), etc. but we don't have #defines to indicate this.
+ *
+ * TODO(sjg@chromium.org): Add CONFIG options to indicate what I/O is available
+ * on a platform
+ */
+#ifdef CONFIG_NS16550_DYNAMIC
+static void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
+ int value)
+{
+ if (plat->flags & NS16550_FLAG_IO) {
+ outb(value, addr);
+ } else if (plat->reg_width == 4) {
+ if (plat->flags & NS16550_FLAG_ENDIAN) {
+ if (plat->flags & NS16550_FLAG_BE)
+ out_be32(addr, value);
+ else
+ out_le32(addr, value);
+ } else {
+ writel(value, addr);
+ }
+ } else if (plat->flags & NS16550_FLAG_BE) {
+ writeb(value, addr + (1 << plat->reg_shift) - 1);
+ } else {
+ writeb(value, addr);
+ }
+}
+
+static int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+ if (plat->flags & NS16550_FLAG_IO) {
+ return inb(addr);
+ } else if (plat->reg_width == 4) {
+ if (plat->flags & NS16550_FLAG_ENDIAN) {
+ if (plat->flags & NS16550_FLAG_BE)
+ return in_be32(addr);
+ else
+ return in_le32(addr);
+ } else {
+ return readl(addr);
+ }
+ } else if (plat->flags & NS16550_FLAG_BE) {
+ return readb(addr + (1 << plat->reg_shift) - 1);
+ } else {
+ return readb(addr);
+ }
+}
+#else
+static inline void serial_out_dynamic(struct ns16550_platdata *plat, u8 *addr,
+ int value)
+{
+}
+
+static inline int serial_in_dynamic(struct ns16550_platdata *plat, u8 *addr)
+{
+ return 0;
+}
+
+#endif /* CONFIG_NS16550_DYNAMIC */
+
static void ns16550_writeb(NS16550_t port, int offset, int value)
{
struct ns16550_platdata *plat = port->plat;
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = (unsigned char *)plat->base + offset;
+ addr = (unsigned char *)plat->base + offset + plat->reg_offset;
- /*
- * As far as we know it doesn't make sense to support selection of
- * these options at run-time, so use the existing CONFIG options.
- */
- serial_out_shift(addr + plat->reg_offset, plat->reg_shift, value);
+ if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+ serial_out_dynamic(plat, addr, value);
+ else
+ serial_out_shift(addr, plat->reg_shift, value);
}
static int ns16550_readb(NS16550_t port, int offset)
@@ -114,9 +174,12 @@ static int ns16550_readb(NS16550_t port, int offset)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = (unsigned char *)plat->base + offset;
+ addr = (unsigned char *)plat->base + offset + plat->reg_offset;
- return serial_in_shift(addr + plat->reg_offset, plat->reg_shift);
+ if (IS_ENABLED(CONFIG_NS16550_DYNAMIC))
+ return serial_in_dynamic(plat, addr);
+ else
+ return serial_in_shift(addr, plat->reg_shift);
}
static u32 ns16550_getfcr(NS16550_t port)
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644
index 0000000000..ccab347514
--- /dev/null
+++ b/drivers/serial/serial_coreboot.c
@@ -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,
+};
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 133b25b72e..a9d7715a55 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -562,16 +562,8 @@ static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
return 0; /* ignore */
case SPINOR_OP_BE_4K:
cycle = HSFSTS_CYCLE_4K_ERASE;
- while (len) {
- uint xfer_len = 0x1000;
-
- ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
- if (ret)
- return ret;
- offset += xfer_len;
- len -= xfer_len;
- }
- return 0;
+ ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
+ return ret;
default:
debug("Unknown cycle %x\n", op->cmd.opcode);
return -EINVAL;