diff options
86 files changed, 2420 insertions, 759 deletions
diff --git a/arch/arm/dts/tegra124-apalis.dts b/arch/arm/dts/tegra124-apalis.dts index a962c0a2f0..08184ab3ac 100644 --- a/arch/arm/dts/tegra124-apalis.dts +++ b/arch/arm/dts/tegra124-apalis.dts @@ -1,5 +1,5 @@ /* - * Copyright 2016 Toradex AG + * Copyright 2016-2019 Toradex AG * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -230,19 +230,21 @@ }; /* Apalis GPIO */ - ddc_scl_pv4 { - nvidia,pins = "ddc_scl_pv4"; + usb_vbus_en0_pn4 { + nvidia,pins = "usb_vbus_en0_pn4"; nvidia,function = "rsvd2"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; }; - ddc_sda_pv5 { - nvidia,pins = "ddc_sda_pv5"; + usb_vbus_en1_pn5 { + nvidia,pins = "usb_vbus_en1_pn5"; nvidia,function = "rsvd2"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; + nvidia,open-drain = <TEGRA_PIN_DISABLE>; }; pex_l0_rst_n_pdd1 { nvidia,pins = "pex_l0_rst_n_pdd1"; @@ -333,40 +335,40 @@ nvidia,open-drain = <TEGRA_PIN_ENABLE>; }; - /* Apalis I2C2 (DDC) */ - gen2_i2c_scl_pt5 { - nvidia,pins = "gen2_i2c_scl_pt5"; - nvidia,function = "i2c2"; + /* Apalis I2C3 (CAM) */ + cam_i2c_scl_pbb1 { + nvidia,pins = "cam_i2c_scl_pbb1"; + nvidia,function = "i2c3"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>; }; - gen2_i2c_sda_pt6 { - nvidia,pins = "gen2_i2c_sda_pt6"; - nvidia,function = "i2c2"; + cam_i2c_sda_pbb2 { + nvidia,pins = "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>; }; - /* Apalis I2C3 (CAM) */ - cam_i2c_scl_pbb1 { - nvidia,pins = "cam_i2c_scl_pbb1"; - nvidia,function = "i2c3"; + /* Apalis I2C4 (DDC) */ + ddc_scl_pv4 { + nvidia,pins = "ddc_scl_pv4"; + nvidia,function = "i2c4"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; - nvidia,open-drain = <TEGRA_PIN_ENABLE>; + nvidia,rcv-sel = <TEGRA_PIN_DISABLE>; }; - cam_i2c_sda_pbb2 { - nvidia,pins = "cam_i2c_sda_pbb2"; - nvidia,function = "i2c3"; + ddc_sda_pv5 { + nvidia,pins = "ddc_sda_pv5"; + nvidia,function = "i2c4"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>; - nvidia,open-drain = <TEGRA_PIN_ENABLE>; + nvidia,rcv-sel = <TEGRA_PIN_DISABLE>; }; /* Apalis MMC1 */ @@ -470,12 +472,12 @@ nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; }; - /* PWM3 active on pu6 being Apalis BKL1_PWM */ + /* PWM3 active on pu6 being Apalis BKL1_PWM as well */ ph3 { nvidia,pins = "ph3"; - nvidia,function = "gmi"; - nvidia,pull = <TEGRA_PIN_PULL_DOWN>; - nvidia,tristate = <TEGRA_PIN_ENABLE>; + nvidia,function = "pwm3"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; }; @@ -736,8 +738,8 @@ }; /* Apalis USBH_EN */ - usb_vbus_en1_pn5 { - nvidia,pins = "usb_vbus_en1_pn5"; + gen2_i2c_sda_pt6 { + nvidia,pins = "gen2_i2c_sda_pt6"; nvidia,function = "rsvd2"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; @@ -755,8 +757,8 @@ }; /* Apalis USBO1_EN */ - usb_vbus_en0_pn4 { - nvidia,pins = "usb_vbus_en0_pn4"; + gen2_i2c_scl_pt5 { + nvidia,pins = "gen2_i2c_scl_pt5"; nvidia,function = "rsvd2"; nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,tristate = <TEGRA_PIN_DISABLE>; @@ -1501,10 +1503,14 @@ nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; }; - pv0 { /* NC */ + /* + * PCB Version Indication: V1.2 and later have GPIO_PV0 + * wired to GND, was NC before + */ + pv0 { nvidia,pins = "pv0"; nvidia,function = "rsvd1"; - nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>; }; @@ -1630,13 +1636,7 @@ }; }; - /* - * GEN2_I2C: I2C2_SDA/SCL (DDC) on MXM3 pin 205/207 (e.g. display EDID) - */ - hdmi_ddc: i2c@7000c400 { - status = "okay"; - clock-frequency = <10000>; - }; + /* GEN2_I2C: unused */ /* * CAM_I2C: I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor @@ -1647,7 +1647,14 @@ clock-frequency = <400000>; }; - /* I2C4 (DDC): unused */ + /* + * I2C4 (DDC): I2C4_SDA/SCL (DDC) on MXM3 pin 205/207 + * (e.g. display EDID) + */ + hdmi_ddc: i2c@7000c700 { + status = "okay"; + clock-frequency = <10000>; + }; /* PWR_I2C: power I2C to audio codec, PMIC and temperature sensor */ i2c@7000d000 { @@ -2112,7 +2119,7 @@ regulator-name = "VCC_USBO1"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; + gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>; enable-active-high; vin-supply = <®_5v0>; }; @@ -2123,7 +2130,7 @@ regulator-name = "VCC_USBH(2A|2C|2D|3|4)"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>; + gpio = <&gpio TEGRA_GPIO(T, 6) GPIO_ACTIVE_HIGH>; enable-active-high; vin-supply = <®_5v0>; }; diff --git a/arch/arm/mach-tegra/sys_info.c b/arch/arm/mach-tegra/sys_info.c index 9975f33e0b..5dc998a52b 100644 --- a/arch/arm/mach-tegra/sys_info.c +++ b/arch/arm/mach-tegra/sys_info.c @@ -6,24 +6,36 @@ #include <common.h> #include <linux/ctype.h> +#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA30) +#include <asm/arch-tegra/pmc.h> -static void upstring(char *s) +static char *get_reset_cause(void) { - while (*s) { - *s = toupper(*s); - s++; + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + switch (pmc->pmc_reset_status) { + case 0x00: + return "POR"; + case 0x01: + return "WATCHDOG"; + case 0x02: + return "SENSOR"; + case 0x03: + return "SW_MAIN"; + case 0x04: + return "LP0"; } + return "UNKNOWN"; } +#endif /* Print CPU information */ int print_cpuinfo(void) { - char soc_name[10]; - - strncpy(soc_name, CONFIG_SYS_SOC, 10); - upstring(soc_name); - puts(soc_name); - puts("\n"); + printf("SoC: %s\n", CONFIG_SYS_SOC); +#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA30) + printf("Reset cause: %s\n", get_reset_cause()); +#endif /* TBD: Add printf of major/minor rev info, stepping, etc. */ return 0; diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c index 992c0beb04..abc050c27b 100644 --- a/arch/arm/mach-tegra/tegra124/cpu.c +++ b/arch/arm/mach-tegra/tegra124/cpu.c @@ -238,6 +238,45 @@ static bool is_partition_powered(u32 partid) return !!(reg & (1 << partid)); } +static void unpower_partition(u32 partid) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + debug("%s: part ID = %08X\n", __func__, partid); + /* Is the partition on? */ + if (is_partition_powered(partid)) { + /* Yes, toggle the partition power state (ON -> OFF) */ + debug("power_partition, toggling state\n"); + writel(START_CP | partid, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come down */ + while (is_partition_powered(partid)) + ; + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); + } +} + +void unpower_cpus(void) +{ + debug("%s entry: G cluster\n", __func__); + + /* Power down the fast cluster rail partition */ + debug("%s: CRAIL\n", __func__); + unpower_partition(CRAIL); + + /* Power down the fast cluster non-CPU partition */ + debug("%s: C0NC\n", __func__); + unpower_partition(C0NC); + + /* Power down the fast cluster CPU0 partition */ + debug("%s: CE0\n", __func__); + unpower_partition(CE0); + + debug("%s: done\n", __func__); +} + static void power_partition(u32 partid) { struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; @@ -284,6 +323,12 @@ void start_cpu(u32 reset_vector) debug("%s entry, reset_vector = %x\n", __func__, reset_vector); + /* + * High power clusters are on after software reset, + * it may interfere with tegra124_ram_repair. + * unpower them. + */ + unpower_cpus(); tegra124_init_clocks(); /* Set power-gating timer multiplier */ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 70f939869a..218e817cf3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -115,6 +115,7 @@ source "arch/x86/cpu/efi/Kconfig" source "arch/x86/cpu/qemu/Kconfig" source "arch/x86/cpu/quark/Kconfig" source "arch/x86/cpu/queensbay/Kconfig" +source "arch/x86/cpu/slimbootloader/Kconfig" source "arch/x86/cpu/tangier/Kconfig" # architecture-specific options below @@ -344,9 +345,17 @@ config INTEL_ME_FILE The filename of the file to use as Intel Management Engine in the board directory. +config USE_HOB + bool "Use HOB (Hand-Off Block)" + help + Select this option to access HOB (Hand-Off Block) data structures + and parse HOBs. This HOB infra structure can be reused with + different solutions across different platforms. + config HAVE_FSP bool "Add an Firmware Support Package binary" depends on !EFI + select USE_HOB help Select this option to add an Firmware Support Package binary to the resulting U-Boot image. It is a binary blob which U-Boot uses diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 85fd5e616e..3f1f62da2b 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_INTEL_BRASWELL) += braswell/ obj-$(CONFIG_INTEL_BROADWELL) += broadwell/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-$(CONFIG_SYS_SLIMBOOTLOADER) += slimbootloader/ obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_QEMU) += qemu/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ diff --git a/arch/x86/cpu/slimbootloader/Kconfig b/arch/x86/cpu/slimbootloader/Kconfig new file mode 100644 index 0000000000..3ea4c9958c --- /dev/null +++ b/arch/x86/cpu/slimbootloader/Kconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Intel Corporation <www.intel.com> + +config SYS_SLIMBOOTLOADER + bool + select USE_HOB + imply SYS_NS16550 + imply AHCI_PCI + imply SCSI + imply SCSI_AHCI + imply MMC + imply MMC_PCI + imply MMC_SDHCI + imply MMC_SDHCI_SDMA + imply USB + imply USB_EHCI_HCD + imply USB_XHCI_HCD + imply E1000 diff --git a/arch/x86/cpu/slimbootloader/Makefile b/arch/x86/cpu/slimbootloader/Makefile new file mode 100644 index 0000000000..aac9fa3db8 --- /dev/null +++ b/arch/x86/cpu/slimbootloader/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Intel Corporation <www.intel.com> + +obj-y += car.o slimbootloader.o sdram.o serial.o diff --git a/arch/x86/cpu/slimbootloader/car.S b/arch/x86/cpu/slimbootloader/car.S new file mode 100644 index 0000000000..6e0304333c --- /dev/null +++ b/arch/x86/cpu/slimbootloader/car.S @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <generated/asm-offsets.h> + +.section .text + +.globl car_init +car_init: + /* Get hob pointer parameter from previous stage's stack */ + mov 0x4(%esp), %esi + jmp car_init_ret diff --git a/arch/x86/cpu/slimbootloader/sdram.c b/arch/x86/cpu/slimbootloader/sdram.c new file mode 100644 index 0000000000..05d40d196c --- /dev/null +++ b/arch/x86/cpu/slimbootloader/sdram.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <linux/sizes.h> +#include <asm/e820.h> +#include <asm/arch/slimbootloader.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * This returns a data pointer of memory map info from the guid hob. + * + * @return: A data pointer of memory map info hob + */ +static struct sbl_memory_map_info *get_memory_map_info(void) +{ + struct sbl_memory_map_info *data; + const efi_guid_t guid = SBL_MEMORY_MAP_INFO_GUID; + + if (!gd->arch.hob_list) + return NULL; + + data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid); + if (!data) + panic("memory map info hob not found\n"); + if (!data->count) + panic("invalid number of memory map entries\n"); + + return data; +} + +#define for_each_if(condition) if (!(condition)) {} else + +#define for_each_memory_map_entry_reversed(iter, entries) \ + for (iter = entries->count - 1; iter >= 0; iter--) \ + for_each_if(entries->entry[iter].type == E820_RAM) + +/** + * This is to give usable memory region information for u-boot relocation. + * so search usable memory region lower than 4GB. + * The memory map entries from Slim Bootloader hob are already sorted. + * + * @total_size: The memory size that u-boot occupies + * @return : The top available memory address lower than 4GB + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + struct sbl_memory_map_info *data; + int i; + u64 addr_start; + u64 addr_end; + ulong ram_top; + + data = get_memory_map_info(); + + /** + * sorted memory map entries from Slim Bootloader based on physical + * start memory address, from low to high. So do reversed search to + * get highest usable, suitable size, 4KB aligned available memory + * under 4GB. + */ + ram_top = 0; + for_each_memory_map_entry_reversed(i, data) { + addr_start = data->entry[i].addr; + addr_end = addr_start + data->entry[i].size; + + if (addr_start > SZ_4G) + continue; + + if (addr_end > SZ_4G) + addr_end = SZ_4G; + + if (addr_end < total_size) + continue; + + /* to relocate u-boot at 4K aligned memory */ + addr_end = rounddown(addr_end - total_size, SZ_4K); + if (addr_end >= addr_start) { + ram_top = (ulong)addr_end + total_size; + break; + } + } + + if (!ram_top) + panic("failed to find available memory for relocation!"); + + return ram_top; +} + +/** + * The memory initialization has already been done in previous Slim Bootloader + * stage thru FSP-M. Instead, this sets the ram_size from the memory map info + * hob. + */ +int dram_init(void) +{ + struct sbl_memory_map_info *data; + int i; + u64 ram_size; + + data = get_memory_map_info(); + + /** + * sorted memory map entries from Slim Bootloader based on physical + * start memory address, from low to high. So do reversed search to + * simply get highest usable memory address as RAM size + */ + ram_size = 0; + for_each_memory_map_entry_reversed(i, data) { + /* simply use the highest usable memory address as RAM size */ + ram_size = data->entry[i].addr + data->entry[i].size; + break; + } + + if (!ram_size) + panic("failed to detect memory size"); + + gd->ram_size = ram_size; + return 0; +} + +int dram_init_banksize(void) +{ + if (!CONFIG_NR_DRAM_BANKS) + return 0; + + /* simply use a single bank to have whole size for now */ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; + return 0; +} + +unsigned int install_e820_map(unsigned int max_entries, + struct e820_entry *entries) +{ + struct sbl_memory_map_info *data; + unsigned int i; + + data = get_memory_map_info(); + + for (i = 0; i < data->count; i++) { + entries[i].addr = data->entry[i].addr; + entries[i].size = data->entry[i].size; + entries[i].type = data->entry[i].type; + } + + return i; +} diff --git a/arch/x86/cpu/slimbootloader/serial.c b/arch/x86/cpu/slimbootloader/serial.c new file mode 100644 index 0000000000..7b44a59bff --- /dev/null +++ b/arch/x86/cpu/slimbootloader/serial.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <dm.h> +#include <ns16550.h> +#include <serial.h> +#include <asm/arch/slimbootloader.h> + +/** + * The serial port info hob is generated by Slim Bootloader, so eligible for + * Slim Bootloader based boards only. + */ +static int slimbootloader_serial_ofdata_to_platdata(struct udevice *dev) +{ + const efi_guid_t guid = SBL_SERIAL_PORT_INFO_GUID; + struct sbl_serial_port_info *data; + struct ns16550_platdata *plat = dev->platdata; + + if (!gd->arch.hob_list) + panic("hob list not found!"); + + data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid); + if (!data) { + debug("failed to get serial port information\n"); + return -ENOENT; + } + debug("type:%d base=0x%08x baudrate=%d stride=%d clk=%d\n", + data->type, + data->base, + data->baud, + 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->clock = data->clk; + + return 0; +} + +static const struct udevice_id slimbootloader_serial_ids[] = { + { .compatible = "intel,slimbootloader-uart" }, + {} +}; + +U_BOOT_DRIVER(serial_slimbootloader) = { + .name = "serial_slimbootloader", + .id = UCLASS_SERIAL, + .of_match = slimbootloader_serial_ids, + .ofdata_to_platdata = slimbootloader_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, +}; diff --git a/arch/x86/cpu/slimbootloader/slimbootloader.c b/arch/x86/cpu/slimbootloader/slimbootloader.c new file mode 100644 index 0000000000..e6b174ca88 --- /dev/null +++ b/arch/x86/cpu/slimbootloader/slimbootloader.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> +#include <asm/arch/slimbootloader.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * This sets tsc_base and clock_rate for early_timer and tsc_timer. + * The performance info guid hob has all performance timestamp data, but + * the only tsc frequency info is used for the timer driver for now. + * + * Slim Bootloader already calibrated TSC and provides it to U-Boot. + * Therefore, U-Boot does not have to re-calibrate TSC. + * Configuring tsc_base and clock_rate here makes x86 tsc_timer driver + * bypass TSC calibration and use the provided TSC frequency. + */ +static void tsc_init(void) +{ + struct sbl_performance_info *data; + const efi_guid_t guid = SBL_PERFORMANCE_INFO_GUID; + + if (!gd->arch.hob_list) + panic("hob list not found!"); + + gd->arch.tsc_base = rdtsc(); + debug("tsc_base=0x%llx\n", gd->arch.tsc_base); + + data = hob_get_guid_hob_data(gd->arch.hob_list, NULL, &guid); + if (!data) { + debug("performance info hob not found\n"); + return; + } + + /* frequency is in KHz, so to Hz */ + gd->arch.clock_rate = data->frequency * 1000; + debug("freq=0x%lx\n", gd->arch.clock_rate); +} + +int arch_cpu_init(void) +{ + tsc_init(); + + return x86_cpu_init_f(); +} + +int checkcpu(void) +{ + return 0; +} + +int print_cpuinfo(void) +{ + return default_print_cpuinfo(); +} diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 4a82add76b..71cd70f9cd 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -97,7 +97,7 @@ early_board_init_ret: jmp car_init .globl car_init_ret car_init_ret: -#ifndef CONFIG_HAVE_FSP +#ifndef CONFIG_USE_HOB /* * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, * or fully initialised SDRAM - we really don't care which) @@ -137,12 +137,13 @@ car_init_ret: /* Get address of global_data */ mov %fs:0, %edx -#ifdef CONFIG_HAVE_FSP +#ifdef CONFIG_USE_HOB /* Store the HOB list if we have one */ test %esi, %esi jz skip_hob movl %esi, GD_HOB_LIST(%edx) +#ifdef CONFIG_HAVE_FSP /* * After fsp_init() returns, the stack has already been switched to a * place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR. @@ -151,6 +152,7 @@ car_init_ret: */ subl $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp movl %esp, GD_MALLOC_BASE(%edx) +#endif skip_hob: #else /* Store table pointer */ diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c index 0e4f961c53..61b2642aa9 100644 --- a/arch/x86/cpu/tangier/acpi.c +++ b/arch/x86/cpu/tangier/acpi.c @@ -68,6 +68,44 @@ u32 acpi_fill_mcfg(u32 current) return current; } +static u32 acpi_fill_csrt_dma(struct acpi_csrt_group *grp) +{ + struct acpi_csrt_shared_info *si = (struct acpi_csrt_shared_info *)&grp[1]; + + /* Fill the Resource Group with Shared Information attached */ + memset(grp, 0, sizeof(*grp)); + grp->shared_info_length = sizeof(struct acpi_csrt_shared_info); + grp->length = sizeof(struct acpi_csrt_group) + grp->shared_info_length; + /* TODO: All values below should come from U-Boot DT somehow */ + sprintf((char *)&grp->vendor_id, "%04X", 0x8086); + grp->device_id = 0x11a2; + + /* Fill the Resource Group Shared Information */ + memset(si, 0, sizeof(*si)); + si->major_version = 1; + si->minor_version = 0; + /* TODO: All values below should come from U-Boot DT somehow */ + si->mmio_base_low = 0xff192000; + si->mmio_base_high = 0; + si->gsi_interrupt = 32; + si->interrupt_polarity = 1; + si->interrupt_mode = 0; + si->num_channels = 8; + si->dma_address_width = 32; + si->base_request_line = 0; + si->num_handshake_signals = 16; + si->max_block_size = 0x20000; + + return grp->length; +} + +u32 acpi_fill_csrt(u32 current) +{ + current += acpi_fill_csrt_dma((struct acpi_csrt_group *)current); + + return current; +} + void acpi_create_gnvs(struct acpi_global_nvs *gnvs) { struct udevice *dev; diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index fa717bc096..d4bdf62be6 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -18,6 +18,7 @@ dtb-y += bayleybay.dtb \ qemu-x86_i440fx.dtb \ qemu-x86_q35.dtb \ theadorable-x86-dfi-bt700.dtb \ + slimbootloader.dtb \ baytrail_som-db5800-som-6867.dtb targets += $(dtb-y) diff --git a/arch/x86/dts/edison.dts b/arch/x86/dts/edison.dts index c0487656d3..df24aa0d26 100644 --- a/arch/x86/dts/edison.dts +++ b/arch/x86/dts/edison.dts @@ -84,15 +84,10 @@ reg = <0xff3fc000 0x1000>; }; -/* - * FIXME: For now U-Boot DM model doesn't allow to power up this controller. - * Enabling it will make U-Boot hang. - * sdcard: mmc@ff3fa000 { compatible = "intel,sdhci-tangier"; reg = <0xff3fa000 0x1000>; }; - */ pmu: power@ff00b000 { compatible = "intel,pmu-mid"; diff --git a/arch/x86/dts/slimbootloader.dts b/arch/x86/dts/slimbootloader.dts new file mode 100644 index 0000000000..d04095c4f8 --- /dev/null +++ b/arch/x86/dts/slimbootloader.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" +/include/ "reset.dtsi" +/include/ "tsc_timer.dtsi" + +/ { + model = "slimbootloader x86 payload"; + compatible = "slimbootloader,x86-payload"; + + chosen { + stdout-path = &serial; + }; + + serial: serial { + compatible = "intel,slimbootloader-uart"; + }; + + pci { + compatible = "pci-x86"; + }; +}; diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index e3b65cff66..02aea127c1 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -303,6 +303,37 @@ struct acpi_mcfg_mmconfig { /* ACPI global NVS structure */ struct acpi_global_nvs; +/* CSRT (Core System Resource Table) */ +struct acpi_csrt { + struct acpi_table_header header; +}; + +struct acpi_csrt_group { + u32 length; + u32 vendor_id; + u32 subvendor_id; + u16 device_id; + u16 subdevice_id; + u16 revision; + u16 reserved; + u32 shared_info_length; +}; + +struct acpi_csrt_shared_info { + u16 major_version; + u16 minor_version; + u32 mmio_base_low; + u32 mmio_base_high; + u32 gsi_interrupt; + u8 interrupt_polarity; + u8 interrupt_mode; + u8 num_channels; + u8 dma_address_width; + u16 base_request_line; + u16 num_handshake_signals; + u32 max_block_size; +}; + /* DBG2 definitions are partially used for SPCR interface_type */ /* Types for port_type field */ @@ -370,6 +401,7 @@ u32 acpi_fill_madt(u32 current); int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end); u32 acpi_fill_mcfg(u32 current); +u32 acpi_fill_csrt(u32 current); void acpi_create_gnvs(struct acpi_global_nvs *gnvs); ulong write_acpi_tables(ulong start); diff --git a/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h b/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h new file mode 100644 index 0000000000..05dd1b2b44 --- /dev/null +++ b/arch/x86/include/asm/arch-slimbootloader/slimbootloader.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#ifndef __SLIMBOOTLOADER_ARCH_H__ +#define __SLIMBOOTLOADER_ARCH_H__ + +#include <common.h> +#include <asm/hob.h> + +/** + * A GUID to get MemoryMap info hob which is provided by Slim Bootloader + */ +#define SBL_MEMORY_MAP_INFO_GUID \ + EFI_GUID(0xa1ff7424, 0x7a1a, 0x478e, \ + 0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32) + +/** + * A GUID to get SerialPort info hob which is provided by Slim Bootloader + */ +#define SBL_SERIAL_PORT_INFO_GUID \ + EFI_GUID(0x6c6872fe, 0x56a9, 0x4403, \ + 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1) + +/** + * A GUID to get boot performance info hob which is provided by Slim Bootloader + */ +#define SBL_PERFORMANCE_INFO_GUID \ + EFI_GUID(0x868204be, 0x23d0, 0x4ff9, \ + 0xac, 0x34, 0xb9, 0x95, 0xac, 0x04, 0xb1, 0xb9) + +/** + * A single entry of memory map information + * + * @addr: start address of a memory map entry + * @size: size of a memory map entry + * @type: usable:1, reserved:2, acpi:3, nvs:4, unusable:5 + * @flag: only used in Slim Bootloader + * @rsvd: padding for alignment + */ +struct sbl_memory_map_entry { + u64 addr; + u64 size; + u8 type; + u8 flag; + u8 rsvd[6]; +}; + +/** + * This includes all memory map entries which is sorted based on physical start + * address, from low to high, and carved out reserved, acpi nvs, acpi reclaim + * and usable memory. + * + * @rev : revision of memory_map_info structure. currently 1. + * @rsvd : padding for alignment + * @count: the number of memory map entries + * @entry: array of all memory map entries + */ +struct sbl_memory_map_info { + u8 rev; + u8 rsvd[3]; + u32 count; + struct sbl_memory_map_entry entry[0]; +}; + +/** + * This includes serial port info which has already been initialized in previous + * Slim Bootloader stage. + * The Slim Bootloader initializes serial port regardless of debug/release build + * modes, and it passes the information to a payload thru hob. So, a payload can + * re-use the serial information without re-initializing serial port. + * + * @rev : revision of serial_port_info structure. currently 1. + * @rsvd : padding for alignment + * @type : port io: 1, mmio: 2 + * @base : io base address. ex) 0x3f8, 0x80001000 + * @baud : uart baud rate + * @stride: register stride in Bytes + * @clk : uart frequency in Hz + * @rsvd1 : reserved + */ +struct sbl_serial_port_info { + u8 rev; + u8 rsvd[3]; + u32 type; + u32 base; + u32 baud; + u32 stride; + u32 clk; + u32 rsvd1; +}; + +/** + * This includes timestamp data which has been collected in Slim Bootloader + * stages from the reset vector. In addition, this has TSC frequency in KHz to + * calculate each timestamp. + * + * @rev : revision of performance_info structure. currently 1. + * @rsvd : padding for alignment + * @count : the number of collected timestamp data + * @flags : only used in Slim Bootloader + * @frequency: tsc frequency in KHz + * @timestamp: the array of timestamp data which has 64-bit tsc value + */ +struct sbl_performance_info { + u8 rev; + u8 rsvd[3]; + u16 count; + u16 flags; + u32 frequency; + u64 timestamp[0]; +}; + +#endif /* __SLIMBOOTLOADER_ARCH_H__ */ diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index 8b5b709045..b8b783b82e 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -421,6 +421,28 @@ Device (PCI0) } } } + + Device (GDMA) + { + Name (_ADR, 0x00150000) + Name (_HID, "808611A2") + Name (_UID, Zero) + + Method (_STA, 0, NotSerialized) + { + Return (STA_VISIBLE) + } + + Method (_CRS, 0, Serialized) + { + Name (RBUF, ResourceTemplate () + { + Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } + }) + Return (RBUF) + } + } } Device (FLIS) diff --git a/arch/x86/include/asm/fsp/fsp_ffs.h b/arch/x86/include/asm/fsp/fsp_ffs.h index 61ce63c08e..b7558e5a17 100644 --- a/arch/x86/include/asm/fsp/fsp_ffs.h +++ b/arch/x86/include/asm/fsp/fsp_ffs.h @@ -45,7 +45,7 @@ struct __packed ffs_file_header { * This GUID is the file name. * It is used to uniquely identify the file. */ - struct efi_guid name; + efi_guid_t name; /* Used to verify the integrity of the file */ union ffs_integrity integrity; /* Identifies the type of file */ @@ -68,7 +68,7 @@ struct __packed ffs_file_header2 { * Name in any given firmware volume, except if the file type is * EFI_FV_FILE_TYPE_FFS_PAD. */ - struct efi_guid name; + efi_guid_t name; /* Used to verify the integrity of the file */ union ffs_integrity integrity; /* Identifies the type of file */ diff --git a/arch/x86/include/asm/fsp/fsp_fv.h b/arch/x86/include/asm/fsp/fsp_fv.h index 190aedcf44..511dfb78b8 100644 --- a/arch/x86/include/asm/fsp/fsp_fv.h +++ b/arch/x86/include/asm/fsp/fsp_fv.h @@ -80,7 +80,7 @@ struct fv_header { * Declares the file system with which the firmware volume * is formatted. */ - struct efi_guid fs_guid; + efi_guid_t fs_guid; /* * Length in bytes of the complete firmware volume, including * the header. @@ -128,7 +128,7 @@ struct fv_header { /* Extension header pointed by ExtHeaderOffset of volume header */ struct fv_ext_header { /* firmware volume name */ - struct efi_guid fv_name; + efi_guid_t fv_name; /* Size of the rest of the extension header including this structure */ u32 ext_hdr_size; }; diff --git a/arch/x86/include/asm/fsp/fsp_hob.h b/arch/x86/include/asm/fsp/fsp_hob.h index 00657b62c7..3bb79c4b67 100644 --- a/arch/x86/include/asm/fsp/fsp_hob.h +++ b/arch/x86/include/asm/fsp/fsp_hob.h @@ -7,124 +7,7 @@ #ifndef __FSP_HOB_H__ #define __FSP_HOB_H__ -#include <efi.h> - -/* Type of HOB Header */ -#define HOB_TYPE_MEM_ALLOC 0x0002 -#define HOB_TYPE_RES_DESC 0x0003 -#define HOB_TYPE_GUID_EXT 0x0004 -#define HOB_TYPE_UNUSED 0xFFFE -#define HOB_TYPE_EOH 0xFFFF - -/* - * Describes the format and size of the data inside the HOB. - * All HOBs must contain this generic HOB header. - */ -struct hob_header { - u16 type; /* HOB type */ - u16 len; /* HOB length */ - u32 reserved; /* always zero */ -}; - -/* - * Describes all memory ranges used during the HOB producer phase that - * exist outside the HOB list. This HOB type describes how memory is used, - * not the physical attributes of memory. - */ -struct hob_mem_alloc { - struct hob_header hdr; - /* - * A GUID that defines the memory allocation region's type and purpose, - * as well as other fields within the memory allocation HOB. This GUID - * is used to define the additional data within the HOB that may be - * present for the memory allocation HOB. Type efi_guid is defined in - * InstallProtocolInterface() in the UEFI 2.0 specification. - */ - struct efi_guid name; - /* - * The base address of memory allocated by this HOB. - * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0 - * specification. - */ - phys_addr_t mem_base; - /* The length in bytes of memory allocated by this HOB */ - phys_size_t mem_len; - /* - * Defines the type of memory allocated by this HOB. - * The memory type definition follows the EFI_MEMORY_TYPE definition. - * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0 - * specification. - */ - enum efi_mem_type mem_type; - /* padding */ - u8 reserved[4]; -}; - -/* Value of ResourceType in HOB_RES_DESC */ -#define RES_SYS_MEM 0x00000000 -#define RES_MMAP_IO 0x00000001 -#define RES_IO 0x00000002 -#define RES_FW_DEVICE 0x00000003 -#define RES_MMAP_IO_PORT 0x00000004 -#define RES_MEM_RESERVED 0x00000005 -#define RES_IO_RESERVED 0x00000006 -#define RES_MAX_MEM_TYPE 0x00000007 - -/* - * These types can be ORed together as needed. - * - * The first three enumerations describe settings - * The rest of the settings describe capabilities - */ -#define RES_ATTR_PRESENT 0x00000001 -#define RES_ATTR_INITIALIZED 0x00000002 -#define RES_ATTR_TESTED 0x00000004 -#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 -#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 -#define RES_ATTR_ECC_RESERVED_1 0x00000020 -#define RES_ATTR_ECC_RESERVED_2 0x00000040 -#define RES_ATTR_READ_PROTECTED 0x00000080 -#define RES_ATTR_WRITE_PROTECTED 0x00000100 -#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 -#define RES_ATTR_UNCACHEABLE 0x00000400 -#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 -#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 -#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 -#define RES_ATTR_16_BIT_IO 0x00004000 -#define RES_ATTR_32_BIT_IO 0x00008000 -#define RES_ATTR_64_BIT_IO 0x00010000 -#define RES_ATTR_UNCACHED_EXPORTED 0x00020000 - -/* - * Describes the resource properties of all fixed, nonrelocatable resource - * ranges found on the processor host bus during the HOB producer phase. - */ -struct hob_res_desc { - struct hob_header hdr; - /* - * A GUID representing the owner of the resource. This GUID is - * used by HOB consumer phase components to correlate device - * ownership of a resource. - */ - struct efi_guid owner; - u32 type; - u32 attr; - /* The physical start address of the resource region */ - phys_addr_t phys_start; - /* The number of bytes of the resource region */ - phys_size_t len; -}; - -/* - * Allows writers of executable content in the HOB producer phase to - * maintain and manage HOBs with specific GUID. - */ -struct hob_guid { - struct hob_header hdr; - /* A GUID that defines the contents of this HOB */ - struct efi_guid name; - /* GUID specific data goes here */ -}; +#include <asm/hob.h> enum pixel_format { pixel_rgbx_8bpc, /* RGB 8 bit per color */ @@ -146,70 +29,6 @@ struct __packed hob_graphics_info { u32 pixels_per_scanline; }; -/** - * get_next_hob() - return a pointer to the next HOB in the HOB list - * - * This macro returns a pointer to HOB that follows the HOB specified by hob - * in the HOB List. - * - * @hdr: A pointer to a HOB. - * - * @return: A pointer to the next HOB in the HOB list. - */ -static inline const struct hob_header *get_next_hob(const struct hob_header *hdr) -{ - return (const struct hob_header *)((uintptr_t)hdr + hdr->len); -} - -/** - * end_of_hob() - determine if a HOB is the last HOB in the HOB list - * - * This macro determine if the HOB specified by hob is the last HOB in the - * HOB list. If hob is last HOB in the HOB list, then true is returned. - * Otherwise, false is returned. - * - * @hdr: A pointer to a HOB. - * - * @retval true: The HOB specified by hdr is the last HOB in the HOB list. - * @retval false: The HOB specified by hdr is not the last HOB in the HOB list. - */ -static inline bool end_of_hob(const struct hob_header *hdr) -{ - return hdr->type == HOB_TYPE_EOH; -} - -/** - * get_guid_hob_data() - return a pointer to data buffer from a HOB of - * type HOB_TYPE_GUID_EXT - * - * This macro returns a pointer to the data buffer in a HOB specified by hob. - * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. - * - * @hdr: A pointer to a HOB. - * - * @return: A pointer to the data buffer in a HOB. - */ -static inline void *get_guid_hob_data(const struct hob_header *hdr) -{ - return (void *)((uintptr_t)hdr + sizeof(struct hob_guid)); -} - -/** - * get_guid_hob_data_size() - return the size of the data buffer from a HOB - * of type HOB_TYPE_GUID_EXT - * - * This macro returns the size, in bytes, of the data buffer in a HOB - * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. - * - * @hdr: A pointer to a HOB. - * - * @return: The size of the data buffer. - */ -static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) -{ - return hdr->len - sizeof(struct hob_guid); -} - /* FSP specific GUID HOB definitions */ #define FSP_GUID_DATA1 0x912740be #define FSP_GUID_DATA2 0x2284 @@ -223,56 +42,57 @@ static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) #define FSP_GUID_DATA4_6 0x3f #define FSP_GUID_DATA4_7 0x0c +#define FSP_GUID_BYTE0 0xbe +#define FSP_GUID_BYTE1 0x40 +#define FSP_GUID_BYTE2 0x27 +#define FSP_GUID_BYTE3 0x91 +#define FSP_GUID_BYTE4 0x84 +#define FSP_GUID_BYTE5 0x22 +#define FSP_GUID_BYTE6 0x34 +#define FSP_GUID_BYTE7 0x47 +#define FSP_GUID_BYTE8 FSP_GUID_DATA4_0 +#define FSP_GUID_BYTE9 FSP_GUID_DATA4_1 +#define FSP_GUID_BYTE10 FSP_GUID_DATA4_2 +#define FSP_GUID_BYTE11 FSP_GUID_DATA4_3 +#define FSP_GUID_BYTE12 FSP_GUID_DATA4_4 +#define FSP_GUID_BYTE13 FSP_GUID_DATA4_5 +#define FSP_GUID_BYTE14 FSP_GUID_DATA4_6 +#define FSP_GUID_BYTE15 FSP_GUID_DATA4_7 + #define FSP_HEADER_GUID \ - { \ - FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \ - { FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \ - FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \ - FSP_GUID_DATA4_6, FSP_GUID_DATA4_7 } \ - } + EFI_GUID(FSP_GUID_DATA1, FSP_GUID_DATA2, FSP_GUID_DATA3, \ + FSP_GUID_DATA4_0, FSP_GUID_DATA4_1, FSP_GUID_DATA4_2, \ + FSP_GUID_DATA4_3, FSP_GUID_DATA4_4, FSP_GUID_DATA4_5, \ + FSP_GUID_DATA4_6, FSP_GUID_DATA4_7) #define FSP_NON_VOLATILE_STORAGE_HOB_GUID \ - { \ - 0x721acf02, 0x4d77, 0x4c2a, \ - { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \ - } + EFI_GUID(0x721acf02, 0x4d77, 0x4c2a, \ + 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0) #define FSP_BOOTLOADER_TEMP_MEM_HOB_GUID \ - { \ - 0xbbcff46c, 0xc8d3, 0x4113, \ - { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } \ - } + EFI_GUID(0xbbcff46c, 0xc8d3, 0x4113, \ + 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e) #define FSP_HOB_RESOURCE_OWNER_FSP_GUID \ - { \ - 0x69a79759, 0x1373, 0x4367, \ - { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } \ - } + EFI_GUID(0x69a79759, 0x1373, 0x4367, \ + 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e) #define FSP_HOB_RESOURCE_OWNER_TSEG_GUID \ - { \ - 0xd038747c, 0xd00c, 0x4980, \ - { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } \ - } + EFI_GUID(0xd038747c, 0xd00c, 0x4980, \ + 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55) #define FSP_HOB_RESOURCE_OWNER_GRAPHICS_GUID \ - { \ - 0x9c7c3aa7, 0x5332, 0x4917, \ - { 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07 } \ - } + EFI_GUID(0x9c7c3aa7, 0x5332, 0x4917, \ + 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07) /* The following GUIDs are newly introduced in FSP spec 1.1 */ #define FSP_HOB_RESOURCE_OWNER_BOOTLOADER_TOLUM_GUID \ - { \ - 0x73ff4f56, 0xaa8e, 0x4451, \ - { 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44 } \ - } + EFI_GUID(0x73ff4f56, 0xaa8e, 0x4451, \ + 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44) #define FSP_GRAPHICS_INFO_HOB_GUID \ - { \ - 0x39f62cce, 0x6825, 0x4669, \ - { 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07 } \ - } + EFI_GUID(0x39f62cce, 0x6825, 0x4669, \ + 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07) #endif diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h index 7e51f24b12..7b92392a27 100644 --- a/arch/x86/include/asm/fsp/fsp_support.h +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -8,10 +8,10 @@ #define __FSP_SUPPORT_H__ #include "fsp_types.h" +#include "fsp_hob.h" #include "fsp_fv.h" #include "fsp_ffs.h" #include "fsp_api.h" -#include "fsp_hob.h" #include "fsp_infoheader.h" #include "fsp_bootmode.h" #include "fsp_azalia.h" @@ -106,7 +106,7 @@ u64 fsp_get_usable_highmem_top(const void *hob_list); * 0 if this region does not exist. */ u64 fsp_get_reserved_mem_from_guid(const void *hob_list, - u64 *len, struct efi_guid *guid); + u64 *len, const efi_guid_t *guid); /** * This function retrieves the FSP reserved normal memory. @@ -132,41 +132,6 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len); u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len); /** - * Returns the next instance of a HOB type from the starting HOB. - * - * @type: HOB type to search - * @hob_list: A pointer to the HOB list - * - * @retval: A HOB object with matching type; Otherwise NULL. - */ -const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list); - -/** - * Returns the next instance of the matched GUID HOB from the starting HOB. - * - * @guid: GUID to search - * @hob_list: A pointer to the HOB list - * - * @retval: A HOB object with matching GUID; Otherwise NULL. - */ -const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, - const void *hob_list); - -/** - * This function retrieves a GUID HOB data buffer and size. - * - * @hob_list: A HOB list pointer. - * @len: A pointer to the GUID HOB data buffer length. - * If the GUID HOB is located, the length will be updated. - * @guid A pointer to HOB GUID. - * - * @retval NULL: Failed to find the GUID HOB. - * @retval others: GUID HOB data buffer pointer. - */ -void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, - struct efi_guid *guid); - -/** * This function retrieves FSP Non-volatile Storage HOB buffer and size. * * @hob_list: A HOB list pointer. diff --git a/arch/x86/include/asm/fsp/fsp_types.h b/arch/x86/include/asm/fsp/fsp_types.h index 5247102f75..3d5b17ecf1 100644 --- a/arch/x86/include/asm/fsp/fsp_types.h +++ b/arch/x86/include/asm/fsp/fsp_types.h @@ -7,14 +7,6 @@ #ifndef __FSP_TYPES_H__ #define __FSP_TYPES_H__ -/* 128 bit buffer containing a unique identifier value */ -struct efi_guid { - u32 data1; - u16 data2; - u16 data3; - u8 data4[8]; -}; - /** * Returns a 16-bit signature built from 2 ASCII characters. * diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 9398ec33b2..797397e697 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -83,7 +83,7 @@ struct arch_global_data { const struct pch_gpio_map *gpio_map; /* board GPIO map */ struct memory_info meminfo; /* Memory information */ struct pei_memory_info pei_meminfo; /* PEI memory information */ -#ifdef CONFIG_HAVE_FSP +#ifdef CONFIG_USE_HOB void *hob_list; /* FSP HOB list */ #endif struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; diff --git a/arch/x86/include/asm/hob.h b/arch/x86/include/asm/hob.h new file mode 100644 index 0000000000..b4239821aa --- /dev/null +++ b/arch/x86/include/asm/hob.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#ifndef __HOB_H__ +#define __HOB_H__ + +#include <efi.h> +#include <efi_loader.h> + +/* Type of HOB Header */ +#define HOB_TYPE_MEM_ALLOC 0x0002 +#define HOB_TYPE_RES_DESC 0x0003 +#define HOB_TYPE_GUID_EXT 0x0004 +#define HOB_TYPE_UNUSED 0xFFFE +#define HOB_TYPE_EOH 0xFFFF + +/* Value of ResourceType in HOB_RES_DESC */ +#define RES_SYS_MEM 0x00000000 +#define RES_MMAP_IO 0x00000001 +#define RES_IO 0x00000002 +#define RES_FW_DEVICE 0x00000003 +#define RES_MMAP_IO_PORT 0x00000004 +#define RES_MEM_RESERVED 0x00000005 +#define RES_IO_RESERVED 0x00000006 +#define RES_MAX_MEM_TYPE 0x00000007 + +/* + * These types can be ORed together as needed. + * + * The first three enumerations describe settings + * The rest of the settings describe capabilities + */ +#define RES_ATTR_PRESENT 0x00000001 +#define RES_ATTR_INITIALIZED 0x00000002 +#define RES_ATTR_TESTED 0x00000004 +#define RES_ATTR_SINGLE_BIT_ECC 0x00000008 +#define RES_ATTR_MULTIPLE_BIT_ECC 0x00000010 +#define RES_ATTR_ECC_RESERVED_1 0x00000020 +#define RES_ATTR_ECC_RESERVED_2 0x00000040 +#define RES_ATTR_READ_PROTECTED 0x00000080 +#define RES_ATTR_WRITE_PROTECTED 0x00000100 +#define RES_ATTR_EXECUTION_PROTECTED 0x00000200 +#define RES_ATTR_UNCACHEABLE 0x00000400 +#define RES_ATTR_WRITE_COMBINEABLE 0x00000800 +#define RES_ATTR_WRITE_THROUGH_CACHEABLE 0x00001000 +#define RES_ATTR_WRITE_BACK_CACHEABLE 0x00002000 +#define RES_ATTR_16_BIT_IO 0x00004000 +#define RES_ATTR_32_BIT_IO 0x00008000 +#define RES_ATTR_64_BIT_IO 0x00010000 +#define RES_ATTR_UNCACHED_EXPORTED 0x00020000 + +/* + * Describes the format and size of the data inside the HOB. + * All HOBs must contain this generic HOB header. + */ +struct hob_header { + u16 type; /* HOB type */ + u16 len; /* HOB length */ + u32 reserved; /* always zero */ +}; + +/* + * Describes all memory ranges used during the HOB producer phase that + * exist outside the HOB list. This HOB type describes how memory is used, + * not the physical attributes of memory. + */ +struct hob_mem_alloc { + struct hob_header hdr; + /* + * A GUID that defines the memory allocation region's type and purpose, + * as well as other fields within the memory allocation HOB. This GUID + * is used to define the additional data within the HOB that may be + * present for the memory allocation HOB. Type efi_guid_t is defined in + * InstallProtocolInterface() in the UEFI 2.0 specification. + */ + efi_guid_t name; + /* + * The base address of memory allocated by this HOB. + * Type phys_addr_t is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + phys_addr_t mem_base; + /* The length in bytes of memory allocated by this HOB */ + phys_size_t mem_len; + /* + * Defines the type of memory allocated by this HOB. + * The memory type definition follows the EFI_MEMORY_TYPE definition. + * Type EFI_MEMORY_TYPE is defined in AllocatePages() in the UEFI 2.0 + * specification. + */ + enum efi_mem_type mem_type; + /* padding */ + u8 reserved[4]; +}; + +/* + * Describes the resource properties of all fixed, nonrelocatable resource + * ranges found on the processor host bus during the HOB producer phase. + */ +struct hob_res_desc { + struct hob_header hdr; + /* + * A GUID representing the owner of the resource. This GUID is + * used by HOB consumer phase components to correlate device + * ownership of a resource. + */ + efi_guid_t owner; + u32 type; + u32 attr; + /* The physical start address of the resource region */ + phys_addr_t phys_start; + /* The number of bytes of the resource region */ + phys_size_t len; +}; + +/* + * Allows writers of executable content in the HOB producer phase to + * maintain and manage HOBs with specific GUID. + */ +struct hob_guid { + struct hob_header hdr; + /* A GUID that defines the contents of this HOB */ + efi_guid_t name; + /* GUID specific data goes here */ +}; + +/** + * get_next_hob() - return a pointer to the next HOB in the HOB list + * + * This macro returns a pointer to HOB that follows the HOB specified by hob + * in the HOB List. + * + * @hdr: A pointer to a HOB. + * + * @return: A pointer to the next HOB in the HOB list. + */ +static inline const struct hob_header *get_next_hob(const struct hob_header + *hdr) +{ + return (const struct hob_header *)((uintptr_t)hdr + hdr->len); +} + +/** + * end_of_hob() - determine if a HOB is the last HOB in the HOB list + * + * This macro determine if the HOB specified by hob is the last HOB in the + * HOB list. If hob is last HOB in the HOB list, then true is returned. + * Otherwise, false is returned. + * + * @hdr: A pointer to a HOB. + * + * @retval true: The HOB specified by hdr is the last HOB in the HOB list. + * @retval false: The HOB specified by hdr is not the last HOB in the HOB list. + */ +static inline bool end_of_hob(const struct hob_header *hdr) +{ + return hdr->type == HOB_TYPE_EOH; +} + +/** + * get_guid_hob_data() - return a pointer to data buffer from a HOB of + * type HOB_TYPE_GUID_EXT + * + * This macro returns a pointer to the data buffer in a HOB specified by hob. + * hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return: A pointer to the data buffer in a HOB. + */ +static inline void *get_guid_hob_data(const struct hob_header *hdr) +{ + return (void *)((uintptr_t)hdr + sizeof(struct hob_guid)); +} + +/** + * get_guid_hob_data_size() - return the size of the data buffer from a HOB + * of type HOB_TYPE_GUID_EXT + * + * This macro returns the size, in bytes, of the data buffer in a HOB + * specified by hob. hob is assumed to be a HOB of type HOB_TYPE_GUID_EXT. + * + * @hdr: A pointer to a HOB. + * + * @return: The size of the data buffer. + */ +static inline u16 get_guid_hob_data_size(const struct hob_header *hdr) +{ + return hdr->len - sizeof(struct hob_guid); +} + +/** + * Returns the next instance of a HOB type from the starting HOB. + * + * @type: HOB type to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching type; Otherwise NULL. + */ +const struct hob_header *hob_get_next_hob(uint type, const void *hob_list); + +/** + * Returns the next instance of the matched GUID HOB from the starting HOB. + * + * @guid: GUID to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching GUID; Otherwise NULL. + */ +const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid, + const void *hob_list); + +/** + * This function retrieves a GUID HOB data buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid A pointer to HOB GUID. + * + * @retval NULL: Failed to find the GUID HOB. + * @retval others: GUID HOB data buffer pointer. + */ +void *hob_get_guid_hob_data(const void *hob_list, u32 *len, + const efi_guid_t *guid); + +#endif /* __HOB_H__ */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 436252dd83..906be5eab9 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -42,6 +42,7 @@ obj-y += tables.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_CMD_ZBOOT) += zimage.o endif +obj-$(CONFIG_USE_HOB) += hob.o obj-$(CONFIG_HAVE_FSP) += fsp/ ifdef CONFIG_SPL_BUILD diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 270274f6b3..0d69cf271f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -337,6 +337,30 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg) header->checksum = table_compute_checksum((void *)mcfg, header->length); } +__weak u32 acpi_fill_csrt(u32 current) +{ + return current; +} + +static void acpi_create_csrt(struct acpi_csrt *csrt) +{ + struct acpi_table_header *header = &(csrt->header); + u32 current = (u32)csrt + sizeof(struct acpi_csrt); + + memset((void *)csrt, 0, sizeof(struct acpi_csrt)); + + /* Fill out header fields */ + acpi_fill_header(header, "CSRT"); + header->length = sizeof(struct acpi_csrt); + header->revision = 0; + + current = acpi_fill_csrt(current); + + /* (Re)calculate length and checksum */ + header->length = current - (u32)csrt; + header->checksum = table_compute_checksum((void *)csrt, header->length); +} + static void acpi_create_spcr(struct acpi_spcr *spcr) { struct acpi_table_header *header = &(spcr->header); @@ -464,6 +488,7 @@ ulong write_acpi_tables(ulong start) struct acpi_fadt *fadt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; + struct acpi_csrt *csrt; struct acpi_spcr *spcr; int i; @@ -553,6 +578,13 @@ ulong write_acpi_tables(ulong start) acpi_add_table(rsdp, mcfg); current = ALIGN(current, 16); + debug("ACPI: * CSRT\n"); + csrt = (struct acpi_csrt *)current; + acpi_create_csrt(csrt); + current += csrt->header.length; + acpi_add_table(rsdp, csrt); + current = ALIGN(current, 16); + debug("ACPI: * SPCR\n"); spcr = (struct acpi_spcr *)current; acpi_create_spcr(spcr); diff --git a/arch/x86/lib/asm-offsets.c b/arch/x86/lib/asm-offsets.c index 90dce22b25..47b38cd9e7 100644 --- a/arch/x86/lib/asm-offsets.c +++ b/arch/x86/lib/asm-offsets.c @@ -17,7 +17,7 @@ int main(void) { DEFINE(GD_BIST, offsetof(gd_t, arch.bist)); -#ifdef CONFIG_HAVE_FSP +#ifdef CONFIG_USE_HOB DEFINE(GD_HOB_LIST, offsetof(gd_t, arch.hob_list)); #endif DEFINE(GD_TABLE, offsetof(gd_t, arch.table)); diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 90e4e7db26..0eaa9b232b 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -8,27 +8,6 @@ #include <asm/fsp/fsp_support.h> #include <asm/post.h> -/** - * Compares two GUIDs - * - * If the GUIDs are identical then true is returned. - * If there are any bit differences in the two GUIDs, then false is returned. - * - * @guid1: A pointer to a 128 bit GUID. - * @guid2: A pointer to a 128 bit GUID. - * - * @retval true: guid1 and guid2 are identical. - * @retval false: guid1 and guid2 are not identical. - */ -static bool compare_guid(const struct efi_guid *guid1, - const struct efi_guid *guid2) -{ - if (memcmp(guid1, guid2, sizeof(struct efi_guid)) == 0) - return true; - else - return false; -} - struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void) { /* @@ -58,17 +37,22 @@ struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void) /* Check the FFS GUID */ if (fsp && - ((struct ffs_file_header *)fsp)->name.data1 == FSP_GUID_DATA1 && - ((struct ffs_file_header *)fsp)->name.data2 == FSP_GUID_DATA2 && - ((struct ffs_file_header *)fsp)->name.data3 == FSP_GUID_DATA3 && - ((struct ffs_file_header *)fsp)->name.data4[0] == FSP_GUID_DATA4_0 && - ((struct ffs_file_header *)fsp)->name.data4[1] == FSP_GUID_DATA4_1 && - ((struct ffs_file_header *)fsp)->name.data4[2] == FSP_GUID_DATA4_2 && - ((struct ffs_file_header *)fsp)->name.data4[3] == FSP_GUID_DATA4_3 && - ((struct ffs_file_header *)fsp)->name.data4[4] == FSP_GUID_DATA4_4 && - ((struct ffs_file_header *)fsp)->name.data4[5] == FSP_GUID_DATA4_5 && - ((struct ffs_file_header *)fsp)->name.data4[6] == FSP_GUID_DATA4_6 && - ((struct ffs_file_header *)fsp)->name.data4[7] == FSP_GUID_DATA4_7) { + ((struct ffs_file_header *)fsp)->name.b[0] == FSP_GUID_BYTE0 && + ((struct ffs_file_header *)fsp)->name.b[1] == FSP_GUID_BYTE1 && + ((struct ffs_file_header *)fsp)->name.b[2] == FSP_GUID_BYTE2 && + ((struct ffs_file_header *)fsp)->name.b[3] == FSP_GUID_BYTE3 && + ((struct ffs_file_header *)fsp)->name.b[4] == FSP_GUID_BYTE4 && + ((struct ffs_file_header *)fsp)->name.b[5] == FSP_GUID_BYTE5 && + ((struct ffs_file_header *)fsp)->name.b[6] == FSP_GUID_BYTE6 && + ((struct ffs_file_header *)fsp)->name.b[7] == FSP_GUID_BYTE7 && + ((struct ffs_file_header *)fsp)->name.b[8] == FSP_GUID_BYTE8 && + ((struct ffs_file_header *)fsp)->name.b[9] == FSP_GUID_BYTE9 && + ((struct ffs_file_header *)fsp)->name.b[10] == FSP_GUID_BYTE10 && + ((struct ffs_file_header *)fsp)->name.b[11] == FSP_GUID_BYTE11 && + ((struct ffs_file_header *)fsp)->name.b[12] == FSP_GUID_BYTE12 && + ((struct ffs_file_header *)fsp)->name.b[13] == FSP_GUID_BYTE13 && + ((struct ffs_file_header *)fsp)->name.b[14] == FSP_GUID_BYTE14 && + ((struct ffs_file_header *)fsp)->name.b[15] == FSP_GUID_BYTE15) { /* Add the FFS header size to find the raw section header */ fsp += sizeof(struct ffs_file_header); } else { @@ -305,7 +289,7 @@ u64 fsp_get_usable_highmem_top(const void *hob_list) } u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len, - struct efi_guid *guid) + const efi_guid_t *guid) { const struct hob_header *hdr; struct hob_res_desc *res_desc; @@ -318,7 +302,7 @@ u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len, if (hdr->type == HOB_TYPE_RES_DESC) { res_desc = (struct hob_res_desc *)hdr; if (res_desc->type == RES_MEM_RESERVED) { - if (compare_guid(&res_desc->owner, guid)) { + if (!guidcmp(&res_desc->owner, guid)) { if (len) *len = (u32)(res_desc->len); @@ -334,12 +318,12 @@ u64 fsp_get_reserved_mem_from_guid(const void *hob_list, u64 *len, u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len) { - const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID; + const efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_FSP_GUID; u64 length; u32 base; base = (u32)fsp_get_reserved_mem_from_guid(hob_list, - &length, (struct efi_guid *)&guid); + &length, &guid); if ((len != 0) && (base != 0)) *len = (u32)length; @@ -348,86 +332,35 @@ u32 fsp_get_fsp_reserved_mem(const void *hob_list, u32 *len) u32 fsp_get_tseg_reserved_mem(const void *hob_list, u32 *len) { - const struct efi_guid guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID; + const efi_guid_t guid = FSP_HOB_RESOURCE_OWNER_TSEG_GUID; u64 length; u32 base; base = (u32)fsp_get_reserved_mem_from_guid(hob_list, - &length, (struct efi_guid *)&guid); + &length, &guid); if ((len != 0) && (base != 0)) *len = (u32)length; return base; } -const struct hob_header *fsp_get_next_hob(uint type, const void *hob_list) -{ - const struct hob_header *hdr; - - hdr = hob_list; - - /* Parse the HOB list until end of list or matching type is found */ - while (!end_of_hob(hdr)) { - if (hdr->type == type) - return hdr; - - hdr = get_next_hob(hdr); - } - - return NULL; -} - -const struct hob_header *fsp_get_next_guid_hob(const struct efi_guid *guid, - const void *hob_list) -{ - const struct hob_header *hdr; - struct hob_guid *guid_hob; - - hdr = hob_list; - while ((hdr = fsp_get_next_hob(HOB_TYPE_GUID_EXT, - hdr)) != NULL) { - guid_hob = (struct hob_guid *)hdr; - if (compare_guid(guid, &(guid_hob->name))) - break; - hdr = get_next_hob(hdr); - } - - return hdr; -} - -void *fsp_get_guid_hob_data(const void *hob_list, u32 *len, - struct efi_guid *guid) -{ - const struct hob_header *guid_hob; - - guid_hob = fsp_get_next_guid_hob(guid, hob_list); - if (guid_hob == NULL) { - return NULL; - } else { - if (len) - *len = get_guid_hob_data_size(guid_hob); - - return get_guid_hob_data(guid_hob); - } -} - void *fsp_get_nvs_data(const void *hob_list, u32 *len) { - const struct efi_guid guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; + const efi_guid_t guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID; - return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); + return hob_get_guid_hob_data(hob_list, len, &guid); } void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len) { - const struct efi_guid guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID; + const efi_guid_t guid = FSP_BOOTLOADER_TEMP_MEM_HOB_GUID; - return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); + return hob_get_guid_hob_data(hob_list, len, &guid); } void *fsp_get_graphics_info(const void *hob_list, u32 *len) { - const struct efi_guid guid = FSP_GRAPHICS_INFO_HOB_GUID; + const efi_guid_t guid = FSP_GRAPHICS_INFO_HOB_GUID; - return fsp_get_guid_hob_data(hob_list, len, (struct efi_guid *)&guid); + return hob_get_guid_hob_data(hob_list, len, &guid); } diff --git a/arch/x86/lib/hob.c b/arch/x86/lib/hob.c new file mode 100644 index 0000000000..dcee29b04c --- /dev/null +++ b/arch/x86/lib/hob.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Intel +/* + * Copyright (C) 2013, Intel Corporation + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <asm/hob.h> + +/** + * Returns the next instance of a HOB type from the starting HOB. + * + * @type: HOB type to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching type; Otherwise NULL. + */ +const struct hob_header *hob_get_next_hob(uint type, const void *hob_list) +{ + const struct hob_header *hdr; + + hdr = hob_list; + + /* Parse the HOB list until end of list or matching type is found */ + while (!end_of_hob(hdr)) { + if (hdr->type == type) + return hdr; + + hdr = get_next_hob(hdr); + } + + return NULL; +} + +/** + * Returns the next instance of the matched GUID HOB from the starting HOB. + * + * @guid: GUID to search + * @hob_list: A pointer to the HOB list + * + * @retval: A HOB object with matching GUID; Otherwise NULL. + */ +const struct hob_header *hob_get_next_guid_hob(const efi_guid_t *guid, + const void *hob_list) +{ + const struct hob_header *hdr; + struct hob_guid *guid_hob; + + hdr = hob_list; + while ((hdr = hob_get_next_hob(HOB_TYPE_GUID_EXT, hdr))) { + guid_hob = (struct hob_guid *)hdr; + if (!guidcmp(guid, &guid_hob->name)) + break; + hdr = get_next_hob(hdr); + } + + return hdr; +} + +/** + * This function retrieves a GUID HOB data buffer and size. + * + * @hob_list: A HOB list pointer. + * @len: A pointer to the GUID HOB data buffer length. + * If the GUID HOB is located, the length will be updated. + * @guid A pointer to HOB GUID. + * + * @retval NULL: Failed to find the GUID HOB. + * @retval others: GUID HOB data buffer pointer. + */ +void *hob_get_guid_hob_data(const void *hob_list, u32 *len, + const efi_guid_t *guid) +{ + const struct hob_header *guid_hob; + + guid_hob = hob_get_next_guid_hob(guid, hob_list); + if (!guid_hob) + return NULL; + + if (len) + *len = get_guid_hob_data_size(guid_hob); + + return get_guid_hob_data(guid_hob); +} diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index 0481f453ca..5e19f13720 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -18,7 +18,8 @@ __weak ulong board_get_usable_ram_top(ulong total_size) int init_cache_f_r(void) { -#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) +#if CONFIG_IS_ENABLED(X86_32BIT_INIT) && !defined(CONFIG_HAVE_FSP) && \ + !defined(CONFIG_SYS_SLIMBOOTLOADER) int ret; ret = mtrr_commit(false); diff --git a/board/intel/Kconfig b/board/intel/Kconfig index 5131836cb0..7b16ec4dc1 100644 --- a/board/intel/Kconfig +++ b/board/intel/Kconfig @@ -73,6 +73,19 @@ config TARGET_MINNOWMAX Note that PCIE_ECAM_BASE is set up by the FSP so the value used by U-Boot matches that value. +config TARGET_SLIMBOOTLOADER + bool "slimbootloader" + help + This target is used for running U-Boot on top of Slim Bootloader + boot firmware as a payload. Slim Bootloader does memory initialization + and silicon initialization, and it passes necessary information in + HOB (Hand Off Block) to a payload. The payload consumes HOB data + which is generated by Slim Bootloader for its driver initialization. + Slim Bootloader consumes FSP and its HOB, but FSP HOB is cleared + Before launching a payload. Instead, Slim Bootloader generates its + HOB data such as memory info, serial port info and so on. + Refer to doc/board/intel/slimbootloader.rst for the details. + endchoice source "board/intel/bayleybay/Kconfig" @@ -82,5 +95,6 @@ source "board/intel/crownbay/Kconfig" source "board/intel/edison/Kconfig" source "board/intel/galileo/Kconfig" source "board/intel/minnowmax/Kconfig" +source "board/intel/slimbootloader/Kconfig" endif diff --git a/board/intel/edison/edison.c b/board/intel/edison/edison.c index 5faf3c57f2..d80ee3aa8a 100644 --- a/board/intel/edison/edison.c +++ b/board/intel/edison/edison.c @@ -13,9 +13,19 @@ #include <linux/usb/gadget.h> #include <asm/cache.h> +#include <asm/pmu.h> #include <asm/scu.h> #include <asm/u-boot-x86.h> +/* List of Intel Tangier LSSs */ +#define PMU_LSS_TANGIER_SDIO0_01 1 + +int board_early_init_r(void) +{ + pmu_turn_power(PMU_LSS_TANGIER_SDIO0_01, true); + return 0; +} + static struct dwc3_device dwc3_device_data = { .maximum_speed = USB_SPEED_HIGH, .base = CONFIG_SYS_USB_OTG_BASE, diff --git a/board/intel/slimbootloader/Kconfig b/board/intel/slimbootloader/Kconfig new file mode 100644 index 0000000000..8c7e22cc33 --- /dev/null +++ b/board/intel/slimbootloader/Kconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Intel Corporation <www.intel.com> + +if TARGET_SLIMBOOTLOADER + +config SYS_BOARD + default "slimbootloader" + +config SYS_VENDOR + default "intel" + +config SYS_SOC + default "slimbootloader" + +config SYS_CONFIG_NAME + default "slimbootloader" + +config SYS_TEXT_BASE + default 0x00100000 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select SYS_SLIMBOOTLOADER + select USB_STORAGE + select USB_KEYBOARD + +endif diff --git a/board/intel/slimbootloader/MAINTAINERS b/board/intel/slimbootloader/MAINTAINERS new file mode 100644 index 0000000000..e6935517e0 --- /dev/null +++ b/board/intel/slimbootloader/MAINTAINERS @@ -0,0 +1,6 @@ +Intel Slim Bootloader Payload +M: Aiden Park <aiden.park@intel.com> +S: Maintained +F: board/intel/slimbootloader +F: include/configs/slimbootloader.h +F: configs/slimbootloader_defconfig diff --git a/board/intel/slimbootloader/Makefile b/board/intel/slimbootloader/Makefile new file mode 100644 index 0000000000..fd8fa98a8d --- /dev/null +++ b/board/intel/slimbootloader/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Intel Corporation <www.intel.com> + +obj-y += start.o slimbootloader.o diff --git a/board/intel/slimbootloader/slimbootloader.c b/board/intel/slimbootloader/slimbootloader.c new file mode 100644 index 0000000000..f50eeb823f --- /dev/null +++ b/board/intel/slimbootloader/slimbootloader.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#include <common.h> + +int board_early_init_r(void) +{ + /* + * Make sure PCI bus is enumerated so that peripherals on the PCI bus + * can be discovered by their drivers. + * + * Slim Bootloader has already done PCI bus enumeration before loading + * U-Boot, so U-Boot needs to preserve PCI configuration. + * Therefore, '# CONFIG_PCI_PNP is not set' is included in defconfig. + */ + pci_init(); + + return 0; +} diff --git a/board/intel/slimbootloader/start.S b/board/intel/slimbootloader/start.S new file mode 100644 index 0000000000..5c3f3df09e --- /dev/null +++ b/board/intel/slimbootloader/start.S @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +/* board early initialization */ +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/board/toradex/apalis-tk1/apalis-tk1.c b/board/toradex/apalis-tk1/apalis-tk1.c index b87e9e7a3e..beb7e10dfe 100644 --- a/board/toradex/apalis-tk1/apalis-tk1.c +++ b/board/toradex/apalis-tk1/apalis-tk1.c @@ -10,6 +10,7 @@ #include <asm/io.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> +#include <environment.h> #include <pci_tegra.h> #include <power/as3722.h> #include <power/pmic.h> @@ -19,11 +20,16 @@ #define LAN_DEV_OFF_N TEGRA_GPIO(O, 6) #define LAN_RESET_N TEGRA_GPIO(S, 2) +#define FAN_EN TEGRA_GPIO(DD, 2) #define LAN_WAKE_N TEGRA_GPIO(O, 5) #ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT #define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */ #define RESET_MOCI_CTRL TEGRA_GPIO(U, 4) #endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ +#define VCC_USBH TEGRA_GPIO(T, 6) +#define VCC_USBH_V1_0 TEGRA_GPIO(N, 5) +#define VCC_USBO1 TEGRA_GPIO(T, 5) +#define VCC_USBO1_V1_0 TEGRA_GPIO(N, 4) int arch_misc_init(void) { @@ -31,6 +37,38 @@ int arch_misc_init(void) NVBOOTTYPE_RECOVERY) printf("USB recovery mode\n"); + /* PCB Version Indication: V1.2 and later have GPIO_PV0 wired to GND */ + gpio_request(TEGRA_GPIO(V, 0), "PCB Version Indication"); + gpio_direction_input(TEGRA_GPIO(V, 0)); + if (gpio_get_value(TEGRA_GPIO(V, 0))) { + /* + * if using the default device tree for new V1.2 and later HW, + * use version for older V1.0 and V1.1 HW + */ + char *fdt_env = env_get("fdt_module"); + + if (fdt_env && !strcmp(FDT_MODULE, fdt_env)) { + env_set("fdt_module", FDT_MODULE_V1_0); + printf("patching fdt_module to " FDT_MODULE_V1_0 + " for older V1.0 and V1.1 HW\n"); +#ifndef CONFIG_ENV_IS_NOWHERE + env_save(); +#endif + } + + /* activate USB power enable GPIOs */ + gpio_request(VCC_USBH_V1_0, "VCC_USBH"); + gpio_direction_output(VCC_USBH_V1_0, 1); + gpio_request(VCC_USBO1_V1_0, "VCC_USBO1"); + gpio_direction_output(VCC_USBO1_V1_0, 1); + } else { + /* activate USB power enable GPIOs */ + gpio_request(VCC_USBH, "VCC_USBH"); + gpio_direction_output(VCC_USBH, 1); + gpio_request(VCC_USBO1, "VCC_USBO1"); + gpio_direction_output(VCC_USBO1, 1); + } + return 0; } @@ -242,6 +280,15 @@ void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) #endif /* CONFIG_PCI_TEGRA */ /* + * Enable/start PWM CPU fan + */ +void start_cpu_fan(void) +{ + gpio_request(FAN_EN, "FAN_EN"); + gpio_direction_output(FAN_EN, 1); +} + +/* * Backlight off before OS handover */ void board_preboot_os(void) diff --git a/board/toradex/apalis-tk1/as3722_init.c b/board/toradex/apalis-tk1/as3722_init.c index bd754e5fcf..15f8dce2f1 100644 --- a/board/toradex/apalis-tk1/as3722_init.c +++ b/board/toradex/apalis-tk1/as3722_init.c @@ -43,6 +43,29 @@ void pmic_enable_cpu_vdd(void) udelay(10 * 1000); #endif + /* + * Make sure all non-fused regulators are down. + * That way we're in known state after software reboot from linux + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0003, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0004, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x001b, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0014, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x001a, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0019, I2C_SEND_2_BYTES); + udelay(10 * 1000); + debug("%s: Setting VDD_CPU to 1.0V via AS3722 reg 0/4D\n", __func__); /* * Bring up VDD_CPU via the AS3722 PMIC on the PWR I2C bus. diff --git a/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h b/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h index 1584d9b2d3..6778a41e07 100644 --- a/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h +++ b/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright (c) 2016, Toradex, Inc. + * Copyright (c) 2016-2019, Toradex, Inc. */ #ifndef _PINMUX_CONFIG_APALIS_TK1_H_ @@ -24,8 +24,6 @@ static const struct tegra_gpio_config apalis_tk1_gpio_inits[] = { GPIO_INIT(K, 2, IN), GPIO_INIT(K, 7, IN), GPIO_INIT(N, 2, OUT1), - GPIO_INIT(N, 4, OUT1), - GPIO_INIT(N, 5, OUT1), GPIO_INIT(N, 7, IN), GPIO_INIT(O, 5, IN), GPIO_INIT(Q, 0, OUT0), /* Shift_CTRL_OE[0] */ @@ -39,7 +37,8 @@ static const struct tegra_gpio_config apalis_tk1_gpio_inits[] = { GPIO_INIT(R, 1, OUT0), /* Shift_CTRL_Dir_In[1] */ GPIO_INIT(R, 2, OUT0), /* Shift_CTRL_OE[3] */ GPIO_INIT(S, 3, OUT0), /* Shift_CTRL_Dir_In[2] */ - GPIO_INIT(U, 4, OUT1), + GPIO_INIT(U, 4, OUT0), /* RESET_MOCI_CTRL */ + GPIO_INIT(V, 0, IN), GPIO_INIT(W, 3, IN), GPIO_INIT(W, 5, IN), GPIO_INIT(BB, 0, IN), @@ -130,8 +129,8 @@ static const struct pmux_pingrp_config apalis_tk1_pingrps[] = { PINCFG(DAP1_DIN_PN1, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(DAP1_DOUT_PN2, SATA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), PINCFG(DAP1_SCLK_PN3, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), - PINCFG(USB_VBUS_EN0_PN4, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), - PINCFG(USB_VBUS_EN1_PN5, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), + PINCFG(USB_VBUS_EN0_PN4, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + PINCFG(USB_VBUS_EN1_PN5, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), PINCFG(HDMI_INT_PN7, RSVD1, DOWN, TRISTATE, INPUT, DEFAULT, NORMAL), PINCFG(ULPI_DATA7_PO0, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(ULPI_DATA0_PO1, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), @@ -175,8 +174,8 @@ static const struct pmux_pingrp_config apalis_tk1_pingrps[] = { PINCFG(KB_ROW15_PS7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(KB_ROW16_PT0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(KB_ROW17_PT1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), - PINCFG(GEN2_I2C_SCL_PT5, I2C2, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), - PINCFG(GEN2_I2C_SDA_PT6, I2C2, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(GEN2_I2C_SCL_PT5, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), + PINCFG(GEN2_I2C_SDA_PT6, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), PINCFG(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), PINCFG(PU0, UARTA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), PINCFG(PU1, UARTA, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), @@ -185,12 +184,12 @@ static const struct pmux_pingrp_config apalis_tk1_pingrps[] = { PINCFG(PU4, GMI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), PINCFG(PU5, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(PU6, PWM3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), - PINCFG(PV0, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PV0, RSVD1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), PINCFG(PV1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), PINCFG(SDMMC3_CD_N_PV2, RSVD3, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), PINCFG(SDMMC1_WP_N_PV3, SDMMC1, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), - PINCFG(DDC_SCL_PV4, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), - PINCFG(DDC_SDA_PV5, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL), + PINCFG(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL), PINCFG(GPIO_W2_AUD_PW2, SPI2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), PINCFG(GPIO_W3_AUD_PW3, SPI6, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), PINCFG(DAP_MCLK1_PW4, EXTPERIPH1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), diff --git a/cmd/thordown.c b/cmd/thordown.c index 19ae6721d1..dd0544d475 100644 --- a/cmd/thordown.c +++ b/cmd/thordown.c @@ -37,7 +37,11 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) goto exit; } - g_dnl_register("usb_dnl_thor"); + ret = g_dnl_register("usb_dnl_thor"); + if (ret) { + pr_err("g_dnl_register failed %d\n", ret); + return ret; + } ret = thor_init(); if (ret) { diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile index 707161440d..144b1cf5ab 100644 --- a/cmd/x86/Makefile +++ b/cmd/x86/Makefile @@ -2,4 +2,5 @@ obj-y += mtrr.o obj-$(CONFIG_CMD_EXCEPTION) += exception.o +obj-$(CONFIG_USE_HOB) += hob.o obj-$(CONFIG_HAVE_FSP) += fsp.o diff --git a/cmd/x86/fsp.c b/cmd/x86/fsp.c index 9f94ca9876..efa183854b 100644 --- a/cmd/x86/fsp.c +++ b/cmd/x86/fsp.c @@ -9,21 +9,6 @@ DECLARE_GLOBAL_DATA_PTR; -static char *hob_type[] = { - "reserved", - "Hand-off", - "Mem Alloc", - "Res Desc", - "GUID Ext", - "FV", - "CPU", - "Mem Pool", - "reserved", - "FV2", - "Load PEIM", - "Capsule", -}; - static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct fsp_header *hdr = find_fsp_header(); @@ -72,57 +57,8 @@ static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -static int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - const struct hob_header *hdr; - uint type; - char *desc; - int i = 0; - - hdr = gd->arch.hob_list; - - printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr); - - printf("# | Address | Type | Len | "); - printf("%42s\n", "GUID"); - printf("---|----------|-----------|------|-"); - printf("------------------------------------------\n"); - while (!end_of_hob(hdr)) { - printf("%02x | %08x | ", i, (unsigned int)hdr); - type = hdr->type; - if (type == HOB_TYPE_UNUSED) - desc = "*Unused*"; - else if (type == HOB_TYPE_EOH) - desc = "*EOH*"; - else if (type >= 0 && type <= ARRAY_SIZE(hob_type)) - desc = hob_type[type]; - else - desc = "*Invalid*"; - printf("%-9s | %04x | ", desc, hdr->len); - - if (type == HOB_TYPE_MEM_ALLOC || type == HOB_TYPE_RES_DESC || - type == HOB_TYPE_GUID_EXT) { - struct efi_guid *guid = (struct efi_guid *)(hdr + 1); - int j; - - printf("%08x-%04x-%04x", guid->data1, - guid->data2, guid->data3); - for (j = 0; j < ARRAY_SIZE(guid->data4); j++) - printf("-%02x", guid->data4[j]); - } else { - printf("%42s", "Not Available"); - } - printf("\n"); - hdr = get_next_hob(hdr); - i++; - } - - return 0; -} - static cmd_tbl_t fsp_commands[] = { U_BOOT_CMD_MKENT(hdr, 0, 1, do_hdr, "", ""), - U_BOOT_CMD_MKENT(hob, 0, 1, do_hob, "", ""), }; static int do_fsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -146,6 +82,5 @@ static int do_fsp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fsp, 2, 1, do_fsp, "Show Intel Firmware Support Package (FSP) related information", - "hdr - Print FSP header information\n" - "fsp hob - Print FSP Hand-Off Block (HOB) information" + "hdr - Print FSP header information" ); diff --git a/cmd/x86/hob.c b/cmd/x86/hob.c new file mode 100644 index 0000000000..3967a7ca5a --- /dev/null +++ b/cmd/x86/hob.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <command.h> +#include <efi.h> +#include <asm/hob.h> + +DECLARE_GLOBAL_DATA_PTR; + +static char *hob_type[] = { + "reserved", + "Hand-off", + "Mem Alloc", + "Res Desc", + "GUID Ext", + "FV", + "CPU", + "Mem Pool", + "reserved", + "FV2", + "Load PEIM", + "Capsule", +}; + +static int do_hob(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const struct hob_header *hdr; + uint type; + char *desc; + int i = 0; + efi_guid_t *guid; + char uuid[UUID_STR_LEN + 1]; + + hdr = gd->arch.hob_list; + + printf("HOB list address: 0x%08x\n\n", (unsigned int)hdr); + + printf("# | Address | Type | Len | "); + printf("%36s\n", "GUID"); + printf("---|----------|-----------|------|-"); + printf("------------------------------------\n"); + while (!end_of_hob(hdr)) { + printf("%02x | %08x | ", i, (unsigned int)hdr); + type = hdr->type; + if (type == HOB_TYPE_UNUSED) + desc = "*Unused*"; + else if (type == HOB_TYPE_EOH) + desc = "*EOH*"; + else if (type >= 0 && type <= ARRAY_SIZE(hob_type)) + desc = hob_type[type]; + else + desc = "*Invalid*"; + printf("%-9s | %04x | ", desc, hdr->len); + + if (type == HOB_TYPE_MEM_ALLOC || type == HOB_TYPE_RES_DESC || + type == HOB_TYPE_GUID_EXT) { + guid = (efi_guid_t *)(hdr + 1); + uuid_bin_to_str(guid->b, uuid, UUID_STR_FORMAT_GUID); + printf("%s", uuid); + } else { + printf("%36s", "Not Available"); + } + printf("\n"); + hdr = get_next_hob(hdr); + i++; + } + + return 0; +} + +U_BOOT_CMD(hob, 1, 1, do_hob, + "Print Hand-Off Block (HOB) information", + "" +); diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig index 41f3aff149..be0554b150 100644 --- a/configs/apalis-tk1_defconfig +++ b/configs/apalis-tk1_defconfig @@ -8,7 +8,7 @@ CONFIG_TARGET_APALIS_TK1=y CONFIG_FIT=y CONFIG_OF_SYSTEM_SETUP=y CONFIG_BOOTDELAY=1 -CONFIG_BOOTCOMMAND="run emmcboot; setenv fdtfile ${soc}-apalis-${fdt_board}.dtb && run distro_bootcmd" +CONFIG_BOOTCOMMAND="run emmcboot; setenv fdtfile ${soc}-${fdt-module}-${fdt_board}.dtb && run distro_bootcmd" CONFIG_CONSOLE_MUX=y CONFIG_SYS_STDIO_DEREGISTER=y CONFIG_VERSION_VARIABLE=y @@ -17,7 +17,6 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_SPL_TEXT_BASE=0x80108000 CONFIG_SYS_PROMPT="Apalis TK1 # " # CONFIG_CMD_IMI is not set -CONFIG_CMD_DFU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y @@ -34,8 +33,6 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra124-apalis" CONFIG_IP_DEFRAG=y CONFIG_TFTP_BLOCKSIZE=16352 CONFIG_SPL_DM=y -CONFIG_DFU_MMC=y -CONFIG_DFU_RAM=y CONFIG_SYS_I2C_TEGRA=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_TEGRA124_MMC_DISABLE_EXT_LOOPBACK=y @@ -56,7 +53,7 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_MANUFACTURER="Toradex" CONFIG_USB_GADGET_VENDOR_NUM=0x1b67 -CONFIG_USB_GADGET_PRODUCT_NUM=0xffff +CONFIG_USB_GADGET_PRODUCT_NUM=0x4000 CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/apalis_t30_defconfig b/configs/apalis_t30_defconfig index cf4d14434d..75b5a1dca3 100644 --- a/configs/apalis_t30_defconfig +++ b/configs/apalis_t30_defconfig @@ -14,7 +14,6 @@ CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_TEXT_BASE=0x80108000 CONFIG_SYS_PROMPT="Apalis T30 # " # CONFIG_CMD_IMI is not set -CONFIG_CMD_DFU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y @@ -31,8 +30,6 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra30-apalis" CONFIG_IP_DEFRAG=y CONFIG_TFTP_BLOCKSIZE=16352 CONFIG_SPL_DM=y -CONFIG_DFU_MMC=y -CONFIG_DFU_RAM=y CONFIG_SYS_I2C_TEGRA=y CONFIG_E1000=y CONFIG_PCI=y diff --git a/configs/colibri_t20_defconfig b/configs/colibri_t20_defconfig index 170a1b0b27..73d13bbb06 100644 --- a/configs/colibri_t20_defconfig +++ b/configs/colibri_t20_defconfig @@ -13,7 +13,6 @@ CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_TEXT_BASE=0x00108000 CONFIG_SYS_PROMPT="Colibri T20 # " # CONFIG_CMD_IMI is not set -CONFIG_CMD_DFU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y @@ -39,8 +38,6 @@ CONFIG_ENV_IS_IN_NAND=y CONFIG_IP_DEFRAG=y CONFIG_TFTP_BLOCKSIZE=1536 CONFIG_SPL_DM=y -CONFIG_DFU_MMC=y -CONFIG_DFU_RAM=y CONFIG_SYS_I2C_TEGRA=y CONFIG_MTD=y CONFIG_MTD_UBI_FASTMAP=y diff --git a/configs/colibri_t30_defconfig b/configs/colibri_t30_defconfig index 769f6f3c9e..1e2268a105 100644 --- a/configs/colibri_t30_defconfig +++ b/configs/colibri_t30_defconfig @@ -14,7 +14,6 @@ CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_TEXT_BASE=0x80108000 CONFIG_SYS_PROMPT="Colibri T30 # " # CONFIG_CMD_IMI is not set -CONFIG_CMD_DFU=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y @@ -30,8 +29,6 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra30-colibri" CONFIG_IP_DEFRAG=y CONFIG_TFTP_BLOCKSIZE=16352 CONFIG_SPL_DM=y -CONFIG_DFU_MMC=y -CONFIG_DFU_RAM=y CONFIG_SYS_I2C_TEGRA=y CONFIG_SYS_NS16550=y CONFIG_USB=y diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index a161ad5e02..7cbc9fb656 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -65,6 +65,8 @@ CONFIG_SPI_FLASH_MTD=y CONFIG_DM_ETH=y CONFIG_MII=y CONFIG_DRIVER_TI_EMAC=y +CONFIG_PHY=y +CONFIG_PHY_DA8XX_USB=y CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_DM_SERIAL=y @@ -77,5 +79,8 @@ CONFIG_DM_USB=y # CONFIG_SPL_DM_USB is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_DA8XX=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_DA8XX=y +CONFIG_USB_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=y # CONFIG_FAT_WRITE is not set diff --git a/configs/da850evm_direct_nor_defconfig b/configs/da850evm_direct_nor_defconfig index e3c2d13986..2eaa29fb8f 100644 --- a/configs/da850evm_direct_nor_defconfig +++ b/configs/da850evm_direct_nor_defconfig @@ -54,6 +54,8 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_MII=y CONFIG_DRIVER_TI_EMAC=y +CONFIG_PHY=y +CONFIG_PHY_DA8XX_USB=y CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_SPECIFY_CONSOLE_INDEX=y @@ -67,4 +69,7 @@ CONFIG_DM_USB=y # CONFIG_SPL_DM_USB is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_DA8XX=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_DA8XX=y +CONFIG_USB_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=y diff --git a/configs/da850evm_nand_defconfig b/configs/da850evm_nand_defconfig index 96602e514a..7f0ea0c7e4 100644 --- a/configs/da850evm_nand_defconfig +++ b/configs/da850evm_nand_defconfig @@ -61,6 +61,8 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y CONFIG_DM_ETH=y +CONFIG_PHY=y +CONFIG_PHY_DA8XX_USB=y CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_DM_SERIAL=y @@ -73,6 +75,9 @@ CONFIG_DM_USB=y # CONFIG_SPL_DM_USB is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_DA8XX=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_DA8XX=y +CONFIG_USB_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=y # CONFIG_FAT_WRITE is not set CONFIG_USE_TINY_PRINTF=y diff --git a/configs/edison_defconfig b/configs/edison_defconfig index 468754493e..cac6e4201f 100644 --- a/configs/edison_defconfig +++ b/configs/edison_defconfig @@ -4,6 +4,7 @@ CONFIG_NR_DRAM_BANKS=3 CONFIG_VENDOR_INTEL=y CONFIG_TARGET_EDISON=y CONFIG_SMP=y +CONFIG_BOARD_EARLY_INIT_R=y CONFIG_LAST_STAGE_INIT=y CONFIG_HUSH_PARSER=y # CONFIG_CMDLINE_EDITING is not set diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig index 532611f4a9..53d9c8cf82 100644 --- a/configs/qemu-x86_64_defconfig +++ b/configs/qemu-x86_64_defconfig @@ -12,6 +12,7 @@ CONFIG_SMP=y CONFIG_GENERATE_PIRQ_TABLE=y CONFIG_GENERATE_MP_TABLE=y CONFIG_GENERATE_ACPI_TABLE=y +CONFIG_DISTRO_DEFAULTS=y CONFIG_BUILD_ROM=y CONFIG_FIT=y CONFIG_SPL_LOAD_FIT=y diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig index ef85c52592..ad56135401 100644 --- a/configs/qemu-x86_defconfig +++ b/configs/qemu-x86_defconfig @@ -6,6 +6,7 @@ CONFIG_SMP=y CONFIG_GENERATE_PIRQ_TABLE=y CONFIG_GENERATE_MP_TABLE=y CONFIG_GENERATE_ACPI_TABLE=y +CONFIG_DISTRO_DEFAULTS=y CONFIG_BUILD_ROM=y CONFIG_FIT=y CONFIG_BOOTSTAGE=y diff --git a/configs/slimbootloader_defconfig b/configs/slimbootloader_defconfig new file mode 100644 index 0000000000..b16ed71469 --- /dev/null +++ b/configs/slimbootloader_defconfig @@ -0,0 +1,22 @@ +CONFIG_X86=y +CONFIG_VENDOR_INTEL=y +CONFIG_TARGET_SLIMBOOTLOADER=y +CONFIG_DEFAULT_DEVICE_TREE="slimbootloader" +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_LAST_STAGE_INIT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_MMC=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_FAT=y +CONFIG_CMD_USB=y +CONFIG_DOS_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_OF_CONTROL=y +CONFIG_BOOTSTAGE=y +CONFIG_BOOTSTAGE_REPORT=y +CONFIG_BOOTDELAY=10 +CONFIG_CONSOLE_SCROLL_LINES=5 +# CONFIG_PCI_PNP is not set diff --git a/doc/android/fastboot.txt b/doc/android/fastboot.txt index ea0d1da1fd..9de13223f8 100644 --- a/doc/android/fastboot.txt +++ b/doc/android/fastboot.txt @@ -169,9 +169,9 @@ On the client side you can fetch the bootloader version for instance: :: - $ fastboot getvar bootloader-version - bootloader-version: U-Boot 2014.04-00005-gd24cabc - finished. total time: 0.000s + $ fastboot getvar version-bootloader + version-bootloader: U-Boot 2019.07-rc4-00240-g00c9f2a2ec + Finished. Total time: 0.005s or initiate a reboot: diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst index c2e704afb2..db842f2ece 100644 --- a/doc/board/emulation/qemu-x86.rst +++ b/doc/board/emulation/qemu-x86.rst @@ -54,6 +54,23 @@ If you want to check both consoles, use '-serial stdio'. Multicore is also supported by QEMU via '-smp n' where n is the number of cores to instantiate. Note, the maximum supported CPU number in QEMU is 255. +U-Boot uses 'distro_bootcmd' by default when booting on x86 QEMU. This tries to +load a boot script, kernel, and ramdisk from several different interfaces. For +the default boot order, see 'qemu-x86.h'. For more information, see +'README.distro'. Most Linux distros can be booted by writing a uboot script. +For example, Debian (stretch) can be booted by creating a script file named +'boot.txt' with the contents:: + + setenv bootargs root=/dev/sda1 ro + load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /vmlinuz + load ${devtype} ${devnum}:${distro_bootpart} ${ramdisk_addr_r} /initrd.img + zboot ${kernel_addr_r} - ${ramdisk_addr_r} ${filesize} + +Then compile and install it with:: + + $ apt install u-boot-tools && \ + mkimage -T script -C none -n "Boot script" -d boot.txt /boot/boot.scr + The fw_cfg interface in QEMU also provides information about kernel data, initrd, command-line arguments and more. U-Boot supports directly accessing these informtion from fw_cfg interface, which saves the time of loading them diff --git a/doc/board/intel/index.rst b/doc/board/intel/index.rst index f416801910..f545dee87a 100644 --- a/doc/board/intel/index.rst +++ b/doc/board/intel/index.rst @@ -13,3 +13,4 @@ Intel edison galileo minnowmax + slimbootloader diff --git a/doc/board/intel/slimbootloader.rst b/doc/board/intel/slimbootloader.rst new file mode 100644 index 0000000000..4a46fed069 --- /dev/null +++ b/doc/board/intel/slimbootloader.rst @@ -0,0 +1,174 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Aiden Park <aiden.park@intel.com> + +Slim Bootloader +=============== + +Introduction +------------ + +This target is to enable U-Boot_ as a payload of `Slim Bootloader`_ (a.k.a SBL) +boot firmware which currently supports QEMU, Apollolake, Whiskeylake, +Coffeelake-R platforms. + +The `Slim Bootloader`_ is designed with multi-stages (Stage1A/B, Stage2, Payload) +architecture to cover from reset vector to OS booting and it consumes +`Intel FSP`_ for silicon initialization. + +* Stage1A: Reset vector, CAR init with FSP-T +* Stage1B: Memory init with FSP-M, CAR teardown, Continue execution in memory +* Stage2 : Rest of Silicon init with FSP-S, Create HOB, Hand-off to Payload +* Payload: Payload init with HOB, Load OS from media, Booting OS + +The Slim Bootloader stages (Stage1A/B, Stage2) focus on chipset, hardware and +platform specific initialization, and it provides useful information to a +payload in a HOB (Hand-Off Block) which has serial port, memory map, performance +data info and so on. This is Slim Bootloader architectural design to make a +payload light-weight, platform independent and more generic across different +boot solutions or payloads, and to minimize hardware re-initialization in a +payload. + +Build Instruction for U-Boot as a Slim Bootloader payload +--------------------------------------------------------- + +Build U-Boot and obtain u-boot-dtb.bin:: + + $ make distclean + $ make slimbootloader_defconfig + $ make all + +Prepare Slim Bootloader +----------------------- + +1. Setup Build Environment for Slim Bootloader. + + Refer to `Getting Started`_ page in `Slim Bootloader`_ document site. + +2. Get source code. Let's simply clone the repo:: + + $ git clone https://github.com/slimbootloader/slimbootloader.git + +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 + +Build Instruction for Slim Bootloader for QEMU target +----------------------------------------------------- + +Slim Bootloader supports multiple payloads, and a board of Slim Bootloader +detects its target payload by PayloadId in board configuration. +The PayloadId can be any 4 Bytes value. + +1. Update PayloadId. Let's use 'U-BT' as an example:: + + $ vi Platform/QemuBoardPkg/CfgData/CfgDataExt_Brd1.dlt + -GEN_CFG_DATA.PayloadId | 'AUTO' + +GEN_CFG_DATA.PayloadId | 'U-BT' + +2. Update payload text base. PAYLOAD_EXE_BASE must be the same as U-Boot + CONFIG_SYS_TEXT_BASE in board/intel/slimbootloader/Kconfig. + PAYLOAD_LOAD_HIGH must be 0:: + + $ vi Platform/QemuBoardPkg/BoardConfig.py + + self.PAYLOAD_LOAD_HIGH = 0 + + self.PAYLOAD_EXE_BASE = 0x00100000 + +3. Build QEMU target. Make sure u-boot-dtb.bin and U-BT PayloadId + in build command. The output is Outputs/qemu/SlimBootloader.bin:: + + $ python BuildLoader.py build qemu -p "OsLoader.efi:LLDR:Lz4;u-boot-dtb.bin:U-BT:Lzma" + +4. Launch Slim Bootloader on QEMU. + You should reach at U-Boot serial console:: + + $ qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Outputs/qemu/SlimBootloader.bin + +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. + +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:: + + $ vi Platform/ApollolakeBoardPkg/CfgData/CfgData_Int_LeafHill.dlt + -GEN_CFG_DATA.PayloadId | 'AUTO + +GEN_CFG_DATA.PayloadId | 'U-BT' + +5. Update payload text base. + +* PAYLOAD_EXE_BASE must be the same as U-Boot CONFIG_SYS_TEXT_BASE + in board/intel/slimbootloader/Kconfig. +* PAYLOAD_LOAD_HIGH must be 0:: + + $ vi Platform/ApollolakeBoardPkg/BoardConfig.py + + self.PAYLOAD_LOAD_HIGH = 0 + + self.PAYLOAD_EXE_BASE = 0x00100000 + +6. 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. + + 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. + + Use DediProg to flash IFWI. You should reach at U-Boot serial console. + + +Build Instruction to use ELF U-Boot +----------------------------------- + +1. Enable CONFIG_OF_EMBED:: + + $ vi configs/slimbootloader_defconfig + +CONFIG_OF_EMBED=y + +2. Build U-Boot:: + + $ make disclean + $ make slimbootloader_defconfig + $ make all + $ strip u-boot (removing symbol for reduced size) + +3. Do same steps as above + +* Copy u-boot (ELF) to PayloadBins directory +* Update PayloadId 'U-BT' as above. +* No need to set PAYLOAD_LOAD_HIGH and PAYLOAD_EXE_BASE. +* Build Slim Bootloader. Use u-boot instead of u-boot-dtb.bin:: + + $ python BuildLoader.py build <qemu or apl> -p "OsLoader.efi:LLDR:Lz4;u-boot:U-BT:Lzma" + +.. _U-Boot: https://gitlab.denx.de/ +.. _`Slim Bootloader`: https://github.com/slimbootloader/ +.. _`Intel FSP`: https://github.com/IntelFsp/ +.. _`Getting Started`: https://slimbootloader.github.io/getting-started/ +.. _Apollolake: https://slimbootloader.github.io/supported-hardware/apollo-lake-crb.html#stitching diff --git a/doc/device-tree-bindings/sound/intel-hda.txt b/doc/device-tree-bindings/sound/intel-hda.txt index fb2ce55006..aa96be06e9 100644 --- a/doc/device-tree-bindings/sound/intel-hda.txt +++ b/doc/device-tree-bindings/sound/intel-hda.txt @@ -12,6 +12,7 @@ Required properties: Optional properties - intel,beep-nid: Node ID to use for beep (will be detected if not provided) +- codec-enable-gpio : The GPIO used to enable the audio codec Required subnodes: - codecs: Contains a list of codec nodes diff --git a/doc/device-tree-bindings/sound/nvidia,tegra-audio-max98090.txt b/doc/device-tree-bindings/sound/nvidia,tegra-audio-max98090.txt new file mode 100644 index 0000000000..25c63eac62 --- /dev/null +++ b/doc/device-tree-bindings/sound/nvidia,tegra-audio-max98090.txt @@ -0,0 +1,54 @@ +NVIDIA Tegra audio complex, with MAX98090 CODEC + +Required properties: +- compatible : "nvidia,tegra-audio-max98090" +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) +- nvidia,model : The user-visible name of this sound complex. +- nvidia,audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the connection's sink, + the second being the connection's source. Valid names for sources and + sinks are the MAX98090's pins (as documented in its binding), and the jacks + on the board: + + * Headphones + * Speakers + * Mic Jack + * Int Mic + +- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's + connected to the CODEC. +- nvidia,audio-codec : The phandle of the MAX98090 audio codec. + +Optional properties: +- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in +- nvidia,mic-det-gpios : The GPIO that detect microphones are plugged in +- codec-enable-gpio : The GPIO used to enable the audio codec + +Example: + +sound { + compatible = "nvidia,tegra-audio-max98090-venice2", + "nvidia,tegra-audio-max98090"; + nvidia,model = "NVIDIA Tegra Venice2"; + + nvidia,audio-routing = + "Headphones", "HPR", + "Headphones", "HPL", + "Speakers", "SPKR", + "Speakers", "SPKL", + "Mic Jack", "MICBIAS", + "IN34", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&acodec>; + + clocks = <&tegra_car TEGRA124_CLK_PLL_A>, + <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; +}; diff --git a/doc/device-tree-bindings/sound/snow.txt b/doc/device-tree-bindings/sound/snow.txt new file mode 100644 index 0000000000..fa06956e77 --- /dev/null +++ b/doc/device-tree-bindings/sound/snow.txt @@ -0,0 +1,32 @@ +Audio Binding for Snow boards + +Required properties: +- compatible : Can be one of the following, + "google,snow-audio-max98090" or + "google,snow-audio-max98091" or + "google,snow-audio-max98095" +- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller +- samsung,audio-codec (deprecated): The phandle of the audio codec + +Required sub-nodes: + + - 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S + controller + - 'codec' subnode with a 'sound-dai' property containing list of phandles + to the CODEC nodes, first entry must be the phandle of the MAX98090, + MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible + string) and the second entry must be the phandle of the HDMI IP block node + +Optional: +- samsung,model: The name of the sound-card +- codec-enable-gpio : The GPIO used to enable the audio codec + +Example: + +sound { + compatible = "google,snow-audio-max98095"; + + samsung,model = "Snow-I2S-MAX98095"; + samsung,i2s-controller = <&i2s0>; + samsung,audio-codec = <&max98095>; +}; diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 4f362d1453..fb806b53d4 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -136,7 +136,6 @@ static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs, bool linear_ok; int attr; - break; debug("Mode %x: ", mode); memset(buffer, '\0', sizeof(struct vbe_mode_info)); regs->e.eax = VESA_GET_MODE_INFO; diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c index bf957e8326..ebe5c8a104 100644 --- a/drivers/fastboot/fb_getvar.c +++ b/drivers/fastboot/fb_getvar.c @@ -12,14 +12,13 @@ #include <version.h> static void getvar_version(char *var_parameter, char *response); -static void getvar_bootloader_version(char *var_parameter, char *response); +static void getvar_version_bootloader(char *var_parameter, char *response); static void getvar_downloadsize(char *var_parameter, char *response); static void getvar_serialno(char *var_parameter, char *response); static void getvar_version_baseband(char *var_parameter, char *response); static void getvar_product(char *var_parameter, char *response); static void getvar_platform(char *var_parameter, char *response); static void getvar_current_slot(char *var_parameter, char *response); -static void getvar_slot_suffixes(char *var_parameter, char *response); #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) static void getvar_has_slot(char *var_parameter, char *response); #endif @@ -29,6 +28,7 @@ static void getvar_partition_type(char *part_name, char *response); #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) static void getvar_partition_size(char *part_name, char *response); #endif +static void getvar_is_userspace(char *var_parameter, char *response); static const struct { const char *variable; @@ -38,11 +38,8 @@ static const struct { .variable = "version", .dispatch = getvar_version }, { - .variable = "bootloader-version", - .dispatch = getvar_bootloader_version - }, { .variable = "version-bootloader", - .dispatch = getvar_bootloader_version + .dispatch = getvar_version_bootloader }, { .variable = "downloadsize", .dispatch = getvar_downloadsize @@ -64,9 +61,6 @@ static const struct { }, { .variable = "current-slot", .dispatch = getvar_current_slot - }, { - .variable = "slot-suffixes", - .dispatch = getvar_slot_suffixes #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) }, { .variable = "has-slot", @@ -82,6 +76,9 @@ static const struct { .variable = "partition-size", .dispatch = getvar_partition_size #endif + }, { + .variable = "is-userspace", + .dispatch = getvar_is_userspace } }; @@ -131,7 +128,7 @@ static void getvar_version(char *var_parameter, char *response) fastboot_okay(FASTBOOT_VERSION, response); } -static void getvar_bootloader_version(char *var_parameter, char *response) +static void getvar_version_bootloader(char *var_parameter, char *response) { fastboot_okay(U_BOOT_VERSION, response); } @@ -182,11 +179,6 @@ static void getvar_current_slot(char *var_parameter, char *response) fastboot_okay("a", response); } -static void getvar_slot_suffixes(char *var_parameter, char *response) -{ - fastboot_okay("a,b", response); -} - #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) static void getvar_has_slot(char *part_name, char *response) { @@ -252,6 +244,11 @@ static void getvar_partition_size(char *part_name, char *response) } #endif +static void getvar_is_userspace(char *var_parameter, char *response) +{ + fastboot_okay("no", response); +} + /** * fastboot_getvar() - Writes variable indicated by cmd_parameter to response. * diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 66097ce0e7..c6812f6517 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -592,6 +592,17 @@ config MMC_SDHCI_TEGRA If unsure, say N. +config TEGRA124_MMC_DISABLE_EXT_LOOPBACK + bool "Disable external clock loopback" + depends on MMC_SDHCI_TEGRA && TEGRA124 + help + Disable the external clock loopback and use the internal one on SDMMC3 + as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 bits + being set to 0xfffd according to the TRM. + + TODO(marcel.ziswiler@toradex.com): Move to device tree controlled + approach once proper kernel integration made it mainline. + config MMC_SDHCI_ZYNQ bool "Arasan SDHCI controller support" depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL @@ -671,17 +682,6 @@ config MMC_MTK endif -config TEGRA124_MMC_DISABLE_EXT_LOOPBACK - bool "Disable external clock loopback" - depends on MMC_SDHCI_TEGRA && TEGRA124 - help - Disable the external clock loopback and use the internal one on SDMMC3 - as per the SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 bits - being set to 0xfffd according to the TRM. - - TODO(marcel.ziswiler@toradex.com): Move to device tree controlled - approach once proper kernel integration made it mainline. - config FSL_ESDHC bool "Freescale/NXP eSDHC controller support" help diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 957efb3984..8209ca7323 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -84,6 +84,12 @@ config BCM6368_USBH_PHY help Support for the Broadcom MIPS BCM6368 USBH PHY. +config PHY_DA8XX_USB + tristate "TI DA8xx USB PHY Driver" + depends on PHY && ARCH_DAVINCI + help + Enable this to support the USB PHY on DA8xx SoCs. + config PIPE3_PHY bool "Support omap's PIPE3 PHY" depends on PHY && ARCH_OMAP2PLUS diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90646ca55b..b9f5195e1c 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o +obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c new file mode 100644 index 0000000000..034b47932d --- /dev/null +++ b/drivers/phy/phy-da8xx-usb.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Based on the DA8xx "glue layer" code. + * Copyright (c) 2008-2019, MontaVista Software, Inc. <source@mvista.com> + * + * DT support added by: Adam Ford <aford173@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <asm/arch/hardware.h> +#include <asm/arch/da8xx-usb.h> +#include <asm/io.h> +#include <generic-phy.h> + +static int da8xx_usb_phy_power_on(struct phy *phy) +{ + unsigned long timeout; + + clrsetbits_le32(&davinci_syscfg_regs->cfgchip2, + CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | + CFGCHIP2_OTGMODE | CFGCHIP2_REFFREQ, + CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | + CFGCHIP2_PHY_PLLON | CFGCHIP2_REFFREQ_24MHZ); + + /* wait until the usb phy pll locks */ + timeout = get_timer(0); + while (get_timer(timeout) < 10) { + if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD) + return 0; + } + + debug("Phy was not turned on\n"); + + return -ENODEV; +} + +static int da8xx_usb_phy_power_off(struct phy *phy) +{ + clrsetbits_le32(&davinci_syscfg_regs->cfgchip2, + CFGCHIP2_PHY_PLLON, + CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN); + + return 0; +} + +static const struct udevice_id da8xx_phy_ids[] = { + { .compatible = "ti,da830-usb-phy" }, + { } +}; + +static struct phy_ops da8xx_phy_ops = { + .power_on = da8xx_usb_phy_power_on, + .power_off = da8xx_usb_phy_power_off, +}; + +U_BOOT_DRIVER(da8xx_phy) = { + .name = "da8xx-usb-phy", + .id = UCLASS_PHY, + .of_match = da8xx_phy_ids, + .ops = &da8xx_phy_ops, +}; diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 03531a8c0c..fbb58c783e 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -14,6 +14,8 @@ #include <pci_ids.h> #include <spi.h> #include <asm/io.h> +#include <spi-mem.h> +#include <div64.h> #include "ich.h" @@ -171,18 +173,6 @@ static int ich_init_controller(struct udevice *dev, return 0; } -static inline void spi_use_out(struct spi_trans *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(struct spi_trans *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase) { if (plat->ich_version == ICHV_7) { @@ -213,47 +203,12 @@ static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase) return lock != 0; } -static void spi_setup_type(struct spi_trans *trans, int data_bytes) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes */ - if (trans->bytesin == 0) { - if (trans->bytesout + data_bytes > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans, bool lock) { uint16_t optypes; uint8_t opmenu[ctlr->menubytes]; - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); if (!lock) { /* The lock is off, so just use index 0. */ ich_writeb(ctlr, trans->opcode, ctlr->opmenu); @@ -285,12 +240,7 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans, optypes = ich_readw(ctlr, ctlr->optype); optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } + if (optype != trans->type) { printf("ICH SPI: Transaction doesn't fit type %d\n", optype); @@ -300,26 +250,6 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans, } } -static int spi_setup_offset(struct spi_trans *trans) -{ - /* Separate the SPI address and data */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printf("Unrecognized SPI transaction type %#x\n", trans->type); - return -EPROTO; - } -} - /* * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set * below is true) or 0. In case the wait was for the bit(s) to set - write @@ -350,7 +280,7 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask, return -ETIMEDOUT; } -void ich_spi_config_opcode(struct udevice *dev) +static void ich_spi_config_opcode(struct udevice *dev) { struct ich_spi_priv *ctlr = dev_get_priv(dev); @@ -365,72 +295,48 @@ void ich_spi_config_opcode(struct udevice *dev) ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32)); } -static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) +static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) { - struct udevice *bus = dev_get_parent(dev); + struct udevice *bus = dev_get_parent(slave->dev); struct ich_spi_platdata *plat = dev_get_platdata(bus); struct ich_spi_priv *ctlr = dev_get_priv(bus); uint16_t control; int16_t opcode_index; int with_address; int status; - int bytes = bitlen / 8; struct spi_trans *trans = &ctlr->trans; - unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END); - int using_cmd = 0; bool lock = spi_lock_status(plat, ctlr->base); - int ret; - - /* We don't support writing partial bytes */ - if (bitlen % 8) { - debug("ICH SPI: Accessing partial bytes not supported\n"); - return -EPROTONOSUPPORT; - } + int ret = 0; - /* An empty end transaction can be ignored */ - if (type == SPI_XFER_END && !dout && !din) - return 0; - - if (type & SPI_XFER_BEGIN) - memset(trans, '\0', sizeof(*trans)); + trans->in = NULL; + trans->out = NULL; + trans->type = 0xFF; - /* Dp we need to come back later to finish it? */ - if (dout && type == SPI_XFER_BEGIN) { - if (bytes > ICH_MAX_CMD_LEN) { - debug("ICH SPI: Command length limit exceeded\n"); - return -ENOSPC; + if (op->data.nbytes) { + if (op->data.dir == SPI_MEM_DATA_IN) { + trans->in = op->data.buf.in; + trans->bytesin = op->data.nbytes; + } else { + trans->out = op->data.buf.out; + trans->bytesout = op->data.nbytes; } - memcpy(trans->cmd, dout, bytes); - trans->cmd_len = bytes; - debug_trace("ICH SPI: Saved %d bytes\n", bytes); - return 0; } - /* - * We process a 'middle' spi_xfer() call, which has no - * SPI_XFER_BEGIN/END, as an independent transaction as if it had - * an end. We therefore repeat the command. This is because ICH - * seems to have no support for this, or because interest (in digging - * out the details and creating a special case in the code) is low. - */ - if (trans->cmd_len) { - trans->out = trans->cmd; - trans->bytesout = trans->cmd_len; - using_cmd = 1; - debug_trace("ICH SPI: Using %d bytes\n", trans->cmd_len); - } else { - trans->out = dout; - trans->bytesout = dout ? bytes : 0; - } + if (trans->opcode != op->cmd.opcode) + trans->opcode = op->cmd.opcode; - trans->in = din; - trans->bytesin = din ? bytes : 0; + if (lock && trans->opcode == SPI_OPCODE_WRDIS) + return 0; - /* There has to always at least be an opcode */ - if (!trans->bytesout) { - debug("ICH SPI: No opcode for transfer\n"); - return -EPROTO; + if (trans->opcode == SPI_OPCODE_WREN) { + /* + * Treat Write Enable as Atomic Pre-Op if possible + * in order to prevent the Management Engine from + * issuing a transaction between WREN and DATA. + */ + if (!lock) + ich_writew(ctlr, trans->opcode, ctlr->preop); + return 0; } ret = ich_status_poll(ctlr, SPIS_SCIP, 0); @@ -442,23 +348,29 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, else ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); - spi_setup_type(trans, using_cmd ? bytes : 0); + /* Try to guess spi transaction type */ + if (op->data.dir == SPI_MEM_DATA_OUT) { + if (op->addr.nbytes) + trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; + else + trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; + } else { + if (op->addr.nbytes) + trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; + else + trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; + } + /* Special erase case handling */ + if (op->addr.nbytes && !op->data.buswidth) + trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; + opcode_index = spi_setup_opcode(ctlr, trans, lock); if (opcode_index < 0) return -EINVAL; - with_address = spi_setup_offset(trans); - if (with_address < 0) - return -EINVAL; - if (trans->opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!lock) - ich_writew(ctlr, trans->opcode, ctlr->preop); - return 0; + if (op->addr.nbytes) { + trans->offset = op->addr.val; + with_address = 1; } if (ctlr->speed && ctlr->max_speed >= 33000000) { @@ -472,13 +384,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, ich_writeb(ctlr, byte, ctlr->speed); } - /* See if we have used up the command data */ - if (using_cmd && dout && bytes) { - trans->out = dout; - trans->bytesout = bytes; - debug_trace("ICH SPI: Moving to data, %d bytes\n", bytes); - } - /* Preset control fields */ control = SPIC_SCGO | ((opcode_index & 0x07) << 4); @@ -513,22 +418,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, return 0; } - /* - * Check if this is a write command atempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans->bytesout > ctlr->databytes) { - debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n"); - return -EPROTO; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ while (trans->bytesout || trans->bytesin) { uint32_t data_length; @@ -543,9 +432,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, /* Program data into FDATA0 to N */ if (trans->bytesout) { write_reg(ctlr, trans->out, ctlr->data, data_length); - spi_use_out(trans, data_length); - if (with_address) - trans->offset += data_length; + trans->bytesout -= data_length; } /* Add proper control fields' values */ @@ -568,9 +455,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, if (trans->bytesin) { read_reg(ctlr, ctlr->data, trans->in, data_length); - spi_use_in(trans, data_length); - if (with_address) - trans->offset += data_length; + trans->bytesin -= data_length; } } @@ -581,6 +466,40 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, return 0; } +static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op) +{ + unsigned int page_offset; + int addr = op->addr.val; + unsigned int byte_count = op->data.nbytes; + + if (hweight32(ICH_BOUNDARY) == 1) { + page_offset = addr & (ICH_BOUNDARY - 1); + } else { + u64 aux = addr; + + page_offset = do_div(aux, ICH_BOUNDARY); + } + + if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size) { + op->data.nbytes = min(ICH_BOUNDARY - page_offset, + slave->max_read_size); + } else if (slave->max_write_size) { + op->data.nbytes = min(ICH_BOUNDARY - page_offset, + slave->max_write_size); + } + + op->data.nbytes = min(op->data.nbytes, byte_count); + + return 0; +} + +static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + printf("ICH SPI: Only supports memory operations\n"); + return -1; +} + static int ich_spi_probe(struct udevice *dev) { struct ich_spi_platdata *plat = dev_get_platdata(dev); @@ -686,10 +605,17 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev) return ret; } +static const struct spi_controller_mem_ops ich_controller_mem_ops = { + .adjust_op_size = ich_spi_adjust_size, + .supports_op = NULL, + .exec_op = ich_spi_exec_op, +}; + static const struct dm_spi_ops ich_spi_ops = { .xfer = ich_spi_xfer, .set_speed = ich_spi_set_speed, .set_mode = ich_spi_set_mode, + .mem_ops = &ich_controller_mem_ops, /* * cs_info is not needed, since we require all chip selects to be * in the device tree explicitly diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h index a974241f98..3dfb2aaff1 100644 --- a/drivers/spi/ich.h +++ b/drivers/spi/ich.h @@ -100,13 +100,8 @@ enum { HSFC_FSMIE = 0x8000 }; -enum { - ICH_MAX_CMD_LEN = 5, -}; - struct spi_trans { - uint8_t cmd[ICH_MAX_CMD_LEN]; - int cmd_len; + uint8_t cmd; const uint8_t *out; uint32_t bytesout; uint8_t *in; @@ -166,6 +161,8 @@ struct spi_trans { #define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \ (SPI_OPMENU_1 << 8) | (SPI_OPMENU_0 << 0)) +#define ICH_BOUNDARY 0x1000 + enum ich_version { ICHV_7, ICHV_9, diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 30ece524a8..e27f146605 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -748,6 +748,7 @@ static void dfu_unbind(struct usb_configuration *c, struct usb_function *f) if (f_dfu->function) { i = alt_num; + i++; /* free DFU Functional Descriptor */ while (i) { free(f_dfu->function[--i]); f_dfu->function[i] = NULL; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ac68aa2d27..42046c8062 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -236,6 +236,13 @@ config USB_OHCI_HCD based system where you're not sure, the "lspci -v" entry will list the right "prog-if" for your USB controller(s): EHCI, OHCI, or UHCI. +config USB_OHCI_PCI + bool "Support for PCI-based OHCI USB controller" + depends on DM_USB + default n + help + Enables support for the PCI-based OHCI controller. + if USB_OHCI_HCD config USB_OHCI_GENERIC diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 6aa574f6f7..dd13528475 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o +obj-$(CONFIG_USB_OHCI_PCI) += ohci-pci.o obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o # echi diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2b0df88f49..58aa824ec0 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -50,8 +50,9 @@ #endif #if defined(CONFIG_CPU_ARM920T) || \ - defined(CONFIG_PCI_OHCI) || \ - defined(CONFIG_SYS_OHCI_USE_NPS) + defined(CONFIG_PCI_OHCI) || \ + defined(CONFIG_DM_PCI) || \ + defined(CONFIG_SYS_OHCI_USE_NPS) # define OHCI_USE_NPS /* force NoPowerSwitching mode */ #endif @@ -64,6 +65,7 @@ #define OHCI_CONTROL_INIT \ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE +#if !CONFIG_IS_ENABLED(DM_USB) #ifdef CONFIG_PCI_OHCI static struct pci_device_id ohci_pci_ids[] = { {0x10b9, 0x5237}, /* ULI1575 PCI OHCI module ids */ @@ -73,6 +75,7 @@ static struct pci_device_id ohci_pci_ids[] = { {0, 0} }; #endif +#endif #ifdef CONFIG_PCI_EHCI_DEVNO static struct pci_device_id ehci_pci_ids[] = { @@ -2044,8 +2047,11 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base); printf("OHCI regs address 0x%08x\n", base); gohci.regs = (struct ohci_regs *)base; - } else + } else { + printf("%s: OHCI devnr: %d not found\n", __func__, + CONFIG_PCI_OHCI_DEVNO); return -1; + } #else gohci.regs = (struct ohci_regs *)CONFIG_SYS_USB_OHCI_REGS_BASE; #endif diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c new file mode 100644 index 0000000000..4c1c778672 --- /dev/null +++ b/drivers/usb/host/ohci-pci.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <pci.h> +#include <usb.h> +#include <asm/io.h> + +#include "ohci.h" + +static int ohci_pci_probe(struct udevice *dev) +{ + struct ohci_regs *regs; + + regs = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + return ohci_register(dev, regs); +} + +static int ohci_pci_remove(struct udevice *dev) +{ + return ohci_deregister(dev); +} + +static const struct udevice_id ohci_pci_ids[] = { + { .compatible = "ohci-pci" }, + { } +}; + +U_BOOT_DRIVER(ohci_pci) = { + .name = "ohci_pci", + .id = UCLASS_USB, + .probe = ohci_pci_probe, + .remove = ohci_pci_remove, + .of_match = ohci_pci_ids, + .ops = &ohci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(ohci_t), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; + +static struct pci_device_id ohci_pci_supported[] = { + { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0) }, + {}, +}; + +U_BOOT_PCI_DEVICE(ohci_pci, ohci_pci_supported); diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index f9f02cb09c..9b264bd92a 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -14,8 +14,8 @@ #include <asm/io.h> #ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS -# define ohci_readl(a) __swap_32(readl(a)) -# define ohci_writel(v, a) writel(__swap_32(v), a) +# define ohci_readl(a) __swap_32(in_be32((u32 *)a)) +# define ohci_writel(a, b) out_be32((u32 *)b, __swap_32(a)) #else # define ohci_readl(a) readl(a) # define ohci_writel(v, a) writel(v, a) diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig index 75005ccdd1..79ad14ef66 100644 --- a/drivers/usb/musb-new/Kconfig +++ b/drivers/usb/musb-new/Kconfig @@ -18,6 +18,14 @@ config USB_MUSB_GADGET help Enables the MUSB USB dual-role controller in gadget mode. +config USB_MUSB_DA8XX + bool "Enable DA8xx MUSB Controller" + depends on DM_USB + help + Say y here to enable support for the dual role high + speed USB controller based on the Mentor Graphics + silicon IP. + config USB_MUSB_TI bool "Enable TI OTG USB controller" depends on DM_USB diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile index 4eca0e5631..ec7852ce94 100644 --- a/drivers/usb/musb-new/Makefile +++ b/drivers/usb/musb-new/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_USB_MUSB_GADGET) += musb_gadget.o musb_gadget_ep0.o musb_core.o obj-$(CONFIG_USB_MUSB_GADGET) += musb_uboot.o obj-$(CONFIG_USB_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o +obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o obj-$(CONFIG_USB_MUSB_PIC32) += pic32.o diff --git a/drivers/usb/musb-new/da8xx.c b/drivers/usb/musb-new/da8xx.c new file mode 100644 index 0000000000..899b30db68 --- /dev/null +++ b/drivers/usb/musb-new/da8xx.c @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Texas Instruments da8xx "glue layer" + * + * Copyright (c) 2019, by Texas Instruments + * + * Based on the DA8xx "glue layer" code. + * Copyright (c) 2008-2019, MontaVista Software, Inc. <source@mvista.com> + * + * DT support + * Copyright (c) 2016 Petr Kulhavy <petr@barix.com> + * This file is part of the Inventra Controller Driver for Linux. + * + */ + +#include <common.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <asm/arch/hardware.h> +#include <asm/arch/da8xx-usb.h> +#include <linux/usb/otg.h> +#include <asm/omap_musb.h> +#include <generic-phy.h> +#include "linux-compat.h" +#include "musb_core.h" +#include "musb_uboot.h" + +/* USB 2.0 OTG module registers */ +#define DA8XX_USB_REVISION_REG 0x00 +#define DA8XX_USB_CTRL_REG 0x04 +#define DA8XX_USB_STAT_REG 0x08 +#define DA8XX_USB_EMULATION_REG 0x0c +#define DA8XX_USB_SRP_FIX_TIME_REG 0x18 +#define DA8XX_USB_INTR_SRC_REG 0x20 +#define DA8XX_USB_INTR_SRC_SET_REG 0x24 +#define DA8XX_USB_INTR_SRC_CLEAR_REG 0x28 +#define DA8XX_USB_INTR_MASK_REG 0x2c +#define DA8XX_USB_INTR_MASK_SET_REG 0x30 +#define DA8XX_USB_INTR_MASK_CLEAR_REG 0x34 +#define DA8XX_USB_INTR_SRC_MASKED_REG 0x38 +#define DA8XX_USB_END_OF_INTR_REG 0x3c +#define DA8XX_USB_GENERIC_RNDIS_EP_SIZE_REG(n) (0x50 + (((n) - 1) << 2)) + +/* Control register bits */ +#define DA8XX_SOFT_RESET_MASK 1 + +#define DA8XX_USB_TX_EP_MASK 0x1f /* EP0 + 4 Tx EPs */ +#define DA8XX_USB_RX_EP_MASK 0x1e /* 4 Rx EPs */ + +/* USB interrupt register bits */ +#define DA8XX_INTR_USB_SHIFT 16 +#define DA8XX_INTR_USB_MASK (0x1ff << DA8XX_INTR_USB_SHIFT) /* 8 Mentor */ + /* interrupts and DRVVBUS interrupt */ +#define DA8XX_INTR_DRVVBUS 0x100 +#define DA8XX_INTR_RX_SHIFT 8 +#define DA8XX_INTR_RX_MASK (DA8XX_USB_RX_EP_MASK << DA8XX_INTR_RX_SHIFT) +#define DA8XX_INTR_TX_SHIFT 0 +#define DA8XX_INTR_TX_MASK (DA8XX_USB_TX_EP_MASK << DA8XX_INTR_TX_SHIFT) + +#define DA8XX_MENTOR_CORE_OFFSET 0x400 + +static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) +{ + struct musb *musb = hci; + void __iomem *reg_base = musb->ctrl_base; + unsigned long flags; + irqreturn_t ret = IRQ_NONE; + u32 status; + + spin_lock_irqsave(&musb->lock, flags); + + /* + * NOTE: DA8XX shadows the Mentor IRQs. Don't manage them through + * the Mentor registers (except for setup), use the TI ones and EOI. + */ + + /* Acknowledge and handle non-CPPI interrupts */ + status = musb_readl(reg_base, DA8XX_USB_INTR_SRC_MASKED_REG); + if (!status) + goto eoi; + + musb_writel(reg_base, DA8XX_USB_INTR_SRC_CLEAR_REG, status); + dev_dbg(musb->controller, "USB IRQ %08x\n", status); + + musb->int_rx = (status & DA8XX_INTR_RX_MASK) >> DA8XX_INTR_RX_SHIFT; + musb->int_tx = (status & DA8XX_INTR_TX_MASK) >> DA8XX_INTR_TX_SHIFT; + musb->int_usb = (status & DA8XX_INTR_USB_MASK) >> DA8XX_INTR_USB_SHIFT; + + /* + * DRVVBUS IRQs are the only proxy we have (a very poor one!) for + * DA8xx's missing ID change IRQ. We need an ID change IRQ to + * switch appropriately between halves of the OTG state machine. + * Managing DEVCTL.Session per Mentor docs requires that we know its + * value but DEVCTL.BDevice is invalid without DEVCTL.Session set. + * Also, DRVVBUS pulses for SRP (but not at 5 V)... + */ + if (status & (DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT)) { + int drvvbus = musb_readl(reg_base, DA8XX_USB_STAT_REG); + void __iomem *mregs = musb->mregs; + u8 devctl = musb_readb(mregs, MUSB_DEVCTL); + int err; + + err = musb->int_usb & MUSB_INTR_VBUSERROR; + if (err) { + /* + * The Mentor core doesn't debounce VBUS as needed + * to cope with device connect current spikes. This + * means it's not uncommon for bus-powered devices + * to get VBUS errors during enumeration. + * + * This is a workaround, but newer RTL from Mentor + * seems to allow a better one: "re"-starting sessions + * without waiting for VBUS to stop registering in + * devctl. + */ + musb->int_usb &= ~MUSB_INTR_VBUSERROR; + WARNING("VBUS error workaround (delay coming)\n"); + } else if (drvvbus) { + MUSB_HST_MODE(musb); + musb->port1_status |= USB_PORT_STAT_POWER; + } else if (!(musb->int_usb & MUSB_INTR_BABBLE)) { + /* + * When babble condition happens, drvvbus interrupt + * is also generated. Ignore this drvvbus interrupt + * and let babble interrupt handler recovers the + * controller; otherwise, the host-mode flag is lost + * due to the MUSB_DEV_MODE() call below and babble + * recovery logic will not be called. + */ + musb->is_active = 0; + MUSB_DEV_MODE(musb); + musb->port1_status &= ~USB_PORT_STAT_POWER; + } + ret = IRQ_HANDLED; + } + + if (musb->int_tx || musb->int_rx || musb->int_usb) + ret |= musb_interrupt(musb); +eoi: + /* EOI needs to be written for the IRQ to be re-asserted. */ + if (ret == IRQ_HANDLED || status) + musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); + + spin_unlock_irqrestore(&musb->lock, flags); + + return ret; +} + +static int da8xx_musb_init(struct musb *musb) +{ + u32 revision; + void __iomem *reg_base = musb->ctrl_base; + + int ret; + + /* reset the controller */ + writel(0x1, &da8xx_usb_regs->control); + udelay(50); + + /* Returns zero if e.g. not clocked */ + revision = readl(&da8xx_usb_regs->revision); + if (revision == 0) + return -ENODEV; + + /* Disable all interrupts */ + writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | + DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_set); + + musb->mregs += DA8XX_MENTOR_CORE_OFFSET; + + /* NOTE: IRQs are in mixed mode, not bypass to pure MUSB */ + debug("DA8xx OTG revision %08x, control %02x\n", revision, + musb_readb(reg_base, DA8XX_USB_CTRL_REG)); + + musb->isr = da8xx_musb_interrupt; + return 0; +} + +static int da8xx_musb_exit(struct musb *musb) +{ + /* flush any interrupts */ + writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | + DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr); + writel(0, &da8xx_usb_regs->eoi); + + return 0; +} + +/** + * da8xx_musb_enable - enable interrupts + */ +static int da8xx_musb_enable(struct musb *musb) +{ + void __iomem *reg_base = musb->ctrl_base; + u32 mask; + + /* Workaround: setup IRQs through both register sets. */ + mask = ((musb->epmask & DA8XX_USB_TX_EP_MASK) << DA8XX_INTR_TX_SHIFT) | + ((musb->epmask & DA8XX_USB_RX_EP_MASK) << DA8XX_INTR_RX_SHIFT) | + DA8XX_INTR_USB_MASK; + musb_writel(reg_base, DA8XX_USB_INTR_MASK_SET_REG, mask); + + /* Force the DRVVBUS IRQ so we can start polling for ID change. */ + musb_writel(reg_base, DA8XX_USB_INTR_SRC_SET_REG, + DA8XX_INTR_DRVVBUS << DA8XX_INTR_USB_SHIFT); + + return 0; +} + +/** + * da8xx_musb_disable - disable HDRC and flush interrupts + */ +static void da8xx_musb_disable(struct musb *musb) +{ + void __iomem *reg_base = musb->ctrl_base; + + musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG, + DA8XX_INTR_USB_MASK | + DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK); + musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); +} + +void da8xx_musb_reset(struct udevice *dev) +{ + void *reg_base = dev_read_addr_ptr(dev); + + /* Reset the controller */ + musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); +} + +void da8xx_musb_clear_irq(struct udevice *dev) +{ + /* flush any interrupts */ + writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK | + DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr); + writel(0, &da8xx_usb_regs->eoi); +} + +const struct musb_platform_ops da8xx_ops = { + .init = da8xx_musb_init, + .exit = da8xx_musb_exit, + .enable = da8xx_musb_enable, + .disable = da8xx_musb_disable, +}; + +struct da8xx_musb_platdata { + void *base; + void *ctrl_mod_base; + struct musb_hdrc_platform_data plat; + struct musb_hdrc_config musb_config; + struct omap_musb_board_data otg_board_data; + struct phy phy; +}; + +static int da8xx_musb_ofdata_to_platdata(struct udevice *dev) +{ + struct da8xx_musb_platdata *platdata = dev_get_platdata(dev); + const void *fdt = gd->fdt_blob; + int node = dev_of_offset(dev); + + platdata->base = (void *)dev_read_addr_ptr(dev); + platdata->musb_config.multipoint = 1; + platdata->musb_config.dyn_fifo = 1; + platdata->musb_config.num_eps = 5; + platdata->musb_config.ram_bits = 10; + platdata->plat.power = fdtdec_get_int(fdt, node, "power", 50); + platdata->otg_board_data.interface_type = MUSB_INTERFACE_UTMI; + platdata->plat.mode = MUSB_HOST; + platdata->otg_board_data.dev = dev; + platdata->plat.config = &platdata->musb_config; + platdata->plat.platform_ops = &da8xx_ops; + platdata->plat.board_data = &platdata->otg_board_data; + platdata->otg_board_data.clear_irq = da8xx_musb_clear_irq; + platdata->otg_board_data.reset = da8xx_musb_reset; + return 0; +} + +static int da8xx_musb_probe(struct udevice *dev) +{ + struct musb_host_data *host = dev_get_priv(dev); + struct da8xx_musb_platdata *platdata = dev_get_platdata(dev); + struct usb_bus_priv *priv = dev_get_uclass_priv(dev); + struct omap_musb_board_data *otg_board_data; + int ret; + void *base = dev_read_addr_ptr(dev); + + /* Get the phy info from the device tree */ + ret = generic_phy_get_by_name(dev, "usb-phy", &platdata->phy); + if (ret) + return ret; + + /* Initialize the phy */ + ret = generic_phy_init(&platdata->phy); + if (ret) + return ret; + + /* enable psc for usb2.0 */ + lpsc_on(33); + + /* Enable phy */ + generic_phy_power_on(&platdata->phy); + + priv->desc_before_addr = true; + otg_board_data = &platdata->otg_board_data; + + host->host = musb_init_controller(&platdata->plat, + (struct device *)otg_board_data, + platdata->base); + if (!host->host) { + ret = -ENODEV; + goto shutdown; /* Shutdown what we started */ + } + + ret = musb_lowlevel_init(host); + + if (ret == 0) + return 0; +shutdown: + /* Turn off the phy if we fail */ + generic_phy_power_off(&platdata->phy); + lpsc_disable(33); + return ret; +} + +static int da8xx_musb_remove(struct udevice *dev) +{ + struct musb_host_data *host = dev_get_priv(dev); + + musb_stop(host->host); + + return 0; +} + +static const struct udevice_id da8xx_musb_ids[] = { + { .compatible = "ti,da830-musb" }, + { } +}; + +U_BOOT_DRIVER(da8xx_musb) = { + .name = "da8xx-musb", + .id = UCLASS_USB, + .of_match = da8xx_musb_ids, + .ofdata_to_platdata = da8xx_musb_ofdata_to_platdata, + .probe = da8xx_musb_probe, + .remove = da8xx_musb_remove, + .ops = &musb_usb_ops, + .platdata_auto_alloc_size = sizeof(struct da8xx_musb_platdata), + .priv_auto_alloc_size = sizeof(struct musb_host_data), +}; diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h index b4ddd1bdc6..dacf36bf79 100644 --- a/include/configs/apalis-tk1.h +++ b/include/configs/apalis-tk1.h @@ -18,6 +18,9 @@ #define CONFIG_TEGRA_ENABLE_UARTA #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE +#define FDT_MODULE "apalis-v1.2" +#define FDT_MODULE_V1_0 "apalis" + /* Environment in eMMC, before config block at the end of 1st "boot sector" */ #define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE + \ CONFIG_TDX_CFG_BLOCK_OFFSET) @@ -42,7 +45,7 @@ #define DFU_ALT_EMMC_INFO "apalis-tk1.img raw 0x0 0x500 mmcpart 1; " \ "boot part 0 1 mmcpart 0; " \ "rootfs part 0 2 mmcpart 0; " \ - "uImage fat 0 1 mmcpart 0; " \ + "zImage fat 0 1 mmcpart 0; " \ "tegra124-apalis-eval.dtb fat 0 1 mmcpart 0" #define EMMC_BOOTCMD \ @@ -54,11 +57,11 @@ "run emmcdtbload; " \ "load mmc ${emmcdev}:${emmcbootpart} ${kernel_addr_r} " \ "${boot_file} && run fdt_fixup && " \ - "bootm ${kernel_addr_r} - ${dtbparam}\0" \ + "bootz ${kernel_addr_r} - ${dtbparam}\0" \ "emmcbootpart=1\0" \ "emmcdev=0\0" \ "emmcdtbload=setenv dtbparam; load mmc ${emmcdev}:${emmcbootpart} " \ - "${fdt_addr_r} ${soc}-apalis-${fdt_board}.dtb && " \ + "${fdt_addr_r} ${soc}-${fdt_module}-${fdt_board}.dtb && " \ "setenv dtbparam ${fdt_addr_r}\0" \ "emmcfinduuid=part uuid mmc ${mmcdev}:${emmcrootpart} uuid\0" \ "emmcrootpart=2\0" @@ -68,9 +71,9 @@ "nfsboot=pci enum; run setup; setenv bootargs ${defargs} ${nfsargs} " \ "${setupargs} ${vidargs}; echo Booting via DHCP/TFTP/NFS...; " \ "run nfsdtbload; dhcp ${kernel_addr_r} " \ - "&& run fdt_fixup && bootm ${kernel_addr_r} - ${dtbparam}\0" \ + "&& run fdt_fixup && bootz ${kernel_addr_r} - ${dtbparam}\0" \ "nfsdtbload=setenv dtbparam; tftp ${fdt_addr_r} " \ - "${soc}-apalis-${fdt_board}.dtb " \ + "${soc}-${fdt_module}-${fdt_board}.dtb " \ "&& setenv dtbparam ${fdt_addr_r}\0" #define SD_BOOTCMD \ @@ -81,44 +84,28 @@ "${vidargs}; echo Booting from SD card in 8bit slot...; " \ "run sddtbload; load mmc ${sddev}:${sdbootpart} " \ "${kernel_addr_r} ${boot_file} && run fdt_fixup && " \ - "bootm ${kernel_addr_r} - ${dtbparam}\0" \ + "bootz ${kernel_addr_r} - ${dtbparam}\0" \ "sdbootpart=1\0" \ "sddev=1\0" \ "sddtbload=setenv dtbparam; load mmc ${sddev}:${sdbootpart} " \ - "${fdt_addr_r} ${soc}-apalis-${fdt_board}.dtb " \ + "${fdt_addr_r} ${soc}-${fdt_module}-${fdt_board}.dtb " \ "&& setenv dtbparam ${fdt_addr_r}\0" \ "sdfinduuid=part uuid mmc ${sddev}:${sdrootpart} uuid\0" \ "sdrootpart=2\0" -#define USB_BOOTCMD \ - "set_usbargs=setenv usbargs ip=off root=PARTUUID=${uuid} ro " \ - "rootfstype=ext4 rootwait\0" \ - "usbboot=run setup; usb start; run usbfinduuid; run set_usbargs; " \ - "setenv bootargs ${defargs} ${setupargs} " \ - "${usbargs} ${vidargs}; echo Booting from USB stick...; " \ - "run usbdtbload; load usb ${usbdev}:${usbbootpart} " \ - "${kernel_addr_r} ${boot_file} && run fdt_fixup && " \ - "bootm ${kernel_addr_r} - ${dtbparam}\0" \ - "usbbootpart=1\0" \ - "usbdev=0\0" \ - "usbdtbload=setenv dtbparam; load usb ${usbdev}:${usbbootpart} " \ - "${fdt_addr_r} ${soc}-apalis-${fdt_board}.dtb " \ - "&& setenv dtbparam ${fdt_addr_r}\0" \ - "usbfinduuid=part uuid usb ${usbdev}:${usbrootpart} uuid\0" \ - "usbrootpart=2\0" - #define BOARD_EXTRA_ENV_SETTINGS \ - "boot_file=uImage\0" \ + "boot_file=zImage\0" \ "console=ttyS0\0" \ "defargs=lp0_vec=2064@0xf46ff000 core_edp_mv=1150 core_edp_ma=4000 " \ - "usb_port_owner_info=2 lane_owner_info=6 emc_max_dvfs=0\0" \ + "usb_port_owner_info=2 lane_owner_info=6 emc_max_dvfs=0 " \ + "user_debug=30 pcie_aspm=off\0" \ "dfu_alt_info=" DFU_ALT_EMMC_INFO "\0" \ EMMC_BOOTCMD \ "fdt_board=eval\0" \ "fdt_fixup=;\0" \ + "fdt_module=" FDT_MODULE "\0" \ NFS_BOOTCMD \ SD_BOOTCMD \ - USB_BOOTCMD \ "setethupdate=if env exists ethaddr; then; else setenv ethaddr " \ "00:14:2d:00:00:00; fi; pci enum && tftpboot ${loadaddr} " \ "flash_eth.img && source ${loadaddr}\0" \ @@ -135,8 +122,7 @@ "setusbupdate=usb start && setenv interface usb; setenv drive 0; " \ "load ${interface} ${drive}:1 ${loadaddr} flash_blk.img && " \ "source ${loadaddr}\0" \ - USB_BOOTCMD \ - "vidargs=video=tegrafb0:640x480-16@60 fbcon=map:1\0" + "vidargs=fbcon=map:1\0" /* Increase console I/O buffer size */ #undef CONFIG_SYS_CBSIZE diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h index 64e7a60b8a..c5574201dd 100644 --- a/include/configs/qemu-x86.h +++ b/include/configs/qemu-x86.h @@ -10,8 +10,23 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include <linux/sizes.h> + +#define BOOT_TARGET_DEVICES(func) \ + func(USB, usb, 0) \ + func(SCSI, scsi, 0) \ + func(VIRTIO, virtio, 0) \ + func(IDE, ide, 0) \ + func(DHCP, dhcp, na) + +#include <config_distro_bootcmd.h> #include <configs/x86-common.h> +#undef CONFIG_ENV_SIZE +#define CONFIG_ENV_SIZE SZ_256K + +#define CONFIG_PREBOOT "pci enum" + #define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,i8042-kbd\0" \ diff --git a/include/configs/slimbootloader.h b/include/configs/slimbootloader.h new file mode 100644 index 0000000000..e0011ed446 --- /dev/null +++ b/include/configs/slimbootloader.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019 Intel Corporation <www.intel.com> + */ + +#ifndef __SLIMBOOTLOADER_CONFIG_H__ +#define __SLIMBOOTLOADER_CONFIG_H__ + +#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" \ + "stderr=serial\0" + +/* + * Override CONFIG_EXTRA_ENV_SETTINGS in x86-common.h + */ +#undef CONFIG_EXTRA_ENV_SETTINGS +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_STD_DEVICES_SETTINGS \ + "netdev=eth0\0" \ + "consoledev=ttyS0\0" \ + "ramdiskaddr=0x4000000\0" \ + "ramdiskfile=initrd\0" \ + "bootdev=usb\0" \ + "bootdevnum=0\0" \ + "bootdevpart=0\0" \ + "bootfsload=fatload\0" \ + "bootusb=setenv bootdev usb; boot\0" \ + "bootscsi=setenv bootdev scsi; boot\0" \ + "bootmmc=setenv bootdev mmc; boot\0" \ + "bootargs=console=ttyS0,115200 console=tty0\0" + +/* + * Override CONFIG_BOOTCOMMAND in x86-common.h + */ +#undef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND \ + "if test ${bootdev} = \"usb\"; then ${bootdev} start; fi; " \ + "if test ${bootdev} = \"scsi\"; then ${bootdev} scan; fi; " \ + "${bootdev} info; " \ + "${bootfsload} ${bootdev} ${bootdevnum}:${bootdevpart} " \ + "${loadaddr} ${bootfile}; " \ + "${bootfsload} ${bootdev} ${bootdevnum}:${bootdevpart} " \ + "${ramdiskaddr} ${ramdiskfile}; " \ + "zboot ${loadaddr} 0 ${ramdiskaddr} ${filesize}" + +#endif /* __SLIMBOOTLOADER_CONFIG_H__ */ diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index c4deef80af..ca27a4f9e2 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -105,30 +105,37 @@ #define CONFIG_OTHBOOTARGS "othbootargs=acpi=off\0" #endif +#ifndef CONFIG_DISTRO_DEFAULTS +#define BOOTENV +#endif + #define CONFIG_EXTRA_ENV_SETTINGS \ CONFIG_STD_DEVICES_SETTINGS \ "pciconfighost=1\0" \ "netdev=eth0\0" \ "consoledev=ttyS0\0" \ CONFIG_OTHBOOTARGS \ - "ramdiskaddr=0x4000000\0" \ - "ramdiskfile=initramfs.gz\0" + "scriptaddr=0x7000000\0" \ + "kernel_addr_r=0x1000000\0" \ + "ramdisk_addr_r=0x4000000\0" \ + "ramdiskfile=initramfs.gz\0" \ + BOOTENV #define CONFIG_RAMBOOTCOMMAND \ "setenv bootargs root=/dev/ram rw " \ "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ "console=$consoledev,$baudrate $othbootargs;" \ - "tftpboot $loadaddr $bootfile;" \ - "tftpboot $ramdiskaddr $ramdiskfile;" \ - "zboot $loadaddr 0 $ramdiskaddr $filesize" + "tftpboot $kernel_addr_r $bootfile;" \ + "tftpboot $ramdisk_addr_r $ramdiskfile;" \ + "zboot $kernel_addr_r 0 $ramdisk_addr_r $filesize" #define CONFIG_NFSBOOTCOMMAND \ "setenv bootargs root=/dev/nfs rw " \ "nfsroot=$serverip:$rootpath " \ "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \ "console=$consoledev,$baudrate $othbootargs;" \ - "tftpboot $loadaddr $bootfile;" \ - "zboot $loadaddr" + "tftpboot $kernel_addr_r $bootfile;" \ + "zboot $kernel_addr_r" #endif /* __CONFIG_H */ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2f5e28cac3..ef116e0e0a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -395,11 +395,22 @@ $(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/efi_free # ACPI # --------------------------------------------------------------------------- +# +# This first sends the file (typically dsdt.asl) through the preprocessor +# resolve includes and any CONFIG options used. This produces dsdt.asl.tmp +# which is pure ASL code. The Intel ASL (ACPI (Advanced Configuration and Power +# Interface) Source Language compiler (iasl) then converts this ASL code into a +# C file containing the hex data to build into U-Boot. This file is called +# dsdt.hex (despite us setting the prefix to .../dsdt.asl.tmp) so must be +# renamed to dsdt.c for consumption by the build system. +ASL_TMP = $(patsubst %.c,%.asl.tmp,$@) + quiet_cmd_acpi_c_asl= ASL $< cmd_acpi_c_asl= \ - $(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -P $(UBOOTINCLUDE) -o $<.tmp $<; \ - iasl -p $< -tc $<.tmp $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \ - mv $(patsubst %.asl,%.hex,$<) $@ + $(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -P $(UBOOTINCLUDE) \ + -o $(ASL_TMP) $< && \ + iasl -p $@ -tc $(ASL_TMP) $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \ + mv $(patsubst %.c,%.hex,$@) $@ $(obj)/dsdt.c: $(src)/dsdt.asl $(call cmd,acpi_c_asl) |