diff options
author | Tom Rini | 2020-02-04 11:36:49 -0500 |
---|---|---|
committer | Tom Rini | 2020-02-04 11:36:49 -0500 |
commit | d4827fcd4c1b04c338e4019e412f495aa4231d24 (patch) | |
tree | ec6d55971a72f39069ed66a7ca836bdbead324bc /drivers | |
parent | d861183dc531b74479f92bf4c8de8ad60a0a0d56 (diff) | |
parent | 9e0c131a32028547cc4834f238c614af2675c66d (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.c | 10 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl.c | 2 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 32 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/ns16550.c | 79 | ||||
-rw-r--r-- | drivers/serial/serial_coreboot.c | 46 | ||||
-rw-r--r-- | drivers/spi/ich.c | 12 |
7 files changed, 158 insertions, 24 deletions
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c index 4bf1c9ddc4e..67b8b80b9d6 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 4875a3b0b52..5bf5d8b0e24 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 bd95f70b61c..cd2e098883f 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 06ee30697de..76b1811510d 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 9851663dc54..31f6cfe421c 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 00000000000..ccab347514c --- /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 133b25b72e4..a9d7715a556 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; |