- 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:
commit
d4827fcd4c
26 changed files with 303 additions and 152 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ config INTEL_APOLLOLAKE
|
|||
imply HAVE_X86_FIT
|
||||
imply INTEL_GPIO
|
||||
imply SMP
|
||||
imply HAVE_ITSS
|
||||
|
||||
if INTEL_APOLLOLAKE
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Interrupt Timer Subsystem
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation.
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
46
drivers/serial/serial_coreboot.c
Normal file
46
drivers/serial/serial_coreboot.c
Normal 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,
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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" \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue