- 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
This commit is contained in:
Tom Rini 2020-02-04 11:36:49 -05:00
commit d4827fcd4c
26 changed files with 303 additions and 152 deletions

View file

@ -1,5 +1,5 @@
variables:
windows_vm: vs2015-win2012r2
windows_vm: vs2017-win2016
ubuntu_vm: ubuntu-18.04
ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20200112-17Jan2020
# Add '-u 0' options for Azure pipelines, otherwise we get "permission

View file

@ -709,6 +709,12 @@ config ROM_TABLE_SIZE
hex
default 0x10000
config HAVE_ITSS
bool "Enable ITSS"
help
Select this to include the driver for the Interrupt Timer
Subsystem (ITSS) which is found on several Intel devices.
menu "System tables"
depends on !EFI && !SYS_COREBOOT

View file

@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE
imply HAVE_X86_FIT
imply INTEL_GPIO
imply SMP
imply HAVE_ITSS
if INTEL_APOLLOLAKE

View file

@ -19,7 +19,6 @@ obj-y += fsp_s.o
endif
obj-y += hostbridge.o
obj-y += itss.o
obj-y += lpc.o
obj-y += p2sb.o
obj-y += pch.o

View file

@ -136,10 +136,14 @@ void arch_setup_gd(gd_t *new_gd)
/* DS: data, read/write, 4 GB, base 0 */
gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff);
/* FS: data, read/write, 4 GB, base (Global Data Pointer) */
/*
* FS: data, read/write, sizeof (Global Data Pointer),
* base (Global Data Pointer)
*/
new_gd->arch.gd_addr = new_gd;
gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093,
(ulong)&new_gd->arch.gd_addr, 0xfffff);
gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0x8093,
(ulong)&new_gd->arch.gd_addr,
sizeof(new_gd->arch.gd_addr) - 1);
/* 16-bit CS: code, read/execute, 64 kB, base 0 */
gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff);

View file

@ -27,6 +27,7 @@ obj-y += microcode.o
endif
endif
obj-y += pch.o
obj-$(CONFIG_HAVE_ITSS) += itss.o
ifdef CONFIG_SPL
ifndef CONFIG_SPL_BUILD

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Something to do with Interrupts, but I don't know what ITSS stands for
* Interrupt Timer Subsystem
*
* Copyright (C) 2017 Intel Corporation.
* Copyright (C) 2017 Siemens AG
@ -15,12 +15,12 @@
#include <irq.h>
#include <p2sb.h>
#include <spl.h>
#include <asm/arch/itss.h>
#include <asm/itss.h>
struct apl_itss_platdata {
struct itss_platdata {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
/* Put this first since driver model will copy the data here */
struct dtd_intel_apl_itss dtplat;
struct dtd_intel_itss dtplat;
#endif
};
@ -30,13 +30,13 @@ struct pmc_route {
u32 gpio;
};
struct apl_itss_priv {
struct itss_priv {
struct pmc_route *route;
uint route_count;
u32 irq_snapshot[NUM_IPC_REGS];
};
static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
static int set_polarity(struct udevice *dev, uint irq, bool active_low)
{
u32 mask;
uint reg;
@ -53,9 +53,9 @@ static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low)
}
#ifndef CONFIG_TPL_BUILD
static int apl_snapshot_polarities(struct udevice *dev)
static int snapshot_polarities(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
const int start = GPIO_IRQ_START;
const int end = GPIO_IRQ_END;
int reg_start;
@ -86,9 +86,9 @@ static void show_polarities(struct udevice *dev, const char *msg)
}
}
static int apl_restore_polarities(struct udevice *dev)
static int restore_polarities(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
const int start = GPIO_IRQ_START;
const int end = GPIO_IRQ_END;
int reg_start;
@ -132,9 +132,9 @@ static int apl_restore_polarities(struct udevice *dev)
}
#endif
static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
static int route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
struct pmc_route *route;
int i;
@ -146,14 +146,14 @@ static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num)
return -ENOENT;
}
static int apl_itss_ofdata_to_platdata(struct udevice *dev)
static int itss_ofdata_to_platdata(struct udevice *dev)
{
struct apl_itss_priv *priv = dev_get_priv(dev);
struct itss_priv *priv = dev_get_priv(dev);
int ret;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct apl_itss_platdata *plat = dev_get_platdata(dev);
struct dtd_intel_apl_itss *dtplat = &plat->dtplat;
struct itss_platdata *plat = dev_get_platdata(dev);
struct dtd_intel_itss *dtplat = &plat->dtplat;
/*
* It would be nice to do this in the bind() method, but with
@ -189,26 +189,26 @@ static int apl_itss_ofdata_to_platdata(struct udevice *dev)
return 0;
}
static const struct irq_ops apl_itss_ops = {
.route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe,
.set_polarity = apl_set_polarity,
static const struct irq_ops itss_ops = {
.route_pmc_gpio_gpe = route_pmc_gpio_gpe,
.set_polarity = set_polarity,
#ifndef CONFIG_TPL_BUILD
.snapshot_polarities = apl_snapshot_polarities,
.restore_polarities = apl_restore_polarities,
.snapshot_polarities = snapshot_polarities,
.restore_polarities = restore_polarities,
#endif
};
static const struct udevice_id apl_itss_ids[] = {
{ .compatible = "intel,apl-itss"},
static const struct udevice_id itss_ids[] = {
{ .compatible = "intel,itss"},
{ }
};
U_BOOT_DRIVER(apl_itss_drv) = {
.name = "intel_apl_itss",
U_BOOT_DRIVER(itss_drv) = {
.name = "intel_itss",
.id = UCLASS_IRQ,
.of_match = apl_itss_ids,
.ops = &apl_itss_ops,
.ofdata_to_platdata = apl_itss_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct apl_itss_platdata),
.priv_auto_alloc_size = sizeof(struct apl_itss_priv),
.of_match = itss_ids,
.ops = &itss_ops,
.ofdata_to_platdata = itss_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct itss_platdata),
.priv_auto_alloc_size = sizeof(struct itss_priv),
};

View file

@ -34,18 +34,15 @@ static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev)
data->stride,
data->clk);
/*
* The data->type provides port io or mmio access type info,
* but the access type will be controlled by
* CONFIG_SYS_NS16550_PORT_MAPPED or CONFIG_SYS_NS16550_MEM32.
*
* TBD: ns16550 access type configuration in runtime.
* ex) plat->access_type = data->type
*/
plat->base = data->base;
/* ns16550 uses reg_shift, then covert stride to shift */
plat->reg_shift = data->stride >> 1;
plat->reg_width = data->stride;
plat->clock = data->clk;
plat->fcr = UART_FCR_DEFVAL;
plat->flags = 0;
if (data->type == 1)
plat->flags |= NS16550_FLAG_IO;
return 0;
}

View file

@ -50,7 +50,7 @@ _x86boot_start:
movl %cr0, %eax
orl $(X86_CR0_NW | X86_CR0_CD), %eax
movl %eax, %cr0
wbinvd
invd
/*
* Zero the BIST (Built-In Self Test) value since we don't have it.

View file

@ -28,7 +28,7 @@ start16:
movl %cr0, %eax
orl $(X86_CR0_NW | X86_CR0_CD), %eax
movl %eax, %cr0
wbinvd
invd
/* load the temporary Global Descriptor Table */
data32 cs lidt idt_ptr

View file

@ -171,7 +171,7 @@
itss {
u-boot,dm-pre-reloc;
compatible = "intel,apl-itss";
compatible = "intel,itss";
intel,p2sb-port-id = <PID_ITSS>;
intel,pmc-routes = <
PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0

View file

@ -8,7 +8,6 @@
/dts-v1/;
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
/include/ "keyboard.dtsi"
/include/ "pcspkr.dtsi"
/include/ "reset.dtsi"
@ -40,6 +39,11 @@
u-boot,dm-pre-reloc;
};
serial: serial {
u-boot,dm-pre-reloc;
compatible = "coreboot-serial";
};
coreboot-fb {
compatible = "coreboot-fb";
};

View file

@ -97,6 +97,25 @@ struct cb_serial {
u32 type;
u32 baseaddr;
u32 baud;
u32 regwidth;
/*
* Crystal or input frequency to the chip containing the UART.
* Provide the board specific details to allow the payload to
* initialize the chip containing the UART and make independent
* decisions as to which dividers to select and their values
* to eventually arrive at the desired console baud-rate.
*/
u32 input_hertz;
/*
* UART PCI address: bus, device, function
* 1 << 31 - Valid bit, PCI UART in use
* Bus << 20
* Device << 15
* Function << 12
*/
u32 uart_pci_addr;
};
#define CB_TAG_CONSOLE 0x0010

View file

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Interrupt Timer Subsystem
*
* Copyright (C) 2017 Intel Corporation.
* Copyright 2019 Google LLC
*

View file

@ -6,10 +6,10 @@ CONFIG_NR_DRAM_BANKS=3
CONFIG_VENDOR_INTEL=y
CONFIG_TARGET_EDISON=y
CONFIG_SMP=y
CONFIG_GENERATE_ACPI_TABLE=y
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMDLINE_EDITING is not set
CONFIG_CMD_CPU=y
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GREPENV=y

View file

@ -112,7 +112,7 @@ U-Boot then shuts down CAR and jumps to its relocated version.
Boot flow - U-Boot post-relocation
---------------------------------
----------------------------------
U-Boot starts up normally, running near the top of RAM. After driver model is
running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
@ -142,54 +142,56 @@ Performance
-----------
Bootstage is used through all phases of U-Boot to keep accurate timimgs for
boot. Use 'bootstage report' in U-Boot to see the report, e.g.:
boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
Timer summary in microseconds (16 records):
Mark Elapsed Stage
0 0 reset
155,325 155,325 TPL
204,014 48,689 end TPL
204,385 371 SPL
738,633 534,248 end SPL
739,161 528 board_init_f
842,764 103,603 board_init_r
1,166,233 323,469 main_loop
1,166,283 50 id=175
Timer summary in microseconds (16 records):
Mark Elapsed Stage
0 0 reset
155,325 155,325 TPL
204,014 48,689 end TPL
204,385 371 SPL
738,633 534,248 end SPL
739,161 528 board_init_f
842,764 103,603 board_init_r
1,166,233 323,469 main_loop
1,166,283 50 id=175
Accumulated time:
62 fast_spi
202 dm_r
7,779 dm_spl
15,555 dm_f
208,357 fsp-m
239,847 fsp-s
292,143 mmap_spi
Accumulated time:
62 fast_spi
202 dm_r
7,779 dm_spl
15,555 dm_f
208,357 fsp-m
239,847 fsp-s
292,143 mmap_spi
CPU performance is about 3500 DMIPS:
CPU performance is about 3500 DMIPS::
=> dhry
1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
=> dhry
1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
Partial memory map
------------------
ffffffff Top of ROM (and last byte of 32-bit address space)
ffff8000 TPL loaded here (from IFWI)
ff000000 Bottom of ROM
fefc000 Top of CAR region
fef96000 Stack for FSP-M
fef40000 59000 FSP-M
fef11000 SPL loaded here
fef10000 CONFIG_BLOBLIST_ADDR
fef10000 Stack top in TPL, SPL and U-Boot before relocation
fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
fef00000 Base of CAR region
::
f0000 CONFIG_ROM_TABLE_ADDR
120000 BSS (defined in u-boot-spl.lds)
200000 FSP-S (which is run after U-Boot is relocated)
1110000 CONFIG_SYS_TEXT_BASE
ffffffff Top of ROM (and last byte of 32-bit address space)
ffff8000 TPL loaded here (from IFWI)
ff000000 Bottom of ROM
fefc000 Top of CAR region
fef96000 Stack for FSP-M
fef40000 59000 FSP-M
fef11000 SPL loaded here
fef10000 CONFIG_BLOBLIST_ADDR
fef10000 Stack top in TPL, SPL and U-Boot before relocation
fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
fef00000 Base of CAR region
f0000 CONFIG_ROM_TABLE_ADDR
120000 BSS (defined in u-boot-spl.lds)
200000 FSP-S (which is run after U-Boot is relocated)
1110000 CONFIG_SYS_TEXT_BASE
Supported peripherals

View file

@ -111,35 +111,16 @@ Download it from http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/mach
Build Instruction for Slim Bootloader for LeafHill (APL) target
---------------------------------------------------------------
LeafHill is using PCI UART2 device as a serial port.
For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
Prepare U-Boot and Slim Bootloader as described at the beginning of this page.
Also, the PayloadId needs to be set for APL board.
1. Enable CONFIG_SYS_NS16550_MEM32 in U-Boot::
$ vi include/configs/slimbootloader.h
+#define CONFIG_SYS_NS16550_MEM32
#ifdef CONFIG_SYS_NS16550_MEM3
2. Build U-Boot::
$ make disclean
$ make slimbootloader_defconfig
$ make all
3. Copy u-boot-dtb.bin to Slim Bootloader.
Slim Bootloader looks for a payload from the specific location.
Copy the build u-boot-dtb.bin to the expected location::
$ mkdir -p <Slim Bootloader Dir>/PayloadPkg/PayloadBins/
$ cp <U-Boot Dir>/u-boot-dtb.bin <Slim Bootloader Dir>/PayloadPkg/PayloadBins/u-boot-dtb.bin
4. Update PayloadId. Let's use 'U-BT' as an example::
1. Update PayloadId. Let's use 'U-BT' as an example::
$ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt
-GEN_CFG_DATA.PayloadId | 'AUTO
+GEN_CFG_DATA.PayloadId | 'U-BT'
5. Update payload text base.
2. Update payload text base.
* PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE
in board/intel/slimbootloader/Kconfig.
@ -149,18 +130,18 @@ For MEM32 serial port, CONFIG_SYS_NS16550_MEM32 needs to be enabled in U-Boot.
+ self.PAYLOAD_LOAD_HIGH = 0
+ self.PAYLOAD_EXE_BASE = 0x00100000
6. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
3. Build APL target. Make sure u-boot-dtb.bin and U-BT PayloadId
in build command. The output is Outputs/apl/Stitch_Components.zip::
$ python BuildLoader.py build apl -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma"
7. Stitch IFWI.
4. Stitch IFWI.
Refer to Apollolake_ page in Slim Bootloader document site::
$ python Platform/ApollolakeBoardPkg/Script/StitchLoader.py -i <Existing IFWI> -s Outputs/apl/Stitch_Components.zip -o <Output IFWI>
8. Flash IFWI.
5. Flash IFWI.
Use DediProg to flash IFWI. You should reach at U-Boot serial console.
@ -175,7 +156,7 @@ Build Instruction to use ELF U-Boot
2. Build U-Boot::
$ make disclean
$ make distclean
$ make slimbootloader_defconfig
$ make all
$ strip u-boot (removing symbol for reduced size)

View file

@ -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;

View file

@ -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>

View 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
@ -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

View 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

View file

@ -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)

View file

@ -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,
};

View file

@ -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;

View file

@ -8,19 +8,6 @@
#include <configs/x86-common.h>
/*
* By default, CONFIG_SYS_NS16550_PORT_MAPPED is enabled for port io serial.
* To use mmio base serial, enable CONFIG_SYS_NS16550_MEM32 and disable
* CONFIG_SYS_NS16550_PORT_MAPPED until ns16550 driver supports serial port
* configuration in run-time.
*
* #define CONFIG_SYS_NS16550_MEM32
* #undef CONFIG_SYS_NS16550_PORT_MAPPED
*/
#ifdef CONFIG_SYS_NS16550_MEM32
#undef CONFIG_SYS_NS16550_PORT_MAPPED
#endif
#define CONFIG_STD_DEVICES_SETTINGS \
"stdin=serial,i8042-kbd,usbkbd\0" \
"stdout=serial\0" \

View file

@ -31,6 +31,9 @@
#define CONFIG_SYS_NS16550_REG_SIZE (-1)
#endif
#ifdef CONFIG_NS16550_DYNAMIC
#define UART_REG(x) unsigned char x
#else
#if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
#error "Please define NS16550 registers size."
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_DM_SERIAL)
@ -44,14 +47,24 @@
unsigned char x; \
unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
#endif
#endif /* CONFIG_NS16550_DYNAMIC */
enum ns16550_flags {
NS16550_FLAG_IO = 1 << 0, /* Use I/O access (else mem-mapped) */
NS16550_FLAG_ENDIAN = 1 << 1, /* Use out_le/be_32() */
NS16550_FLAG_BE = 1 << 2, /* Big-endian access (else little) */
};
/**
* struct ns16550_platdata - information about a NS16550 port
*
* @base: Base register address
* @reg_width: IO accesses size of registers (in bytes)
* @reg_width: IO accesses size of registers (in bytes, 1 or 4)
* @reg_shift: Shift size of registers (0=byte, 1=16bit, 2=32bit...)
* @reg_offset: Offset to start of registers (normally 0)
* @clock: UART base clock speed in Hz
* @fcr: Offset of FCR register (normally UART_FCR_DEFVAL)
* @flags: A few flags (enum ns16550_flags)
* @bdf: PCI slot/function (pci_dev_t)
*/
struct ns16550_platdata {
@ -61,6 +74,7 @@ struct ns16550_platdata {
int reg_offset;
int clock;
u32 fcr;
int flags;
#if defined(CONFIG_PCI) && defined(CONFIG_SPL)
int bdf;
#endif