From 715f599f8a0f8a0e60ee483f55eb207ade34ad49 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 6 Aug 2015 01:31:20 -0700 Subject: common: Display >=4GiB memory bank size bd->bi_dram[] has both start address and size defined as 32-bit, which is not the case on some platforms where >=4GiB memory bank is used. Change them to support such memory banks. Signed-off-by: Bin Meng diff --git a/common/board_f.c b/common/board_f.c index c7cc67c..8cca4de 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -206,7 +206,8 @@ static int show_dram_config(void) debug("\nRAM Configuration:\n"); for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) { size += gd->bd->bi_dram[i].size; - debug("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); + debug("Bank #%d: %llx ", i, + (unsigned long long)(gd->bd->bi_dram[i].start)); #ifdef DEBUG print_size(gd->bd->bi_dram[i].size, "\n"); #endif diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h index c918049..9f3351d 100644 --- a/include/asm-generic/u-boot.h +++ b/include/asm-generic/u-boot.h @@ -130,8 +130,8 @@ typedef struct bd_info { ulong bi_boot_params; /* where this board expects params */ #ifdef CONFIG_NR_DRAM_BANKS struct { /* RAM configuration */ - ulong start; - ulong size; + phys_addr_t start; + phys_size_t size; } bi_dram[CONFIG_NR_DRAM_BANKS]; #endif /* CONFIG_NR_DRAM_BANKS */ } bd_t; -- cgit v0.10.2 From 44a8b96f6488bc0392f99e6caa424539813dee20 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 6 Aug 2015 02:36:01 -0700 Subject: x86: baytrail: Add all IDE/SATA PCI device IDs The BayTrail SoC has 4 different PCI devices IDs regarding to IDE and AHCI. Add these IDs in pci_ids.h and also add the other SATA ID in the Bayley Bay and MinnowMax board configuration header. Signed-off-by: Bin Meng diff --git a/include/configs/bayleybay.h b/include/configs/bayleybay.h index ecda4ba..c590f56 100644 --- a/include/configs/bayleybay.h +++ b/include/configs/bayleybay.h @@ -26,7 +26,8 @@ "stderr=serial,vga\0" #define CONFIG_SCSI_DEV_LIST \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA} + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA_ALT} #define CONFIG_MMC #define CONFIG_SDHCI diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 2a40d1f..64fa676 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -26,8 +26,10 @@ "stdout=vga,serial\0" \ "stderr=vga,serial\0" -#define CONFIG_SCSI_DEV_LIST \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA} +#define CONFIG_SCSI_DEV_LIST \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA_ALT} + #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_MMC diff --git a/include/pci_ids.h b/include/pci_ids.h index 5771e12..49f7d7d 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2602,7 +2602,10 @@ #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO 0x0f15 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD 0x0f16 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC 0x0f1c -#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA 0x0f23 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IDE 0x0f20 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IDE_ALT 0x0f21 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA 0x0f22 +#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA_ALT 0x0f23 #define PCI_DEVICE_ID_INTEL_82541ER 0x1078 #define PCI_DEVICE_ID_INTEL_82541GI_LF 0x107c #define PCI_DEVICE_ID_INTEL_82542 0x1000 -- cgit v0.10.2 From f3b84a3032dd989a029320d9512846f48276db95 Mon Sep 17 00:00:00 2001 From: Andrew Bradford Date: Fri, 7 Aug 2015 08:36:35 -0400 Subject: x86: baytrail: Configure FSP UPD from device tree Allow for configuration of FSP UPD from the device tree which will override any settings which the FSP was built with itself. Modify the MinnowMax and BayleyBay boards to transfer sensible UPD settings from the Intel FSPv4 Gold release to the respective dts files, with the condition that the memory-down parameters for MinnowMax are also used. Signed-off-by: Andrew Bradford Reviewed-by: Bin Meng Tested-by: Bin Meng Removed fsp,mrc-debug-msg and fsp,enable-xhci for minnowmax, bayleybay Fixed lines >80col Signed-off-by: Simon Glass diff --git a/arch/x86/cpu/baytrail/fsp_configs.c b/arch/x86/cpu/baytrail/fsp_configs.c index 86b6926..a72d615 100644 --- a/arch/x86/cpu/baytrail/fsp_configs.c +++ b/arch/x86/cpu/baytrail/fsp_configs.c @@ -1,14 +1,18 @@ /* * Copyright (C) 2013, Intel Corporation * Copyright (C) 2014, Bin Meng + * Copyright (C) 2015, Kodak Alaris, Inc * * SPDX-License-Identifier: Intel */ #include +#include #include #include +DECLARE_GLOBAL_DATA_PTR; + /* ALC262 Verb Table - 10EC0262 */ static const uint32_t verb_table_data13[] = { /* Pin Complex (NID 0x11) */ @@ -116,41 +120,139 @@ const struct pch_azalia_config azalia_config = { .reset_wait_timer_us = 300 }; +/** + * Override the FSP's UPD. + * If the device tree does not specify an integer setting, use the default + * provided in Intel's Baytrail_FSP_Gold4.tgz release FSP/BayleyBayFsp.bsf file. + */ void update_fsp_upd(struct upd_region *fsp_upd) { struct memory_down_data *mem; + const void *blob = gd->fdt_blob; + int node; - /* - * Configure everything here to avoid the poor hard-pressed user - * needing to run Intel's binary configuration tool. It may also allow - * us to support the 1GB single core variant easily. - * - * TODO(sjg@chromium.org): Move to device tree - */ - fsp_upd->mrc_init_tseg_size = 8; - fsp_upd->mrc_init_mmio_size = 0x800; - fsp_upd->emmc_boot_mode = 0xff; - fsp_upd->enable_sdio = 1; - fsp_upd->enable_sdcard = 1; - fsp_upd->enable_hsuart0 = 1; fsp_upd->azalia_config_ptr = (uint32_t)&azalia_config; - fsp_upd->enable_i2_c0 = 0; - fsp_upd->enable_i2_c2 = 0; - fsp_upd->enable_i2_c3 = 0; - fsp_upd->enable_i2_c4 = 0; - fsp_upd->enable_xhci = 0; - fsp_upd->igd_render_standby = 1; + + node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_BAYTRAIL_FSP); + if (node < 0) { + debug("%s: Cannot find FSP node\n", __func__); + return; + } + + fsp_upd->mrc_init_tseg_size = fdtdec_get_int(blob, node, + "fsp,mrc-init-tseg-size", + 0); + fsp_upd->mrc_init_mmio_size = fdtdec_get_int(blob, node, + "fsp,mrc-init-mmio-size", + 0x800); + fsp_upd->mrc_init_spd_addr1 = fdtdec_get_int(blob, node, + "fsp,mrc-init-spd-addr1", + 0xa0); + fsp_upd->mrc_init_spd_addr2 = fdtdec_get_int(blob, node, + "fsp,mrc-init-spd-addr2", + 0xa2); + fsp_upd->emmc_boot_mode = fdtdec_get_int(blob, node, + "fsp,emmc-boot-mode", 2); + fsp_upd->enable_sdio = fdtdec_get_bool(blob, node, "fsp,enable-sdio"); + fsp_upd->enable_sdcard = fdtdec_get_bool(blob, node, + "fsp,enable-sdcard"); + fsp_upd->enable_hsuart0 = fdtdec_get_bool(blob, node, + "fsp,enable-hsuart0"); + fsp_upd->enable_hsuart1 = fdtdec_get_bool(blob, node, + "fsp,enable-hsuart1"); + fsp_upd->enable_spi = fdtdec_get_bool(blob, node, "fsp,enable-spi"); + fsp_upd->enable_sata = fdtdec_get_bool(blob, node, "fsp,enable-sata"); + fsp_upd->sata_mode = fdtdec_get_int(blob, node, "fsp,sata-mode", 1); + fsp_upd->enable_azalia = fdtdec_get_bool(blob, node, + "fsp,enable-azalia"); + fsp_upd->enable_xhci = fdtdec_get_bool(blob, node, "fsp,enable-xhci"); + fsp_upd->enable_lpe = fdtdec_get_bool(blob, node, "fsp,enable-lpe"); + fsp_upd->lpss_sio_enable_pci_mode = fdtdec_get_bool(blob, node, + "fsp,lpss-sio-enable-pci-mode"); + fsp_upd->enable_dma0 = fdtdec_get_bool(blob, node, "fsp,enable-dma0"); + fsp_upd->enable_dma1 = fdtdec_get_bool(blob, node, "fsp,enable-dma1"); + fsp_upd->enable_i2_c0 = fdtdec_get_bool(blob, node, "fsp,enable-i2c0"); + fsp_upd->enable_i2_c1 = fdtdec_get_bool(blob, node, "fsp,enable-i2c1"); + fsp_upd->enable_i2_c2 = fdtdec_get_bool(blob, node, "fsp,enable-i2c2"); + fsp_upd->enable_i2_c3 = fdtdec_get_bool(blob, node, "fsp,enable-i2c3"); + fsp_upd->enable_i2_c4 = fdtdec_get_bool(blob, node, "fsp,enable-i2c4"); + fsp_upd->enable_i2_c5 = fdtdec_get_bool(blob, node, "fsp,enable-i2c5"); + fsp_upd->enable_i2_c6 = fdtdec_get_bool(blob, node, "fsp,enable-i2c6"); + fsp_upd->enable_pwm0 = fdtdec_get_bool(blob, node, "fsp,enable-pwm0"); + fsp_upd->enable_pwm1 = fdtdec_get_bool(blob, node, "fsp,enable-pwm1"); + fsp_upd->enable_hsi = fdtdec_get_bool(blob, node, "fsp,enable-hsi"); + fsp_upd->igd_dvmt50_pre_alloc = fdtdec_get_int(blob, node, + "fsp,igd-dvmt50-pre-alloc", 2); + fsp_upd->aperture_size = fdtdec_get_int(blob, node, "fsp,aperture-size", + 2); + fsp_upd->gtt_size = fdtdec_get_int(blob, node, "fsp,gtt-size", 2); + fsp_upd->serial_debug_port_address = fdtdec_get_int(blob, node, + "fsp,serial-debug-port-address", 0x3f8); + fsp_upd->serial_debug_port_type = fdtdec_get_int(blob, node, + "fsp,serial-debug-port-type", 1); + fsp_upd->mrc_debug_msg = fdtdec_get_bool(blob, node, + "fsp,mrc-debug-msg"); + fsp_upd->isp_enable = fdtdec_get_bool(blob, node, "fsp,isp-enable"); + fsp_upd->scc_enable_pci_mode = fdtdec_get_bool(blob, node, + "fsp,scc-enable-pci-mode"); + fsp_upd->igd_render_standby = fdtdec_get_bool(blob, node, + "fsp,igd-render-standby"); + fsp_upd->txe_uma_enable = fdtdec_get_bool(blob, node, + "fsp,txe-uma-enable"); + fsp_upd->os_selection = fdtdec_get_int(blob, node, "fsp,os-selection", + 4); + fsp_upd->emmc45_ddr50_enabled = fdtdec_get_bool(blob, node, + "fsp,emmc45-ddr50-enabled"); + fsp_upd->emmc45_hs200_enabled = fdtdec_get_bool(blob, node, + "fsp,emmc45-hs200-enabled"); + fsp_upd->emmc45_retune_timer_value = fdtdec_get_int(blob, node, + "fsp,emmc45-retune-timer-value", 8); + fsp_upd->enable_igd = fdtdec_get_bool(blob, node, "fsp,enable-igd"); mem = &fsp_upd->memory_params; - mem->enable_memory_down = 1; - mem->dram_speed = 1; - mem->dimm_width = 1; - mem->dimm_density = 2; - mem->dimm_tcl = 0xb; - mem->dimm_trpt_rcd = 0xb; - mem->dimm_twr = 0xc; - mem->dimm_twtr = 6; - mem->dimm_trrd = 6; - mem->dimm_trtp = 6; - mem->dimm_tfaw = 0x14; + mem->enable_memory_down = fdtdec_get_bool(blob, node, + "fsp,enable-memory-down"); + if (mem->enable_memory_down) { + node = fdtdec_next_compatible(blob, node, + COMPAT_INTEL_BAYTRAIL_FSP_MDP); + if (node < 0) { + debug("%s: Cannot find FSP memory-down-params node\n", + __func__); + } else { + mem->dram_speed = fdtdec_get_int(blob, node, + "fsp,dram-speed", + 0x02); + mem->dram_type = fdtdec_get_int(blob, node, + "fsp,dram-type", 0x01); + mem->dimm_0_enable = fdtdec_get_bool(blob, node, + "fsp,dimm-0-enable"); + mem->dimm_1_enable = fdtdec_get_bool(blob, node, + "fsp,dimm-1-enable"); + mem->dimm_width = fdtdec_get_int(blob, node, + "fsp,dimm-width", + 0x00); + mem->dimm_density = fdtdec_get_int(blob, node, + "fsp,dimm-density", + 0x01); + mem->dimm_bus_width = fdtdec_get_int(blob, node, + "fsp,dimm-bus-width", 0x03); + mem->dimm_sides = fdtdec_get_int(blob, node, + "fsp,dimm-sides", + 0x00); + mem->dimm_tcl = fdtdec_get_int(blob, node, + "fsp,dimm-tcl", 0x09); + mem->dimm_trpt_rcd = fdtdec_get_int(blob, node, + "fsp,dimm-trpt-rcd", 0x09); + mem->dimm_twr = fdtdec_get_int(blob, node, + "fsp,dimm-twr", 0x0A); + mem->dimm_twtr = fdtdec_get_int(blob, node, + "fsp,dimm-twtr", 0x05); + mem->dimm_trrd = fdtdec_get_int(blob, node, + "fsp,dimm-trrd", 0x04); + mem->dimm_trtp = fdtdec_get_int(blob, node, + "fsp,dimm-trtp", 0x05); + mem->dimm_tfaw = fdtdec_get_int(blob, node, + "fsp,dimm-tfaw", 0x14); + } + } } diff --git a/arch/x86/dts/bayleybay.dts b/arch/x86/dts/bayleybay.dts index 9f8fa70..8f0e192 100644 --- a/arch/x86/dts/bayleybay.dts +++ b/arch/x86/dts/bayleybay.dts @@ -188,6 +188,44 @@ }; }; + fsp { + compatible = "intel,baytrail-fsp"; + fsp,mrc-init-tseg-size = <0>; + fsp,mrc-init-mmio-size = <0x800>; + fsp,mrc-init-spd-addr1 = <0xa0>; + fsp,mrc-init-spd-addr2 = <0xa2>; + fsp,emmc-boot-mode = <2>; + fsp,enable-sdio; + fsp,enable-sdcard; + fsp,enable-hsuart1; + fsp,enable-spi; + fsp,enable-sata; + fsp,sata-mode = <1>; + fsp,enable-lpe; + fsp,lpss-sio-enable-pci-mode; + fsp,enable-dma0; + fsp,enable-dma1; + fsp,enable-i2c0; + fsp,enable-i2c1; + fsp,enable-i2c2; + fsp,enable-i2c3; + fsp,enable-i2c4; + fsp,enable-i2c5; + fsp,enable-i2c6; + fsp,enable-pwm0; + fsp,enable-pwm1; + fsp,igd-dvmt50-pre-alloc = <2>; + fsp,aperture-size = <2>; + fsp,gtt-size = <2>; + fsp,serial-debug-port-address = <0x3f8>; + fsp,serial-debug-port-type = <1>; + fsp,scc-enable-pci-mode; + fsp,os-selection = <4>; + fsp,emmc45-ddr50-enabled; + fsp,emmc45-retune-timer-value = <8>; + fsp,enable-igd; + }; + microcode { update@0 { #include "microcode/m0230671117.dtsi" diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 9527233..d0c0fe6 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -122,6 +122,62 @@ 0x01000000 0x0 0x2000 0x2000 0 0xe000>; }; + fsp { + compatible = "intel,baytrail-fsp"; + fsp,mrc-init-tseg-size = <0>; + fsp,mrc-init-mmio-size = <0x800>; + fsp,mrc-init-spd-addr1 = <0xa0>; + fsp,mrc-init-spd-addr2 = <0xa2>; + fsp,emmc-boot-mode = <2>; + fsp,enable-sdio; + fsp,enable-sdcard; + fsp,enable-hsuart1; + fsp,enable-spi; + fsp,enable-sata; + fsp,sata-mode = <1>; + fsp,enable-lpe; + fsp,lpss-sio-enable-pci-mode; + fsp,enable-dma0; + fsp,enable-dma1; + fsp,enable-i2c0; + fsp,enable-i2c1; + fsp,enable-i2c2; + fsp,enable-i2c3; + fsp,enable-i2c4; + fsp,enable-i2c5; + fsp,enable-i2c6; + fsp,enable-pwm0; + fsp,enable-pwm1; + fsp,igd-dvmt50-pre-alloc = <2>; + fsp,aperture-size = <2>; + fsp,gtt-size = <2>; + fsp,serial-debug-port-address = <0x3f8>; + fsp,serial-debug-port-type = <1>; + fsp,scc-enable-pci-mode; + fsp,os-selection = <4>; + fsp,emmc45-ddr50-enabled; + fsp,emmc45-retune-timer-value = <8>; + fsp,enable-igd; + fsp,enable-memory-down; + fsp,memory-down-params { + compatible = "intel,baytrail-fsp-mdp"; + fsp,dram-speed = <1>; + fsp,dram-type = <1>; + fsp,dimm-0-enable; + fsp,dimm-width = <1>; + fsp,dimm-density = <2>; + fsp,dimm-bus-width = <3>; + fsp,dimm-sides = <0>; + fsp,dimm-tcl = <0xb>; + fsp,dimm-trpt-rcd = <0xb>; + fsp,dimm-twr = <0xc>; + fsp,dimm-twtr = <6>; + fsp,dimm-trrd = <6>; + fsp,dimm-trtp = <6>; + fsp,dimm-tfaw = <0x14>; + }; + }; + spi { #address-cells = <1>; #size-cells = <0>; diff --git a/doc/device-tree-bindings/misc/intel,baytrail-fsp.txt b/doc/device-tree-bindings/misc/intel,baytrail-fsp.txt new file mode 100644 index 0000000..b44b5b5 --- /dev/null +++ b/doc/device-tree-bindings/misc/intel,baytrail-fsp.txt @@ -0,0 +1,158 @@ +Intel Bay Trail FSP UPD Binding +=============================== + +The device tree node which describes the overriding of the Intel Bay Trail FSP +UPD data for configuring the SoC. + +All properties can be found within the `upd-region` struct in +arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h, under the same names, and in +Intel's FSP Binary Configuration Tool for Bay Trail. This list of properties is +matched up to Intel's E3800 FSPv4 release. + +# Boolean properties: + +- fsp,enable-sdio +- fsp,enable-sdcard +- fsp,enable-hsuart0 +- fsp,enable-hsuart1 +- fsp,enable-spi +- fsp,enable-sata +- fsp,enable-azalia +- fsp,enable-xhci +- fsp,enable-lpe +- fsp,lpss-sio-enable-pci-mode +- fsp,enable-dma0 +- fsp,enable-dma1 +- fsp,enable-i2-c0 +- fsp,enable-i2-c1 +- fsp,enable-i2-c2 +- fsp,enable-i2-c3 +- fsp,enable-i2-c4 +- fsp,enable-i2-c5 +- fsp,enable-i2-c6 +- fsp,enable-pwm0 +- fsp,enable-pwm1 +- fsp,enable-hsi +- fsp,mrc-debug-msg +- fsp,isp-enable +- fsp,scc-enable-pci-mode +- fsp,igd-render-standby +- fsp,txe-uma-enable +- fsp,emmc45-ddr50-enabled +- fsp,emmc45-hs200-enabled +- fsp,enable-igd +- fsp,enable-memory-down + +If you set "fsp,enable-memory-down" you are strongly encouraged to provide an +"fsp,memory-down-params{};" to specify how your memory is configured. If you do +not set "fsp,enable-memory-down", then the DIMM SPD information will be +discovered by the FSP and used to setup main memory. + + +# Integer properties: + +- fsp,mrc-init-tseg-size +- fsp,mrc-init-mmio-size +- fsp,mrc-init-spd-addr1 +- fsp,mrc-init-spd-addr2 +- fsp,emmc-boot-mode +- fsp,sata-mode +- fsp,igd-dvmt50-pre-alloc +- fsp,aperture-size +- fsp,gtt-size +- fsp,serial-debug-port-address +- fsp,serial-debug-port-type +- fsp,os-selection +- fsp,emmc45-retune-timer-value + +- fsp,memory-down-params { + + # Boolean properties: + + - fsp,dimm-0-enable + - fsp,dimm-1-enable + + # Integer properties: + + - fsp,dram-speed + - fsp,dram-type + - fsp,dimm-width + - fsp,dimm-density + - fsp,dimm-bus-width + - fsp,dimm-sides + - fsp,dimm-tcl + - fsp,dimm-trpt-rcd + - fsp,dimm-twr + - fsp,dimm-twtr + - fsp,dimm-trrd + - fsp,dimm-trtp + - fsp,dimm-tfaw +}; + + +Example (from MinnowMax Dual Core): +----------------------------------- + +/ { + ... + + fsp { + compatible = "intel,baytrail-fsp"; + fsp,mrc-init-tseg-size = <0>; + fsp,mrc-init-mmio-size = <0x800>; + fsp,mrc-init-spd-addr1 = <0xa0>; + fsp,mrc-init-spd-addr2 = <0xa2>; + fsp,emmc-boot-mode = <2>; + fsp,enable-sdio; + fsp,enable-sdcard; + fsp,enable-hsuart1; + fsp,enable-spi; + fsp,enable-sata; + fsp,sata-mode = <1>; + fsp,enable-xhci; + fsp,enable-lpe; + fsp,lpss-sio-enable-pci-mode; + fsp,enable-dma0; + fsp,enable-dma1; + fsp,enable-i2c0; + fsp,enable-i2c1; + fsp,enable-i2c2; + fsp,enable-i2c3; + fsp,enable-i2c4; + fsp,enable-i2c5; + fsp,enable-i2c6; + fsp,enable-pwm0; + fsp,enable-pwm1; + fsp,igd-dvmt50-pre-alloc = <2>; + fsp,aperture-size = <2>; + fsp,gtt-size = <2>; + fsp,serial-debug-port-address = <0x3f8>; + fsp,serial-debug-port-type = <1>; + fsp,mrc-debug-msg; + fsp,scc-enable-pci-mode; + fsp,os-selection = <4>; + fsp,emmc45-ddr50-enabled; + fsp,emmc45-retune-timer-value = <8>; + fsp,enable-igd; + fsp,enable-memory-down; + fsp,memory-down-params { + compatible = "intel,baytrail-fsp-mdp"; + fsp,dram-speed = <1>; + fsp,dram-type = <1>; + fsp,dimm-0-enable; + fsp,dimm-width = <1>; + fsp,dimm-density = <2>; + fsp,dimm-bus-width = <3>; + fsp,dimm-sides = <0>; + fsp,dimm-tcl = <0xb>; + fsp,dimm-trpt-rcd = <0xb>; + fsp,dimm-twr = <0xc>; + fsp,dimm-twtr = <6>; + fsp,dimm-trrd = <6>; + fsp,dimm-trtp = <6>; + fsp,dimm-tfaw = <0x14>; + }; + }; + + ... +}; diff --git a/include/fdtdec.h b/include/fdtdec.h index eac679e..62acbd0 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -182,6 +182,8 @@ enum fdt_compat_id { COMPAT_INTEL_PCH, /* Intel PCH */ COMPAT_INTEL_IRQ_ROUTER, /* Intel Interrupt Router */ COMPAT_ALTERA_SOCFPGA_DWMAC, /* SoCFPGA Ethernet controller */ + COMPAT_INTEL_BAYTRAIL_FSP, /* Intel Bay Trail FSP */ + COMPAT_INTEL_BAYTRAIL_FSP_MDP, /* Intel FSP memory-down params */ COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index b201787..cdfc844 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -76,6 +76,8 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"), COMPAT(COMPAT_INTEL_IRQ_ROUTER, "intel,irq-router"), COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"), + COMPAT(COMPAT_INTEL_BAYTRAIL_FSP, "intel,baytrail-fsp"), + COMPAT(COMPAT_INTEL_BAYTRAIL_FSP_MDP, "intel,baytrail-fsp-mdp"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) -- cgit v0.10.2 From da60fb79349320a21fd0b7c1e602fa492291d1f7 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 Aug 2015 22:01:23 +0800 Subject: x86: fsp: Do not assert VPD_IMAGE_REV when DEBUG When using different release version of Intel FSP, the VPD_IMAGE_REV is different (ie: BayTrail Gold 3 is 0x0303 while Gold 4 is 0x0304). Remove the asserting of this so that U-Boot does not hang in a debug build. Signed-off-by: Bin Meng Acked-by: Simon Glass diff --git a/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h index eb0d506..3c782a8 100644 --- a/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h +++ b/arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h @@ -82,7 +82,6 @@ struct __packed upd_region { }; #define VPD_IMAGE_ID 0x3157454956594C56 /* 'VLYVIEW1' */ -#define VPD_IMAGE_REV 0x00000303 struct __packed vpd_region { uint64_t sign; /* Offset 0x0000 */ diff --git a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h index 3c57558..9c54ecc 100644 --- a/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h +++ b/arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h @@ -35,7 +35,6 @@ struct __packed upd_region { }; #define VPD_IMAGE_ID 0x445056574F4E4E4D /* 'MNNOWVPD' */ -#define VPD_IMAGE_REV 0x00000301 struct __packed vpd_region { u64 sign; /* Offset 0x0000 */ diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 4585166..1d48ff4 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -147,8 +147,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) fsp_hdr->cfg_region_off); /* Verify the VPD data region is valid */ - assert((fsp_vpd->img_rev == VPD_IMAGE_REV) && - (fsp_vpd->sign == VPD_IMAGE_ID)); + assert(fsp_vpd->sign == VPD_IMAGE_ID); /* Copy default data from Flash */ memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset), -- cgit v0.10.2 From 66afb4ed924693412f2f4e05fbfae6a642159402 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:03 -0600 Subject: dm: pci: Provide friendly config access functions At present there are no PCI functions which allow access to PCI configuration using a struct udevice. This is a sad situation for driver model as it makes use of PCI harder. Add these functions. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 6262f35..b79927e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -210,6 +210,17 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, return pci_bus_write_config(bus, bdf, offset, value, size); } +int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value, + enum pci_size_t size) +{ + struct udevice *bus; + + for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) + bus = bus->parent; + return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size); +} + + int pci_write_config32(pci_dev_t bdf, int offset, u32 value) { return pci_write_config(bdf, offset, value, PCI_SIZE_32); @@ -225,6 +236,21 @@ int pci_write_config8(pci_dev_t bdf, int offset, u8 value) return pci_write_config(bdf, offset, value, PCI_SIZE_8); } +int dm_pci_write_config8(struct udevice *dev, int offset, u8 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_8); +} + +int dm_pci_write_config16(struct udevice *dev, int offset, u16 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_16); +} + +int dm_pci_write_config32(struct udevice *dev, int offset, u32 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_32); +} + int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long *valuep, enum pci_size_t size) { @@ -249,6 +275,17 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, return pci_bus_read_config(bus, bdf, offset, valuep, size); } +int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep, + enum pci_size_t size) +{ + struct udevice *bus; + + for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) + bus = bus->parent; + return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep, + size); +} + int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) { unsigned long value; @@ -288,6 +325,45 @@ int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep) return 0; } +int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_8); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_16); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_32); + if (ret) + return ret; + *valuep = value; + + return 0; +} + int pci_auto_config_devices(struct udevice *bus) { struct pci_controller *hose = bus->uclass_priv; diff --git a/include/pci.h b/include/pci.h index 628ede0..d1e2765 100644 --- a/include/pci.h +++ b/include/pci.h @@ -988,6 +988,24 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long value, enum pci_size_t size); +/** + * Driver model PCI config access functions. Use these in preference to others + * when you have a valid device + */ +int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep, + enum pci_size_t size); + +int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep); +int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep); +int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep); + +int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value, + enum pci_size_t size); + +int dm_pci_write_config8(struct udevice *dev, int offset, u8 value); +int dm_pci_write_config16(struct udevice *dev, int offset, u16 value); +int dm_pci_write_config32(struct udevice *dev, int offset, u32 value); + /* * The following functions provide access to the above without needing the * size parameter. We are trying to encourage the use of the 8/16/32-style -- cgit v0.10.2 From 76c3fbcd3db61b9a3d9c38b0c18968322c5b1588 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:04 -0600 Subject: dm: pci: Add a way to iterate through all PCI devices These functions allow iteration through all PCI devices including bridges. The children of each PCI bus are returned in turn. This can be useful for configuring, checking or enumerating all the devices. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index b79927e..ad65427 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -775,6 +775,66 @@ static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); } +static int skip_to_next_device(struct udevice *bus, struct udevice **devp) +{ + struct udevice *dev; + int ret = 0; + + /* + * Scan through all the PCI controllers. On x86 there will only be one + * but that is not necessarily true on other hardware. + */ + do { + device_find_first_child(bus, &dev); + if (dev) { + *devp = dev; + return 0; + } + ret = uclass_next_device(&bus); + if (ret) + return ret; + } while (bus); + + return 0; +} + +int pci_find_next_device(struct udevice **devp) +{ + struct udevice *child = *devp; + struct udevice *bus = child->parent; + int ret; + + /* First try all the siblings */ + *devp = NULL; + while (child) { + device_find_next_child(&child); + if (child) { + *devp = child; + return 0; + } + } + + /* We ran out of siblings. Try the next bus */ + ret = uclass_next_device(&bus); + if (ret) + return ret; + + return bus ? skip_to_next_device(bus, devp) : 0; +} + +int pci_find_first_device(struct udevice **devp) +{ + struct udevice *bus; + int ret; + + *devp = NULL; + ret = uclass_first_device(UCLASS_PCI, &bus); + if (ret) + return ret; + + return skip_to_next_device(bus, devp); +} + UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index d1e2765..488ff44 100644 --- a/include/pci.h +++ b/include/pci.h @@ -910,6 +910,31 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, struct udevice **devp); /** + * pci_find_first_device() - return the first available PCI device + * + * This function and pci_find_first_device() allow iteration through all + * available PCI devices on all buses. Assuming there are any, this will + * return the first one. + * + * @devp: Set to the first available device, or NULL if no more are left + * or we got an error + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) + */ +int pci_find_first_device(struct udevice **devp); + +/** + * pci_find_next_device() - return the next available PCI device + * + * Finds the next available PCI device after the one supplied, or sets @devp + * to NULL if there are no more. + * + * @devp: On entry, the last device returned. Set to the next available + * device, or NULL if no more are left or we got an error + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) + */ +int pci_find_next_device(struct udevice **devp); + +/** * pci_get_ff() - Returns a mask for the given access size * * @size: Access size -- cgit v0.10.2 From 1adafd40bbe4282ff72ece5a7d80c8eb29061aff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:05 -0600 Subject: x86: Re-order efi-x86_defconfig Use savedefconfig to get this file into the correct order. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig index 1aa0655..43fb0c4 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_defconfig @@ -1,16 +1,16 @@ CONFIG_X86=y CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi" CONFIG_TARGET_EFI=y CONFIG_TSC_CALIBRATION_BYPASS=y +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_NET is not set CONFIG_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DM_PCI=y -CONFIG_DEFAULT_DEVICE_TREE="efi" -CONFIG_EFI=y -CONFIG_EFI_APP=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_EFI_CONSOLE=y CONFIG_DEBUG_UART_BASE=0 CONFIG_DEBUG_UART_CLOCK=0 -# CONFIG_CMD_NET is not set -# CONFIG_CMD_BOOTM is not set +# CONFIG_X86_SERIAL is not set +CONFIG_EFI=y -- cgit v0.10.2 From 9e3ff9c2b464e4aa342bed74a534ec9844612459 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:06 -0600 Subject: x86: Tidy up the PIRQ routing code a little This code could use a little tightening up. There is some repetition and an odd use of fdtdec_get_int_array(). Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 97dd000..6be2f81 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -125,10 +125,10 @@ static int create_pirq_routing_table(void) return -EINVAL; } - ret = fdtdec_get_int_array(blob, node, "intel,pirq-link", - &irq_router.link_base, 1); - if (ret) + ret = fdtdec_get_int(blob, node, "intel,pirq-link", -1); + if (ret == -1) return ret; + irq_router.link_base = ret; irq_router.irq_mask = fdtdec_get_int(blob, node, "intel,pirq-mask", PIRQ_BITMAP); @@ -156,18 +156,13 @@ static int create_pirq_routing_table(void) } cell = fdt_getprop(blob, node, "intel,pirq-routing", &len); - if (!cell) - return -EINVAL; - - if ((len % sizeof(struct pirq_routing)) == 0) - count = len / sizeof(struct pirq_routing); - else + if (!cell || len % sizeof(struct pirq_routing)) return -EINVAL; + count = len / sizeof(struct pirq_routing); - rt = malloc(sizeof(struct irq_routing_table)); + rt = calloc(1, sizeof(struct irq_routing_table)); if (!rt) return -ENOMEM; - memset((char *)rt, 0, sizeof(struct irq_routing_table)); /* Populate the PIRQ table fields */ rt->signature = PIRQ_SIGNATURE; @@ -181,7 +176,8 @@ static int create_pirq_routing_table(void) slot_base = rt->slots; /* Now fill in the irq_info entries in the PIRQ table */ - for (i = 0; i < count; i++) { + for (i = 0; i < count; + i++, cell += sizeof(struct pirq_routing) / sizeof(u32)) { struct pirq_routing pr; pr.bdf = fdt_addr_to_cpu(cell[0]); @@ -212,25 +208,14 @@ static int create_pirq_routing_table(void) if (slot->irq[pr.pin - 1].link != LINK_N2V(pr.pirq, irq_router.link_base)) debug("WARNING: Inconsistent PIRQ routing information\n"); - - cell += sizeof(struct pirq_routing) / - sizeof(u32); - continue; - } else { - debug("writing INT%c\n", 'A' + pr.pin - 1); - fill_irq_info(slot, PCI_BUS(pr.bdf), - PCI_DEV(pr.bdf), pr.pin, pr.pirq); - cell += sizeof(struct pirq_routing) / - sizeof(u32); continue; } + } else { + slot = slot_base + irq_entries++; } - - slot = slot_base + irq_entries; - fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), - pr.pin, pr.pirq); - irq_entries++; - cell += sizeof(struct pirq_routing) / sizeof(u32); + debug("writing INT%c\n", 'A' + pr.pin - 1); + fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin, + pr.pirq); } rt->size = irq_entries * sizeof(struct irq_info) + 32; -- cgit v0.10.2 From 412400abaaa6ef02adff35419188689ea6d3ec7e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:07 -0600 Subject: x86: Split out fsp_init_phase_pci() code into a new function This code may be useful for boards that use driver model for PCI. Note: It would be better to have driver model automatically call this function somehow. However for now it is probably safer to have it under board control. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h index c6c7dc0..7317dda 100644 --- a/arch/x86/include/asm/fsp/fsp_support.h +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -207,4 +207,11 @@ void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len); */ void update_fsp_upd(struct upd_region *fsp_upd); +/** + * fsp_init_phase_pci() - Tell the FSP that we have completed PCI init + * + * @return 0 if OK, -EPERM if the FSP gave an error. + */ +int fsp_init_phase_pci(void); + #endif diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index c585710..6f72c6d 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -19,19 +19,24 @@ int print_cpuinfo(void) return default_print_cpuinfo(); } -int board_pci_post_scan(struct pci_controller *hose) +int fsp_init_phase_pci(void) { u32 status; /* call into FspNotify */ debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); status = fsp_notify(NULL, INIT_PHASE_PCI); - if (status != FSP_SUCCESS) + if (status) debug("fail, error code %x\n", status); else debug("OK\n"); - return 0; + return status ? -EPERM : 0; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + return fsp_init_phase_pci(); } void board_final_cleanup(void) -- cgit v0.10.2 From 7e4be120e88974d49ebb4bcf837134cfb71efc8c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:08 -0600 Subject: x86: Allow pirq_init() to return an error This function can fail. In this case we should return the error rather than swallowing it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 610e9d9..225ea38 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -40,8 +40,6 @@ int arch_cpu_init(void) int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } #endif diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 6be2f81..35b29f6 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -225,17 +225,22 @@ static int create_pirq_routing_table(void) return 0; } -void pirq_init(void) +int pirq_init(void) { + int ret; + cpu_irq_init(); - if (create_pirq_routing_table()) { + ret = create_pirq_routing_table(); + if (ret) { debug("Failed to create pirq routing table\n"); - } else { - /* Route PIRQ */ - pirq_route_irqs(pirq_routing_table->slots, - get_irq_slot_count(pirq_routing_table)); + return ret; } + /* Route PIRQ */ + pirq_route_irqs(pirq_routing_table->slots, + get_irq_slot_count(pirq_routing_table)); + + return 0; } u32 write_pirq_routing_table(u32 addr) diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 64634a9..7c03e02 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -41,7 +41,5 @@ void reset_cpu(ulong addr) int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 20cc09e..12ac376 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -174,7 +174,5 @@ void cpu_irq_init(void) int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index de50893..c465642 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -80,7 +80,5 @@ void cpu_irq_init(void) int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 4de5512..6697da3 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -70,7 +70,9 @@ void cpu_irq_init(void); * * This initializes the PIRQ routing on the platform and configures all PCI * devices' interrupt line register to a working IRQ number on the 8259 PIC. + * + * @return 0 if OK, -ve on error */ -void pirq_init(void); +int pirq_init(void); #endif /* _ARCH_IRQ_H_ */ -- cgit v0.10.2 From 46f8efee70313a4f8fb3831dadbc0530fcbfa9b6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:10 -0600 Subject: x86: baytrail: Tidy up interrupt and FSP init We should signal to the FSP that PCI enumeration is complete. Perform this task in a suitable place. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 225ea38..2d5a0eb 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -9,6 +9,7 @@ #include #include #include +#include static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, @@ -40,6 +41,12 @@ int arch_cpu_init(void) int arch_misc_init(void) { - return pirq_init(); + int ret; + + ret = pirq_init(); + if (ret) + return ret; + + return fsp_init_phase_pci(); } #endif -- cgit v0.10.2 From c8896ee481a2ca4a25f5f1f3c2d211dbc127bdb9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 07:05:12 -0600 Subject: x86: baytrail: Support running as an EFI payload We should not fiddle with interrupts or the FSP when running as an EFI payload. Detect this and skip this code. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 2d5a0eb..6c3dfe8 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -43,6 +43,8 @@ int arch_misc_init(void) { int ret; + if (!ll_boot_init()) + return 0; ret = pirq_init(); if (ret) return ret; -- cgit v0.10.2 From 93afae5d055bc5467d49f211b2167f6f0f4e39f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:44:28 -0600 Subject: x86: Remove init_gd() function This is declared but no-longer exists. Drop it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 4dae365..1c459d5 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -14,7 +14,6 @@ extern char gdt_rom[]; int arch_cpu_init(void); int x86_cpu_init_f(void); int cpu_init_f(void); -void init_gd(gd_t *id, u64 *gdt_addr); void setup_gdt(gd_t *id, u64 *gdt_addr); /* * Setup FSP execution environment GDT to use the one we used in -- cgit v0.10.2 From 2afddae07523f23f77acd066ad1719f53d289f98 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:44:29 -0600 Subject: Align global_data to a 16-byte boundary Some archs like to have larger alignment for their global data. Use 16 bytes which suits all current archs. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/common/board_f.c b/common/board_f.c index 8cca4de..74f77f1 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -499,6 +499,7 @@ static int setup_machine(void) static int reserve_global_data(void) { gd->start_addr_sp -= sizeof(gd_t); + gd->start_addr_sp &= ~0xf; gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t)); debug("Reserving %zu Bytes for Global Data at: %08lx\n", sizeof(gd_t), gd->start_addr_sp); diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 2155265..cc369fc 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -99,7 +99,8 @@ typedef struct global_data { int pcidelay_done; #endif struct udevice *cur_serial_dev; /* current serial device */ - struct arch_global_data arch; /* architecture-specific data */ + /* arch-specific data */ + struct arch_global_data arch __attribute__((aligned(16))); } gd_t; #endif -- cgit v0.10.2 From 1fed87db6a6a2eea7f93667e98db41e258b9c8f0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:44:30 -0600 Subject: Allow arch-specific setting of global_data in board_init_f_mem() At present we have a simple assignment to gd. With some archs this is implemented as a register or through some other means; a simple assignment does not suit in all cases. Change this to a function and add documentation to describe how this all works. Signed-off-by: Simon Glass Reviewed-by: York Sun Reviewed-by: Bin Meng diff --git a/common/board_f.c b/common/board_f.c index 74f77f1..37b7bf5 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -1027,16 +1027,25 @@ void board_init_f_r(void) } #endif /* CONFIG_X86 */ +/* Unfortunately x86 can't compile this code as gd cannot be assigned */ #ifndef CONFIG_X86 +__weak void arch_setup_gd(struct global_data *gd_ptr) +{ + gd = gd_ptr; +} + ulong board_init_f_mem(ulong top) { + struct global_data *gd_ptr; + /* Leave space for the stack we are running with now */ top -= 0x40; top -= sizeof(struct global_data); top = ALIGN(top, 16); - gd = (struct global_data *)top; - memset((void *)gd, '\0', sizeof(*gd)); + gd_ptr = (struct global_data *)top; + memset(gd_ptr, '\0', sizeof(*gd)); + arch_setup_gd(gd_ptr); #ifdef CONFIG_SYS_MALLOC_F_LEN top -= CONFIG_SYS_MALLOC_F_LEN; diff --git a/include/common.h b/include/common.h index 5c076d6..c48e5bc 100644 --- a/include/common.h +++ b/include/common.h @@ -217,6 +217,49 @@ extern char console_buffer[]; /* arch/$(ARCH)/lib/board.c */ void board_init_f(ulong); void board_init_r(gd_t *, ulong) __attribute__ ((noreturn)); + +/** + * board_init_f_mem() - Allocate global data and set stack position + * + * This function is called by each architecture very early in the start-up + * code to set up the environment for board_init_f(). It allocates space for + * global_data (see include/asm-generic/global_data.h) and places the stack + * below this. + * + * This function requires a stack[1] Normally this is at @top. The function + * starts allocating space from 64 bytes below @top. First it creates space + * for global_data. Then it calls arch_setup_gd() which sets gd to point to + * the global_data space and can reserve additional bytes of space if + * required). Finally it allocates early malloc() memory + * (CONFIG_SYS_MALLOC_F_LEN). The new top of the stack is just below this, + * and it returned by this function. + * + * [1] Strictly speaking it would be possible to implement this function + * in C on many archs such that it does not require a stack. However this + * does not seem hugely important as only 64 byte are wasted. The 64 bytes + * are used to handle the calling standard which generally requires pushing + * addresses or registers onto the stack. We should be able to get away with + * less if this becomes important. + * + * @top: Top of available memory, also normally the top of the stack + * @return: New stack location + */ +ulong board_init_f_mem(ulong top); + +/** + * arch_setup_gd() - Set up the global_data pointer + * + * This pointer is special in some architectures and cannot easily be assigned + * to. For example on x86 it is implemented by adding a specific record to its + * Global Descriptor Table! So we we provide a function to carry out this task. + * For most architectures this can simply be: + * + * gd = gd_ptr; + * + * @gd_ptr: Pointer to global data + */ +void arch_setup_gd(gd_t *gd_ptr); + int checkboard(void); int show_board_info(void); int checkflash(void); -- cgit v0.10.2 From 2db937456114d964e814f8cc25131e3b2c641b49 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:44:31 -0600 Subject: x86: Move the GDT into global_data Rather than keeping track of the Global Descriptor Table in its own memory we may as well put it in global_data with everything else. As a first step, stop using the separately allocated GDT. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 129777c..4f57145 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -136,9 +136,10 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries) asm volatile("lgdtl %0\n" : : "m" (gdt)); } -void setup_gdt(gd_t *id, u64 *gdt_addr) +void setup_gdt(gd_t *new_gd, u64 *gdt_addr) { - id->arch.gdt = gdt_addr; + gdt_addr = new_gd->arch.gdt; + /* CS: code, read/execute, 4 GB, base 0 */ gdt_addr[X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff); @@ -146,9 +147,9 @@ void setup_gdt(gd_t *id, u64 *gdt_addr) gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff); /* FS: data, read/write, 4 GB, base (Global Data Pointer) */ - id->arch.gd_addr = id; + new_gd->arch.gd_addr = new_gd; gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093, - (ulong)&id->arch.gd_addr, 0xfffff); + (ulong)&new_gd->arch.gd_addr, 0xfffff); /* 16-bit CS: code, read/execute, 64 kB, base 0 */ gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x009b, 0, 0x0ffff); diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index f7e3889..35148ab 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -10,6 +10,8 @@ #ifndef __ASSEMBLY__ +#include + enum pei_boot_mode_t { PEI_BOOT_NONE = 0, PEI_BOOT_SOFT_RESET, @@ -44,6 +46,7 @@ struct mtrr_request { /* Architecture-specific global data */ struct arch_global_data { + u64 gdt[X86_GDT_NUM_ENTRIES] __aligned(16); struct global_data *gd_addr; /* Location of Global Data */ uint8_t x86; /* CPU family */ uint8_t x86_vendor; /* CPU vendor */ @@ -68,7 +71,6 @@ struct arch_global_data { /* MRC training data to save for the next boot */ char *mrc_output; unsigned int mrc_output_len; - void *gdt; /* Global descriptor table */ ulong table; /* Table pointer from previous loader */ }; -- cgit v0.10.2 From f0c7d9c74642ccd6c76993b721b0fb87aab685fa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:44:32 -0600 Subject: x86: Switch to using generic global_data setup There is quite a bit of assembler code that can be removed if we use the generic global_data setup. Less arch-specific code makes it easier to add new features and maintain the start-up code. Drop the unneeded code and adjust the hooks in board_f.c to cope. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 4f57145..1b76ca1 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -136,8 +136,10 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries) asm volatile("lgdtl %0\n" : : "m" (gdt)); } -void setup_gdt(gd_t *new_gd, u64 *gdt_addr) +void arch_setup_gd(gd_t *new_gd) { + u64 *gdt_addr; + gdt_addr = new_gd->arch.gdt; /* CS: code, read/execute, 4 GB, base 0 */ diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 313fa3f..e94ddc4 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -104,8 +104,7 @@ car_init_ret: * * top-> CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE * MRC area - * global_data - * x86 global descriptor table + * global_data with x86 global descriptor table * early malloc area * stack * bottom-> CONFIG_SYS_CAR_ADDR @@ -120,13 +119,10 @@ car_init_ret: * and esi holds the HOB list address returned by the FSP. */ #endif - - /* Reserve space on stack for global data */ - subl $GENERATED_GBL_DATA_SIZE, %esp - - /* Align global data to 16-byte boundary */ - andl $0xfffffff0, %esp - post_code(POST_START_STACK) + /* Set up global data */ + mov %esp, %eax + call board_init_f_mem + mov %eax, %esp /* * Debug UART is available here although it may not be plumbed out @@ -137,56 +133,21 @@ car_init_ret: * call printch */ - /* Zero the global data since it won't happen later */ - xorl %eax, %eax - movl $GENERATED_GBL_DATA_SIZE, %ecx - movl %esp, %edi - rep stosb - + /* Get address of global_data */ + mov %fs:0, %edx #ifdef CONFIG_HAVE_FSP + /* Store the HOB list if we have one */ test %esi, %esi jz skip_hob - - /* Store HOB list */ - movl %esp, %edx - addl $GD_HOB_LIST, %edx - movl %esi, (%edx) + movl %esi, GD_HOB_LIST(%edx) skip_hob: #else /* Store table pointer */ - movl %esp, %edx - addl $GD_TABLE, %edx - movl %esi, (%edx) + movl %esi, GD_TABLE(%edx) #endif - - /* Setup first parameter to setup_gdt, pointer to global_data */ - movl %esp, %eax - - /* Reserve space for global descriptor table */ - subl $X86_GDT_SIZE, %esp - - /* Align temporary global descriptor table to 16-byte boundary */ - andl $0xfffffff0, %esp - movl %esp, %ecx - -#if defined(CONFIG_SYS_MALLOC_F_LEN) - /* Set up the pre-relocation malloc pool */ - subl $CONFIG_SYS_MALLOC_F_LEN, %esp - movl %eax, %edx - addl $GD_MALLOC_BASE, %edx - movl %esp, (%edx) -#endif - /* Store BIST into global_data */ - movl %eax, %edx - addl $GD_BIST, %edx - movl %ebp, (%edx) - - /* Set second parameter to setup_gdt() */ - movl %ecx, %edx - - /* Setup global descriptor table so gd->xyz works */ - call setup_gdt + /* Store BIST */ + movl %ebp, GD_BIST(%edx) /* Set parameter to board_init_f() to boot flags */ post_code(POST_START_DONE) @@ -213,37 +174,7 @@ board_init_f_r_trampoline: /* Stack grows down from top of SDRAM */ movl %eax, %esp - /* Reserve space on stack for global data */ - subl $GENERATED_GBL_DATA_SIZE, %esp - - /* Align global data to 16-byte boundary */ - andl $0xfffffff0, %esp - - /* Setup first parameter to memcpy() and setup_gdt() */ - movl %esp, %eax - - /* Setup second parameter to memcpy() */ - fs movl 0, %edx - - /* Set third parameter to memcpy() */ - movl $GENERATED_GBL_DATA_SIZE, %ecx - - /* Copy global data from CAR to SDRAM stack */ - call memcpy - - /* Reserve space for global descriptor table */ - subl $X86_GDT_SIZE, %esp - - /* Align global descriptor table to 16-byte boundary */ - andl $0xfffffff0, %esp - - /* Set second parameter to setup_gdt() */ - movl %esp, %edx - - /* Setup global descriptor table so gd->xyz works */ - call setup_gdt - - /* Set if we need to disable CAR */ + /* See if we need to disable CAR */ .weak car_uninit movl $car_uninit, %eax cmpl $0, %eax diff --git a/common/board_f.c b/common/board_f.c index 37b7bf5..c959774 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -715,6 +715,7 @@ static int jump_to_copy(void) * with the stack in SDRAM and Global Data in temporary memory * (CPU cache) */ + arch_setup_gd(gd->new_gd); board_init_f_r_trampoline(gd->start_addr_sp); #else relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr); @@ -1033,6 +1034,7 @@ __weak void arch_setup_gd(struct global_data *gd_ptr) { gd = gd_ptr; } +#endif /* !CONFIG_X86 */ ulong board_init_f_mem(ulong top) { @@ -1054,4 +1056,3 @@ ulong board_init_f_mem(ulong top) return top; } -#endif /* !CONFIG_X86 */ -- cgit v0.10.2 From 78689170329931ad81599d545cddc1b63b1bb4dc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 20:54:52 -0600 Subject: Revert "dm: pci: Allow scan bridge child devices before relocation" This reverts commit df189d9ba3f8fd1bc67e3c0c3c4ace16cd065ee1. Unfortunately this commit breaks chromebook_link because it adds lots of PCI devices before relocation and there is not enough pre-reloc malloc() memory. Rathar then increase this memory, revert for now until we figure this out. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index ad65427..7d41d56 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -717,6 +717,10 @@ static int pci_uclass_post_probe(struct udevice *bus) { int ret; + /* Don't scan buses before relocation */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + debug("%s: probing bus %d\n", __func__, bus->seq); ret = pci_bind_bus_devices(bus); if (ret) -- cgit v0.10.2 From 3d4e2491ff4979ace37bbecb5081d52d3f6c1fec Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 22:02:52 -0600 Subject: x86: Convert minnowmax to use CONFIG_DM_USB Move to driver model for USB on minnowmax. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index a67597d..2d9fa8c 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -18,13 +18,14 @@ CONFIG_OF_CONTROL=y CONFIG_CPU=y CONFIG_DM_PCI=y CONFIG_SPI_FLASH=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x3f8 +CONFIG_DEBUG_UART_CLOCK=1843200 CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_DM_RTC=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_SYS_VSNPRINTF=y -CONFIG_DEBUG_UART=y -CONFIG_DEBUG_UART_NS16550=y -CONFIG_DEBUG_UART_BASE=0x3f8 -CONFIG_DEBUG_UART_CLOCK=1843200 -- cgit v0.10.2 From b8098bc1c14ca397291209e0281f0862ddc6f057 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 22:02:53 -0600 Subject: x86: Convert minnowmax to use CONFIG_DM_NET Move to driver model for networking on minnowmax. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/board/intel/minnowmax/minnowmax.c b/board/intel/minnowmax/minnowmax.c index c4f2c33..44e5bf4 100644 --- a/board/intel/minnowmax/minnowmax.c +++ b/board/intel/minnowmax/minnowmax.c @@ -6,7 +6,6 @@ #include #include -#include int arch_early_init_r(void) { @@ -20,8 +19,3 @@ void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio) { return; } - -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 2d9fa8c..578fcce 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -18,6 +18,7 @@ CONFIG_OF_CONTROL=y CONFIG_CPU=y CONFIG_DM_PCI=y CONFIG_SPI_FLASH=y +CONFIG_DM_ETH=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_UART_BASE=0x3f8 CONFIG_DEBUG_UART_CLOCK=1843200 -- cgit v0.10.2 From 7399515d25066368707d804d90cc8d3976f313bc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Aug 2015 22:02:54 -0600 Subject: x86: Show the un-relocated IP address in exceptions When trying to figure out where an exception has occured, the relocated address is not a lot of help. Its value depends on various factors. Show the un-relocated IP as well. This can be looked up in System.map directly. Signed-off-by: Simon Glass Reviewed-by: Tom Rini Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index 9217307..addd26e 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -103,6 +103,8 @@ static void dump_regs(struct irq_regs *regs) printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n", (u16)cs, eip, eflags); + if (gd->flags & GD_FLG_RELOC) + printf("Original EIP :[<%08lx>]\n", eip - gd->reloc_off); printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); -- cgit v0.10.2 From 57dccb55fc48825db0c125926112af70faabc151 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Aug 2015 23:26:59 -0700 Subject: video: vesa: Correct a typo in the Kconfig VESA mode string There is one typo in the VESA mode 105h string. Correct it. Signed-off-by: Bin Meng Acked-by: Simon Glass diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5cb3685..955b0b7 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -44,7 +44,7 @@ config FRAMEBUFFER_VESA_MODE_104 bool "1024x768 16-color" config FRAMEBUFFER_VESA_MODE_105 - bool "1024x7686 256-color" + bool "1024x768 256-color" config FRAMEBUFFER_VESA_MODE_106 bool "1280x1024 16-color" -- cgit v0.10.2 From ecfeadabb74452a0d78e6d12de9b63263a4a90c5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Aug 2015 23:58:39 -0700 Subject: x86: Set APs' req_seq to the reg number from device tree Multiple APs are brought up simultaneously and they may get the same seq num in the uclass_resolve_seq() during device_probe(). To avoid this, set req_seq to the reg number in the device tree in advance. Signed-off-by: Bin Meng Acked-by: Simon Glass diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index 3294a50..4334f5b 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -515,5 +515,12 @@ int mp_init(struct mp_params *p) int mp_init_cpu(struct udevice *cpu, void *unused) { + /* + * Multiple APs are brought up simultaneously and they may get the same + * seq num in the uclass_resolve_seq() during device_probe(). To avoid + * this, set req_seq to the reg number in the device tree in advance. + */ + cpu->req_seq = fdtdec_get_int(gd->fdt_blob, cpu->of_offset, "reg", -1); + return device_probe(cpu); } -- cgit v0.10.2 From ecf674b772713837e1d36f9c70ee319d7753a895 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 12 Aug 2015 19:33:07 -0600 Subject: x86: Drop FSP error defines and use EFI instead Now that we have an efi.h header we can use that for FSP error defines. Drop the FSP ones. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/include/asm/fsp/fsp_types.h b/arch/x86/include/asm/fsp/fsp_types.h index f32d827..4fe69f2 100644 --- a/arch/x86/include/asm/fsp/fsp_types.h +++ b/arch/x86/include/asm/fsp/fsp_types.h @@ -68,15 +68,4 @@ struct efi_guid { #define SIGNATURE_64(A, B, C, D, E, F, G, H) \ (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) -/* - * Define FSP API return status code. - * Compatiable with EFI_STATUS defined in PI Spec. - */ -#define FSP_SUCCESS 0 -#define FSP_INVALID_PARAM 0x80000002 -#define FSP_UNSUPPORTED 0x80000003 -#define FSP_DEVICE_ERROR 0x80000007 -#define FSP_NOT_FOUND 0x8000000E -#define FSP_ALREADY_STARTED 0x80000014 - #endif diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index 6f72c6d..d564cb9 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -46,7 +46,7 @@ void board_final_cleanup(void) /* call into FspNotify */ debug("Calling into FSP (notify phase INIT_PHASE_BOOT): "); status = fsp_notify(NULL, INIT_PHASE_BOOT); - if (status != FSP_SUCCESS) + if (status) debug("fail, error code %x\n", status); else debug("OK\n"); -- cgit v0.10.2 From 052e34b363fdd4b20be099c3e1405a30988b3a5a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 12 Aug 2015 20:09:30 -0600 Subject: x86: Return -1 when reading a PCI config register fails This can fail for internal reasons, so return a sensible value rather than a random one. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c index f8da080..d2ec45a 100644 --- a/arch/x86/cpu/pci.c +++ b/arch/x86/cpu/pci.c @@ -76,7 +76,8 @@ unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where) { uint8_t value; - pci_hose_read_config_byte(get_hose(), dev, where, &value); + if (pci_hose_read_config_byte(get_hose(), dev, where, &value)) + return -1U; return value; } @@ -85,7 +86,8 @@ unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where) { uint16_t value; - pci_hose_read_config_word(get_hose(), dev, where, &value); + if (pci_hose_read_config_word(get_hose(), dev, where, &value)) + return -1U; return value; } @@ -94,7 +96,8 @@ unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where) { uint32_t value; - pci_hose_read_config_dword(get_hose(), dev, where, &value); + if (pci_hose_read_config_dword(get_hose(), dev, where, &value)) + return -1U; return value; } -- cgit v0.10.2 From 28a85365f8a3d51a380ee7d4520432edf70985db Mon Sep 17 00:00:00 2001 From: "Stoppa, Igor" Date: Thu, 13 Aug 2015 16:43:35 +0300 Subject: x86: Add clarifications to the x86 README * Explicitly list the targets supported in each section of the instructions from the x86 README. * Drop references to 'raw mode', in favor of 'bare mode'. Signed-off-by: Igor Stoppa Reviewed-by: Bin Meng diff --git a/doc/README.x86 b/doc/README.x86 index af2459c..9012541 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -18,15 +18,16 @@ U-Boot supports running as a coreboot [1] payload on x86. So far only Link work with minimal adjustments on other x86 boards since coreboot deals with most of the low-level details. -U-Boot also supports booting directly from x86 reset vector without coreboot, -aka raw support or bare support. Currently Link, QEMU x86 targets and all -Intel boards support running U-Boot 'bare metal'. +U-Boot also supports booting directly from x86 reset vector, without coreboot. +In this case, known as bare mode, from the fact that it runs on the +'bare metal', U-Boot acts like a BIOS replacement. Currently Link, QEMU x86 +targets and all Intel boards support running U-Boot 'bare metal'. As for loading an OS, U-Boot supports directly booting a 32-bit or 64-bit Linux kernel as part of a FIT image. It also supports a compressed zImage. -Build Instructions ------------------- +Build Instructions for U-Boot as coreboot payload +------------------------------------------------- Building U-Boot as a coreboot payload is just like building U-Boot for targets on other architectures, like below: @@ -48,6 +49,8 @@ Change the 'Board configuration file' and 'Board Device Tree Source (dts) file' to point to a new board. You can also change the Cache-As-RAM (CAR) related settings here if the default values do not fit your new board. +Build Instructions for U-Boot as BIOS replacement (bare mode) +------------------------------------------------------------- Building a ROM version of U-Boot (hereafter referred to as u-boot.rom) is a little bit tricky, as generally it requires several binary blobs which are not shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is @@ -58,7 +61,9 @@ $ export BUILD_ROM=y This tells the Makefile to build u-boot.rom as a target. -Link-specific instructions: +--- + +Chromebook Link specific instructions for bare mode: First, you need the following binary blobs: @@ -87,7 +92,9 @@ Now you can build U-Boot and obtain u-boot.rom: $ make chromebook_link_defconfig $ make all -Intel Crown Bay specific instructions: +--- + +Intel Crown Bay specific instructions for bare mode: U-Boot support of Intel Crown Bay board [4] relies on a binary blob called Firmware Support Package [5] to perform all the necessary initialization steps @@ -122,7 +129,9 @@ Now you can build U-Boot and obtain u-boot.rom $ make crownbay_defconfig $ make all -Intel Minnowboard Max instructions: +--- + +Intel Minnowboard Max instructions for bare mode: This uses as FSP as with Crown Bay, except it is for the Atom E3800 series. Download this and get the .fd file (BAYTRAIL_FSP_GOLD_003_16-SEP-2014.fd at @@ -188,8 +197,9 @@ Offset Description Controlling config Overall ROM image size is controlled by CONFIG_ROM_SIZE. +--- -Intel Galileo instructions: +Intel Galileo instructions for bare mode: Only one binary blob is needed for Remote Management Unit (RMU) within Intel Quark SoC. Not like FSP, U-Boot does not call into the binary. The binary is @@ -252,8 +262,8 @@ At present it seems that for Minnowboard Max, coreboot does not pass through the video information correctly (it always says the resolution is 0x0). This works correctly for link though. -Test with QEMU --------------- +Test with QEMU for bare mode +---------------------------- QEMU is a fancy emulator that can enable us to test U-Boot without access to a real x86 board. Please make sure your QEMU version is 2.3.0 or above test U-Boot. To launch QEMU with u-boot.rom, call QEMU as follows: -- cgit v0.10.2 From ef910819c5a020e96c444d1e73eac917d394456b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 13 Aug 2015 10:36:16 -0600 Subject: x86: minnowmax: Define and enable interrupt setup Set up interrupts correctly so that Linux can use all devices. Use savedefconfig to regenerate the defconfig file. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index d0c0fe6..daac24e 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include /include/ "skeleton.dtsi" /include/ "serial.dtsi" @@ -117,9 +118,71 @@ #address-cells = <3>; #size-cells = <2>; u-boot,dm-pre-reloc; - ranges = <0x02000000 0x0 0xd0000000 0xd0000000 0 0x10000000 - 0x42000000 0x0 0xc0000000 0xc0000000 0 0x10000000 - 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000 + 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + + irq-router@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,irq-router"; + intel,pirq-config = "ibase"; + intel,ibase-offset = <0x50>; + intel,pirq-link = <8 8>; + intel,pirq-mask = <0xdee0>; + intel,pirq-routing = < + /* BayTrail PCI devices */ + PCI_BDF(0, 2, 0) INTA PIRQA + PCI_BDF(0, 3, 0) INTA PIRQA + PCI_BDF(0, 16, 0) INTA PIRQA + PCI_BDF(0, 17, 0) INTA PIRQA + PCI_BDF(0, 18, 0) INTA PIRQA + PCI_BDF(0, 19, 0) INTA PIRQA + PCI_BDF(0, 20, 0) INTA PIRQA + PCI_BDF(0, 21, 0) INTA PIRQA + PCI_BDF(0, 22, 0) INTA PIRQA + PCI_BDF(0, 23, 0) INTA PIRQA + PCI_BDF(0, 24, 0) INTA PIRQA + PCI_BDF(0, 24, 1) INTC PIRQC + PCI_BDF(0, 24, 2) INTD PIRQD + PCI_BDF(0, 24, 3) INTB PIRQB + PCI_BDF(0, 24, 4) INTA PIRQA + PCI_BDF(0, 24, 5) INTC PIRQC + PCI_BDF(0, 24, 6) INTD PIRQD + PCI_BDF(0, 24, 7) INTB PIRQB + PCI_BDF(0, 26, 0) INTA PIRQA + PCI_BDF(0, 27, 0) INTA PIRQA + PCI_BDF(0, 28, 0) INTA PIRQA + PCI_BDF(0, 28, 1) INTB PIRQB + PCI_BDF(0, 28, 2) INTC PIRQC + PCI_BDF(0, 28, 3) INTD PIRQD + PCI_BDF(0, 29, 0) INTA PIRQA + PCI_BDF(0, 30, 0) INTA PIRQA + PCI_BDF(0, 30, 1) INTD PIRQD + PCI_BDF(0, 30, 2) INTB PIRQB + PCI_BDF(0, 30, 3) INTC PIRQC + PCI_BDF(0, 30, 4) INTD PIRQD + PCI_BDF(0, 30, 5) INTB PIRQB + PCI_BDF(0, 31, 3) INTB PIRQB + + /* PCIe root ports downstream interrupts */ + PCI_BDF(1, 0, 0) INTA PIRQA + PCI_BDF(1, 0, 0) INTB PIRQB + PCI_BDF(1, 0, 0) INTC PIRQC + PCI_BDF(1, 0, 0) INTD PIRQD + PCI_BDF(2, 0, 0) INTA PIRQB + PCI_BDF(2, 0, 0) INTB PIRQC + PCI_BDF(2, 0, 0) INTC PIRQD + PCI_BDF(2, 0, 0) INTD PIRQA + PCI_BDF(3, 0, 0) INTA PIRQC + PCI_BDF(3, 0, 0) INTB PIRQD + PCI_BDF(3, 0, 0) INTC PIRQA + PCI_BDF(3, 0, 0) INTD PIRQB + PCI_BDF(4, 0, 0) INTA PIRQD + PCI_BDF(4, 0, 0) INTB PIRQA + PCI_BDF(4, 0, 0) INTC PIRQB + PCI_BDF(4, 0, 0) INTD PIRQC + >; + }; }; fsp { diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 578fcce..f3cf91b 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -5,7 +5,8 @@ CONFIG_TARGET_MINNOWMAX=y CONFIG_HAVE_INTEL_ME=y CONFIG_SMP=y CONFIG_HAVE_VGA_BIOS=y -CONFIG_GENERATE_SFI_TABLE=y +CONFIG_GENERATE_PIRQ_TABLE=y +CONFIG_GENERATE_MP_TABLE=y CONFIG_CMD_CPU=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 64fa676..aeb04b9 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -15,6 +15,7 @@ #define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_ARCH_EARLY_INIT_R +#define CONFIG_ARCH_MISC_INIT #define CONFIG_SMSC_LPC47M -- cgit v0.10.2 From 590870e7e8919bca7adfd97069ac5b2a924b3151 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 13 Aug 2015 10:36:17 -0600 Subject: x86: Add a simple interrupt script to the README It is a bit tedious to figure out the interrupt configuration for a new x86 platform. Add a script which can do this, based on the output of 'pci long'. This may be helpful in some cases. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng diff --git a/doc/README.x86 b/doc/README.x86 index 9012541..e7dc090 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -718,6 +718,21 @@ allocation and assignment will be done by U-Boot automatically. Now you can enable CONFIG_GENERATE_PIRQ_TABLE for testing Linux kernel using i8259 PIC and CONFIG_GENERATE_MP_TABLE for testing Linux kernel using local APIC and I/O APIC. +This script might be useful. If you feed it the output of 'pci long' from +U-Boot then it will generate a device tree fragment with the interrupt +configuration for each device (note it needs gawk 4.0.0): + + $ cat console_output |awk '/PCI/ {device=$4} /interrupt line/ {line=$4} \ + /interrupt pin/ {pin = $4; if (pin != "0x00" && pin != "0xff") \ + {patsplit(device, bdf, "[0-9a-f]+"); \ + printf "PCI_BDF(%d, %d, %d) INT%c PIRQ%c\n", strtonum("0x" bdf[1]), \ + strtonum("0x" bdf[2]), bdf[3], strtonum(pin) + 64, 64 + strtonum(pin)}}' + +Example output: + PCI_BDF(0, 2, 0) INTA PIRQA + PCI_BDF(0, 3, 0) INTA PIRQA +... + TODO List --------- - Audio -- cgit v0.10.2 From 236efe36be6d1c544f9477f10fdf38a17cd7a869 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 2 Aug 2015 18:13:50 -0600 Subject: Revert "fdt: Fix fdtdec_get_addr_size() for 64-bit" This reverts commit 5b34436035fc862b5e8d0d2c3eab74ba36f1a7f4. This function has a few problems. It calls fdt_parent_offset() which as mentioned in code review is very slow. https://patchwork.ozlabs.org/patch/499482/ https://patchwork.ozlabs.org/patch/452604/ It also happens to break SPI flash on Minnowboard max which is how I noticed that this was applied. I can send a patch to tidy that up, but in any case I think we should consider a revert until the function is better implemented. Signed-off-by: Simon Glass diff --git a/lib/fdtdec.c b/lib/fdtdec.c index cdfc844..d21fb74 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -90,45 +90,29 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id) fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, const char *prop_name, fdt_size_t *sizep) { - const fdt32_t *ptr, *end; - int parent, na, ns, len; - fdt_addr_t addr; + const fdt_addr_t *cell; + int len; debug("%s: %s: ", __func__, prop_name); - - parent = fdt_parent_offset(blob, node); - if (parent < 0) { - debug("(no parent found)\n"); - return FDT_ADDR_T_NONE; - } - - na = fdt_address_cells(blob, parent); - ns = fdt_size_cells(blob, parent); - - ptr = fdt_getprop(blob, node, prop_name, &len); - if (!ptr) { - debug("(not found)\n"); - return FDT_ADDR_T_NONE; - } - - end = ptr + len / sizeof(*ptr); - - if (ptr + na + ns > end) { - debug("(not enough data: expected %d bytes, got %d bytes)\n", - (na + ns) * 4, len); - return FDT_ADDR_T_NONE; - } - - addr = fdtdec_get_number(ptr, na); - - if (sizep) { - *sizep = fdtdec_get_number(ptr + na, ns); - debug("addr=%pa, size=%pa\n", &addr, sizep); - } else { - debug("%pa\n", &addr); + cell = fdt_getprop(blob, node, prop_name, &len); + if (cell && ((!sizep && len == sizeof(fdt_addr_t)) || + len == sizeof(fdt_addr_t) * 2)) { + fdt_addr_t addr = fdt_addr_to_cpu(*cell); + if (sizep) { + const fdt_size_t *size; + + size = (fdt_size_t *)((char *)cell + + sizeof(fdt_addr_t)); + *sizep = fdt_size_to_cpu(*size); + debug("addr=%08lx, size=%llx\n", + (ulong)addr, (u64)*sizep); + } else { + debug("%08lx\n", (ulong)addr); + } + return addr; } - - return addr; + debug("(not found)\n"); + return FDT_ADDR_T_NONE; } fdt_addr_t fdtdec_get_addr(const void *blob, int node, -- cgit v0.10.2