diff options
428 files changed, 14215 insertions, 950 deletions
@@ -545,9 +545,14 @@ config SYS_EXTRA_OPTIONS configuration to Kconfig. Since this option will be removed sometime, new boards should not use this option. -config SYS_TEXT_BASE +config HAVE_SYS_TEXT_BASE + bool depends on !NIOS2 && !XTENSA depends on !EFI_APP + default y + +config SYS_TEXT_BASE + depends on HAVE_SYS_TEXT_BASE default 0x80800000 if ARCH_OMAP2PLUS || ARCH_K3 default 0x4a000000 if ARCH_SUNXI && !MACH_SUN9I && !MACH_SUN8I_V3S default 0x2a000000 if ARCH_SUNXI && MACH_SUN9I @@ -556,8 +561,6 @@ config SYS_TEXT_BASE help The address in memory that U-Boot will be running from, initially. - - config SYS_CLK_FREQ depends on ARC || ARCH_SUNXI || MPC83xx int "CPU clock frequency" diff --git a/arch/Kconfig b/arch/Kconfig index 141e48bc43..ae9c93ed7b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -133,6 +133,9 @@ config SANDBOX imply PHYLIB imply DM_MDIO imply DM_MDIO_MUX + imply ACPI_PMC + imply ACPI_PMC_SANDBOX + imply CMD_PMC config SH bool "SuperH architecture" @@ -183,12 +186,14 @@ config X86 imply USB_HOST_ETHER imply PCH imply RTC_MC146818 + imply IRQ # Thing to enable for when SPL/TPL are enabled: SPL imply SPL_DM imply SPL_OF_LIBFDT imply SPL_DRIVERS_MISC_SUPPORT imply SPL_GPIO_SUPPORT + imply SPL_PINCTRL imply SPL_LIBCOMMON_SUPPORT imply SPL_LIBGENERIC_SUPPORT imply SPL_SERIAL_SUPPORT @@ -200,14 +205,12 @@ config X86 imply SPL_SYSCON # TPL imply TPL_DM - imply TPL_OF_LIBFDT imply TPL_DRIVERS_MISC_SUPPORT imply TPL_GPIO_SUPPORT + imply TPL_PINCTRL imply TPL_LIBCOMMON_SUPPORT imply TPL_LIBGENERIC_SUPPORT imply TPL_SERIAL_SUPPORT - imply TPL_SPI_FLASH_SUPPORT - imply TPL_SPI_SUPPORT imply TPL_OF_CONTROL imply TPL_TIMER imply TPL_REGMAP diff --git a/arch/arm/cpu/armv7/ls102xa/Kconfig b/arch/arm/cpu/armv7/ls102xa/Kconfig index b9511da3f3..57d7fd9e55 100644 --- a/arch/arm/cpu/armv7/ls102xa/Kconfig +++ b/arch/arm/cpu/armv7/ls102xa/Kconfig @@ -27,14 +27,6 @@ config ARCH_LS1021A menu "LS102xA architecture" depends on ARCH_LS1021A -config FSL_PCIE_COMPAT - string "PCIe compatible of Kernel DT" - depends on PCIE_LAYERSCAPE - default "fsl,ls1021a-pcie" if ARCH_LS1021A - help - This compatible is used to find pci controller node in Kernel DT - to complete fixup. - config LS1_DEEP_SLEEP bool "Deep sleep" depends on ARCH_LS1021A diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index f1578b10bc..ed478ddd48 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -219,6 +219,7 @@ config ARCH_LX2160A select SYS_FSL_DDR_VER_50 select SYS_FSL_EC1 select SYS_FSL_EC2 + select SYS_FSL_ERRATUM_A050106 select SYS_FSL_HAS_RGMII select SYS_FSL_HAS_SEC select SYS_FSL_HAS_CCN508 @@ -252,20 +253,6 @@ menu "Layerscape architecture" config FSL_LAYERSCAPE bool -config FSL_PCIE_COMPAT - string "PCIe compatible of Kernel DT" - depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4 - default "fsl,ls1012a-pcie" if ARCH_LS1012A - default "fsl,ls1028a-pcie" if ARCH_LS1028A - default "fsl,ls1043a-pcie" if ARCH_LS1043A - default "fsl,ls1046a-pcie" if ARCH_LS1046A - default "fsl,ls2080a-pcie" if ARCH_LS2080A - default "fsl,ls1088a-pcie" if ARCH_LS1088A - default "fsl,lx2160a-pcie" if ARCH_LX2160A - help - This compatible is used to find pci controller node in Kernel DT - to complete fixup. - config HAS_FEATURE_GIC64K_ALIGN bool default y if ARCH_LS1043A @@ -348,6 +335,14 @@ config SYS_FSL_ERRATUM_A009008 config SYS_FSL_ERRATUM_A009798 bool "Workaround for USB PHY erratum A009798" +config SYS_FSL_ERRATUM_A050106 + bool "Workaround for USB PHY erratum A050106" + help + USB3.0 Receiver needs to enable fixed equalization + for each of PHY instances in an SOC. This is similar + to erratum A-009007, but this one is for LX2160A, + and the register value is different. + config SYS_FSL_ERRATUM_A010315 bool "Workaround for PCIe erratum A010315" @@ -388,6 +383,15 @@ config QSPI_AHB_INIT But some QSPI flash size up to 64MBytes, so initialize the QSPI AHB bus for those flashes to support the full QSPI flash size. +config FSPI_AHB_EN_4BYTE + bool "Enable 4-byte Fast Read command for AHB mode" + default n + help + The default setting for FlexSPI AHB bus just supports 3-byte addressing. + But some FlexSPI flash sizes are up to 64MBytes. + This flag enables fast read command for AHB mode and modifies required + LUT to support full FlexSPI flash. + config SYS_CCI400_OFFSET hex "Offset for CCI400 base" depends on SYS_FSL_HAS_CCI400 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 6c87c1b11a..639f531649 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -1101,6 +1101,12 @@ static void config_core_prefetch(void) } } +#ifdef CONFIG_PCIE_ECAM_GENERIC +__weak void set_ecam_icids(void) +{ +} +#endif + int arch_early_init_r(void) { #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 @@ -1153,6 +1159,9 @@ int arch_early_init_r(void) #ifdef CONFIG_SYS_DPAA_QBMAN setup_qbman_portals(); #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC + set_ecam_icids(); +#endif return 0; } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index e993209593..1e7e46e88a 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -421,6 +421,12 @@ static void fdt_disable_multimedia(void *blob, unsigned int svr) } #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC +__weak void fdt_fixup_ecam(void *blob) +{ +} +#endif + void ft_cpu_setup(void *blob, bd_t *bd) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); @@ -485,4 +491,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) #ifdef CONFIG_ARCH_LS1028A fdt_disable_multimedia(blob, svr); #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC + fdt_fixup_ecam(blob); +#endif } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c index 9462298fbf..8110412da6 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c @@ -33,3 +33,96 @@ struct icid_id_table icid_tbl[] = { }; int icid_tbl_sz = ARRAY_SIZE(icid_tbl); + +/* integrated PCI is handled separately as it's not part of CCSR/SCFG */ +#ifdef CONFIG_PCIE_ECAM_GENERIC + +#define ECAM_IERB_BASE 0x1f0800000ULL +#define ECAM_IERB_OFFSET_NA -1 +#define ECAM_IERB_FUNC_CNT ARRAY_SIZE(ierb_offset) +/* cache related transaction attributes for PCIe functions */ +#define ECAM_IERB_MSICAR (ECAM_IERB_BASE + 0xa400) +#define ECAM_IERB_MSICAR_VALUE 0x30 + +/* offset of IERB config register per PCI function */ +static int ierb_offset[] = { + 0x0800, + 0x1800, + 0x2800, + 0x3800, + 0x4800, + 0x5800, + 0x6800, + ECAM_IERB_OFFSET_NA, + 0x0804, + 0x0808, + 0x1804, + 0x1808, +}; + +/* + * Use a custom function for LS1028A, for now this is the only SoC with IERB + * and we're currently considering reorganizing IERB for future SoCs. + */ +void set_ecam_icids(void) +{ + int i; + + out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE); + + for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) { + if (ierb_offset[i] == ECAM_IERB_OFFSET_NA) + continue; + + out_le32(ECAM_IERB_BASE + ierb_offset[i], + FSL_ECAM_STREAM_ID_START + i); + } +} + +static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset, + const char *name, uint32_t idx, u32 val) +{ + val = cpu_to_be32(val); + return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, + strlen(name), + idx * sizeof(val), &val, + sizeof(val)); +} + +static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name) +{ + int len; + + if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len)) + return len; + + return 0; +} + +void fdt_fixup_ecam(void *blob) +{ + int off; + + off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic"); + if (off < 0) { + debug("ECAM node not found\n"); + return; + } + + if (fdt_getprop_len(blob, off, "msi-map") != 16 || + fdt_getprop_len(blob, off, "iommu-map") != 16) { + log_err("invalid msi/iommu-map propertly size in ECAM node\n"); + return; + } + + fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2, + FSL_ECAM_STREAM_ID_START); + fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3, + ECAM_IERB_FUNC_CNT); + + fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2, + FSL_ECAM_STREAM_ID_START); + fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3, + ECAM_IERB_FUNC_CNT); +} +#endif /* CONFIG_PCIE_ECAM_GENERIC */ diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 70933a2e03..578f8d12de 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -147,7 +147,7 @@ static void erratum_a008997(void) out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4) #elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \ - defined(CONFIG_ARCH_LS1028A) + defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LX2160A) #define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy) \ out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \ @@ -181,6 +181,15 @@ static void erratum_a009007(void) } #if defined(CONFIG_FSL_LSCH3) +static void erratum_a050106(void) +{ +#if defined(CONFIG_ARCH_LX2160A) + void __iomem *dcsr = (void __iomem *)DCSR_BASE; + + PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1); + PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY2); +#endif +} /* * This erratum requires setting a value to eddrtqcr1 to * optimal the DDR performance. @@ -332,6 +341,7 @@ void fsl_lsch3_early_init_f(void) erratum_a009798(); erratum_a008997(); erratum_a009007(); + erratum_a050106(); #ifdef CONFIG_CHAIN_OF_TRUST /* In case of Secure Boot, the IBR configures the SMMU * to allow only Secure transactions. @@ -676,6 +686,47 @@ void fsl_lsch2_early_init_f(void) } #endif +#ifdef CONFIG_FSPI_AHB_EN_4BYTE +int fspi_ahb_init(void) +{ + /* Enable 4bytes address support and fast read */ + u32 *fspi_lut, lut_key, *fspi_key; + + fspi_key = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUTKEY_BASE_ADDR; + fspi_lut = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUT_BASE_ADDR; + + lut_key = in_be32(fspi_key); + + if (lut_key == SYS_NXP_FSPI_LUTKEY) { + /* That means the register is BE */ + out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY); + /* Unlock the lut table */ + out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK); + /* Create READ LUT */ + out_be32(fspi_lut, 0x0820040c); + out_be32(fspi_lut + 1, 0x24003008); + out_be32(fspi_lut + 2, 0x00000000); + /* Lock the lut table */ + out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY); + out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK); + } else { + /* That means the register is LE */ + out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY); + /* Unlock the lut table */ + out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK); + /* Create READ LUT */ + out_le32(fspi_lut, 0x0820040c); + out_le32(fspi_lut + 1, 0x24003008); + out_le32(fspi_lut + 2, 0x00000000); + /* Lock the lut table */ + out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY); + out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK); + } + + return 0; +} +#endif + #ifdef CONFIG_QSPI_AHB_INIT /* Enable 4bytes address support and fast read */ int qspi_ahb_init(void) @@ -868,6 +919,9 @@ int board_late_init(void) #ifdef CONFIG_QSPI_AHB_INIT qspi_ahb_init(); #endif +#ifdef CONFIG_FSPI_AHB_EN_4BYTE + fspi_ahb_init(); +#endif return fsl_board_late_init(); } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index 58a39e1123..ed3a605663 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -129,7 +129,7 @@ int spl_start_uboot(void) } #endif /* CONFIG_SPL_OS_BOOT */ #ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) +__weak int board_fit_config_name_match(const char *name) { /* Just empty function now - can't decide what to choose */ debug("%s: %s\n", __func__, name); diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi index a189333e40..9d018cad1c 100644 --- a/arch/arm/dts/fsl-lx2160a.dtsi +++ b/arch/arm/dts/fsl-lx2160a.dtsi @@ -127,12 +127,14 @@ compatible = "arm,pl011"; reg = <0x0 0x21c0000 0x0 0x1000>; clocks = <&clockgen 4 0>; + status = "disabled"; }; uart1: serial@21d0000 { compatible = "arm,pl011"; reg = <0x0 0x21d0000 0x0 0x1000>; clocks = <&clockgen 4 0>; + status = "disabled"; }; uart2: serial@21e0000 { diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h index d46477d96e..299201b157 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h @@ -23,7 +23,13 @@ #define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR (CONFIG_SYS_IMMR + 0x00300000) #define CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR (CONFIG_SYS_IMMR + 0x00310000) #define CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR (CONFIG_SYS_IMMR + 0x00370000) +#ifndef CONFIG_NXP_LSCH3_2 #define SYS_FSL_QSPI_ADDR (CONFIG_SYS_IMMR + 0x010c0000) +#else +#define SYS_NXP_FSPI_ADDR (CONFIG_SYS_IMMR + 0x010c0000) +#define SYS_NXP_FSPI_LUTKEY_BASE_ADDR 0x18 +#define SYS_NXP_FSPI_LUT_BASE_ADDR 0x200 +#endif #define CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x01140000) #define FSL_ESDHC1_BASE_ADDR CONFIG_SYS_FSL_ESDHC_ADDR #define FSL_ESDHC2_BASE_ADDR (CONFIG_SYS_IMMR + 0x01150000) @@ -252,8 +258,14 @@ #define DCSR_USB_PHY_RX_OVRD_IN_HI 0x200C #define USB_PHY_RX_EQ_VAL_1 0x0000 #define USB_PHY_RX_EQ_VAL_2 0x0080 +#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \ + defined(CONFIG_ARCH_LS1028A) #define USB_PHY_RX_EQ_VAL_3 0x0380 #define USB_PHY_RX_EQ_VAL_4 0x0b80 +#elif defined(CONFIG_ARCH_LX2160A) +#define USB_PHY_RX_EQ_VAL_3 0x0080 +#define USB_PHY_RX_EQ_VAL_4 0x0880 +#endif #define DCSR_USB_IOCR1 0x108004 #define DCSR_USB_PCSTXSWINGFULL 0x71 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h index 35719d747b..c62d414aac 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h @@ -140,6 +140,13 @@ void init_pfe_scfg_dcfg_regs(void); int qspi_ahb_init(void); #endif +#ifdef CONFIG_FSPI_AHB_EN_4BYTE +#define SYS_NXP_FSPI_LUTCR_LOCK 0x00000001 +#define SYS_NXP_FSPI_LUTCR_UNLOCK 0x00000002 +#define SYS_NXP_FSPI_LUTKEY 0x5AF05AF0 +int fspi_ahb_init(void); +#endif + void cpu_name(char *name); #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 void erratum_a009635(void); diff --git a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h index 94ea99a349..4c54e3d3d5 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright 2015-2018 NXP + * Copyright 2015-2019 NXP * Copyright 2014 Freescale Semiconductor, Inc. * */ @@ -42,6 +42,10 @@ * -the MC is responsible for allocating and setting up 'isolation context * IDs (ICIDs) based on the allocated stream IDs for all DPAA2 devices. * + * - ECAM (integrated PCI) + * - U-Boot applies the value here to HW and does DT fix-up for both + * 'iommu-map' and 'msi-map' + * * On Chasis-3 SoCs stream IDs are programmed in AMQ registers (32-bits) for * each of the different bus masters. The relationship between * the AMQ registers and stream IDs is defined in the table below: @@ -83,14 +87,12 @@ /* PCI - programmed in PEXn_LUT */ #define FSL_PEX_STREAM_ID_START 7 -#ifdef CONFIG_ARCH_LX2160A -#define FSL_PEX_STREAM_ID_NUM (0x100) -#endif - #if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1028A) #define FSL_PEX_STREAM_ID_END 22 #elif defined(CONFIG_ARCH_LS1088A) #define FSL_PEX_STREAM_ID_END 18 +#elif defined(CONFIG_ARCH_LX2160A) +#define FSL_PEX_STREAM_ID_END (0x100) #endif @@ -98,6 +100,10 @@ #define FSL_DPAA2_STREAM_ID_START 23 #define FSL_DPAA2_STREAM_ID_END 63 +/* PCI IEPs, this overlaps DPAA2 but these two are exclusive at least for now */ +#define FSL_ECAM_STREAM_ID_START 32 +#define FSL_ECAM_STREAM_ID_END 63 + #define FSL_SEC_STREAM_ID 64 #define FSL_SEC_JR1_STREAM_ID 65 #define FSL_SEC_JR2_STREAM_ID 66 diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h index 20268fa084..151afa8f44 100644 --- a/arch/arm/include/asm/omap_gpio.h +++ b/arch/arm/include/asm/omap_gpio.h @@ -22,7 +22,7 @@ #include <asm/arch/cpu.h> -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* Information about a GPIO bank */ struct omap_gpio_platdata { diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 91faf729ae..2daeb4fef8 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -133,7 +133,7 @@ /* * Other misc defines */ -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */ #define ATMEL_BASE_PIO ATMEL_BASE_PIOA #endif diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index c150240962..e5a4053414 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -18,7 +18,7 @@ #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) #define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8) -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define gpio_status() gpio_info() #endif #define GPIO_NAME_SIZE 20 diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c index 03460c3eb7..e64942b716 100644 --- a/arch/arm/mach-omap2/am33xx/board.c +++ b/arch/arm/mach-omap2/am33xx/board.c @@ -116,7 +116,7 @@ U_BOOT_DEVICES(am33xx_i2c) = { }; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) static const struct omap_gpio_platdata am33xx_gpio[] = { { 0, AM33XX_GPIO0_BASE }, { 1, AM33XX_GPIO1_BASE }, @@ -141,7 +141,7 @@ U_BOOT_DEVICES(am33xx_gpios) = { #endif #endif -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static const struct gpio_bank gpio_bank_am33xx[] = { { (void *)AM33XX_GPIO0_BASE }, { (void *)AM33XX_GPIO1_BASE }, diff --git a/arch/arm/mach-omap2/omap3/board.c b/arch/arm/mach-omap2/omap3/board.c index 658ef8c1f1..60de0d6052 100644 --- a/arch/arm/mach-omap2/omap3/board.c +++ b/arch/arm/mach-omap2/omap3/board.c @@ -33,7 +33,7 @@ extern omap3_sysinfo sysinfo; static void omap3_invalidate_l2_cache_secure(void); #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #if !CONFIG_IS_ENABLED(OF_CONTROL) /* Manually initialize GPIO banks when OF_CONTROL doesn't */ static const struct omap_gpio_platdata omap34xx_gpio[] = { diff --git a/arch/arm/mach-omap2/omap5/hwinit.c b/arch/arm/mach-omap2/omap5/hwinit.c index eba21647d9..56458ce495 100644 --- a/arch/arm/mach-omap2/omap5/hwinit.c +++ b/arch/arm/mach-omap2/omap5/hwinit.c @@ -25,7 +25,7 @@ u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV; -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static struct gpio_bank gpio_bank_54xx[8] = { { (void *)OMAP54XX_GPIO1_BASE }, { (void *)OMAP54XX_GPIO2_BASE }, diff --git a/arch/powerpc/dts/p1020-post.dtsi b/arch/powerpc/dts/p1020-post.dtsi index fb3b203a24..1c77702f01 100644 --- a/arch/powerpc/dts/p1020-post.dtsi +++ b/arch/powerpc/dts/p1020-post.dtsi @@ -13,6 +13,18 @@ compatible = "fsl,p1020-immr", "simple-bus"; bus-frequency = <0x0>; + usb@22000 { + compatible = "fsl-usb2-dr"; + reg = <0x22000 0x1000>; + phy_type = "ulpi"; + }; + + usb@23000 { + compatible = "fsl-usb2-dr"; + reg = <0x23000 0x1000>; + phy_type = "ulpi"; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; @@ -31,6 +43,7 @@ /* Filled in by U-Boot */ clock-frequency = <0>; }; + }; /* PCIe controller base address 0x9000 */ diff --git a/arch/powerpc/dts/p2020-post.dtsi b/arch/powerpc/dts/p2020-post.dtsi index c07ed66726..5bbd5c5468 100644 --- a/arch/powerpc/dts/p2020-post.dtsi +++ b/arch/powerpc/dts/p2020-post.dtsi @@ -13,6 +13,12 @@ compatible = "fsl,p2020-immr", "simple-bus"; bus-frequency = <0x0>; + usb@22000 { + compatible = "fsl-usb2-dr"; + reg = <0x22000 0x1000>; + phy_type = "ulpi"; + }; + mpic: pic@40000 { interrupt-controller; #address-cells = <0>; diff --git a/arch/powerpc/dts/p2041.dtsi b/arch/powerpc/dts/p2041.dtsi index 223052ac1c..0f5e7dbdc8 100644 --- a/arch/powerpc/dts/p2041.dtsi +++ b/arch/powerpc/dts/p2041.dtsi @@ -60,6 +60,18 @@ clock-frequency = <0x0>; }; + usb0: usb@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb1: usb@211000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/powerpc/dts/p3041.dtsi b/arch/powerpc/dts/p3041.dtsi index e873db2a36..6736d00035 100644 --- a/arch/powerpc/dts/p3041.dtsi +++ b/arch/powerpc/dts/p3041.dtsi @@ -60,6 +60,18 @@ clock-frequency = <0x0>; }; + usb0: usb@fe210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb1: usb@fe211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/powerpc/dts/p4080.dtsi b/arch/powerpc/dts/p4080.dtsi index 08ac26df67..02f39fbfcb 100644 --- a/arch/powerpc/dts/p4080.dtsi +++ b/arch/powerpc/dts/p4080.dtsi @@ -85,6 +85,18 @@ reg = <0x114000 0x1000>; clock-frequency = <0>; }; + + usb0@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "ulpi"; + }; + + usb1@211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "ulpi"; + }; }; pcie@ffe200000 { diff --git a/arch/powerpc/dts/p5040.dtsi b/arch/powerpc/dts/p5040.dtsi index 71019245f0..67a62a7725 100644 --- a/arch/powerpc/dts/p5040.dtsi +++ b/arch/powerpc/dts/p5040.dtsi @@ -59,6 +59,18 @@ clock-frequency = <0x0>; }; + usb@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb@211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/powerpc/dts/t102x.dtsi b/arch/powerpc/dts/t102x.dtsi index 0bc1d809a4..a6b821a76a 100644 --- a/arch/powerpc/dts/t102x.dtsi +++ b/arch/powerpc/dts/t102x.dtsi @@ -49,6 +49,18 @@ clock-frequency = <0x0>; }; + usb0@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb1@211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/powerpc/dts/t104x.dtsi b/arch/powerpc/dts/t104x.dtsi index 0828f73b93..093aaab834 100644 --- a/arch/powerpc/dts/t104x.dtsi +++ b/arch/powerpc/dts/t104x.dtsi @@ -59,6 +59,18 @@ clock-frequency = <0x0>; }; + usb0@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb1@211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/powerpc/dts/t4240.dtsi b/arch/powerpc/dts/t4240.dtsi index 5170083b5b..43f98cd9e1 100644 --- a/arch/powerpc/dts/t4240.dtsi +++ b/arch/powerpc/dts/t4240.dtsi @@ -99,6 +99,18 @@ clock-frequency = <0x0>; }; + usb@210000 { + compatible = "fsl-usb2-mph"; + reg = <0x210000 0x1000>; + phy_type = "utmi"; + }; + + usb@211000 { + compatible = "fsl-usb2-dr"; + reg = <0x211000 0x1000>; + phy_type = "utmi"; + }; + sata: sata@220000 { compatible = "fsl,pq-sata-v2"; reg = <0x220000 0x1000>; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index dee5fde4f7..cd46e000f5 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -356,6 +356,7 @@ void state_reset_for_test(struct sandbox_state *state) /* No reset yet, so mark it as such. Always allow power reset */ state->last_sysreset = SYSRESET_COUNT; state->sysreset_allowed[SYSRESET_POWER_OFF] = true; + state->allow_memio = false; memset(&state->wdt, '\0', sizeof(state->wdt)); memset(state->spi, '\0', sizeof(state->spi)); diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index f1637c80f6..4dd82f6a32 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -6,6 +6,7 @@ #address-cells = <1>; #size-cells = <1>; model = "sandbox"; + compatible = "sandbox"; aliases { i2c0 = &i2c_0; diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index f09bc70b0d..7bf144f532 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -100,6 +100,17 @@ }; pci-controller { + pci@1e,0 { + compatible = "sandbox,pmc"; + reg = <0xf000 0 0 0 0>; + sandbox,emul = <&pmc_emul>; + gpe0-dwx-mask = <0xf>; + gpe0-dwx-shift-base = <4>; + gpe0-dw = <6 7 9>; + gpe0-sts = <0x20>; + gpe0-en = <0x30>; + }; + pci@1f,0 { compatible = "pci-generic"; reg = <0xf800 0 0 0 0>; @@ -109,6 +120,9 @@ emul { compatible = "sandbox,pci-emul-parent"; + pmc_emul: emul@1e,0 { + compatible = "sandbox,pmc-emul"; + }; swap_case_emul: emul@1f,0 { compatible = "sandbox,swap-case"; }; diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts index 37a5539ff4..5c95cee9d7 100644 --- a/arch/sandbox/dts/sandbox64.dts +++ b/arch/sandbox/dts/sandbox64.dts @@ -6,6 +6,7 @@ #address-cells = <2>; #size-cells = <2>; model = "sandbox"; + compatible = "sandbox"; aliases { i2c0 = &i2c_0; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index fdb08f2111..57513a449f 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -353,6 +353,10 @@ vss-microvolts = <0>; }; + irq { + compatible = "sandbox,irq"; + }; + lcd { u-boot,dm-pre-reloc; compatible = "sandbox,lcd-sdl"; @@ -471,6 +475,27 @@ 0x01000810 0 0 0 0>; sandbox,emul = <&swap_case_emul0_1>; }; + p2sb-pci@2,0 { + compatible = "sandbox,p2sb"; + reg = <0x02001010 0 0 0 0>; + sandbox,emul = <&p2sb_emul>; + + adder { + intel,p2sb-port-id = <3>; + compatible = "sandbox,adder"; + }; + }; + pci@1e,0 { + compatible = "sandbox,pmc"; + reg = <0xf000 0 0 0 0>; + sandbox,emul = <&pmc_emul1e>; + acpi-base = <0x400>; + gpe0-dwx-mask = <0xf>; + gpe0-dwx-shift-base = <4>; + gpe0-dw = <6 7 9>; + gpe0-sts = <0x20>; + gpe0-en = <0x30>; + }; pci@1f,0 { compatible = "pci-generic"; /* reg 0 is at 0x10, using FDT_PCI_SPACE_IO */ @@ -491,6 +516,12 @@ swap_case_emul0_1f: emul0@1f,0 { compatible = "sandbox,swap-case"; }; + p2sb_emul: emul@2,0 { + compatible = "sandbox,p2sb-emul"; + }; + pmc_emul1e: emul@1e,0 { + compatible = "sandbox,pmc-emul"; + }; }; pci1: pci-controller1 { diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index b885e1a14f..2421922c9e 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -13,6 +13,8 @@ #define SANDBOX_PCI_VENDOR_ID 0x1234 #define SANDBOX_PCI_SWAP_CASE_EMUL_ID 0x5678 +#define SANDBOX_PCI_PMC_EMUL_ID 0x5677 +#define SANDBOX_PCI_P2SB_EMUL_ID 0x5676 #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL @@ -72,6 +74,13 @@ void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev, void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len); +void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev, + uint mask); + +uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev); + +uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev); + /** * sandbox_i2c_rtc_set_offset() - set the time offset from system/base time * diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 17a6fe6d3d..89b93e5de2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -106,6 +106,7 @@ source "board/google/Kconfig" source "board/intel/Kconfig" # platform-specific options below +source "arch/x86/cpu/apollolake/Kconfig" source "arch/x86/cpu/baytrail/Kconfig" source "arch/x86/cpu/braswell/Kconfig" source "arch/x86/cpu/broadwell/Kconfig" @@ -217,6 +218,14 @@ config SYS_X86_START16 depends on X86_RESET_VECTOR default 0xfffff800 +config HAVE_X86_FIT + bool + help + Enable inclusion of an Intel Firmware Interface Table (FIT) into the + image. This table is supposed to point to microcode and the like. So + far it is just a fixed table with the minimum set of headers, so that + it is actually present. + config X86_LOAD_FROM_32_BIT bool "Boot from a 32-bit program" help @@ -326,7 +335,7 @@ config X86_RAMTEST config FLASH_DESCRIPTOR_FILE string "Flash descriptor binary filename" - depends on HAVE_INTEL_ME + depends on HAVE_INTEL_ME || FSP_VERSION2 default "descriptor.bin" help The filename of the file to use as flash descriptor in the @@ -411,6 +420,54 @@ config FSP_ADDR The default base address of 0xfffc0000 indicates that the binary must be located at offset 0xc0000 from the beginning of a 1MB flash device. +if FSP_VERSION2 + +config FSP_FILE_T + string "Firmware Support Package binary filename (Temp RAM)" + default "fsp_t.bin" + help + The filename of the file to use for the temporary-RAM init phase from + the Firmware Support Package binary. Put this in the board directory. + It is used to set up an initial area of RAM which can be used for the + stack and other purposes, while bringing up the main system DRAM. + +config FSP_ADDR_T + hex "Firmware Support Package binary location (Temp RAM)" + default 0xffff8000 + help + FSP is not Position-Independent Code (PIC) and FSP components have to + be rebased if placed at a location which is different from the + perferred base address specified during the FSP build. Use Intel's + Binary Configuration Tool (BCT) to do the rebase. + +config FSP_FILE_M + string "Firmware Support Package binary filename (Memory Init)" + default "fsp_m.bin" + help + The filename of the file to use for the RAM init phase from the + Firmware Support Package binary. Put this in the board directory. + It is used to set up the main system DRAM and runs in SPL, once + temporary RAM (CAR) is working. + +config FSP_FILE_S + string "Firmware Support Package binary filename (Silicon Init)" + default "fsp_s.bin" + help + The filename of the file to use for the Silicon init phase from the + Firmware Support Package binary. Put this in the board directory. + It is used to set up the silicon to work correctly and must be + executed after DRAM is running. + +config IFWI_INPUT_FILE + string "Filename containing FIT (Firmware Interface Table) with IFWI" + default "fitimage.bin" + help + The IFWI is obtained by running a tool on this file to extract the + IFWI. Put this in the board directory. The IFWI contains U-Boot TPL, + microcode and other internal items. + +endif + config FSP_TEMP_RAM_ADDR hex depends on FSP_VERSION1 @@ -532,6 +589,10 @@ config HAVE_REFCODE broadwell) U-Boot will be missing some critical setup steps. Various peripherals may fail to work. +config HAVE_MICROCODE + bool + default y if !FSP_VERSION2 + config SMP bool "Enable Symmetric Multiprocessing" default n @@ -595,7 +656,7 @@ config VGA_BIOS_ADDR config HAVE_VBT bool "Add a Video BIOS Table (VBT) image" - depends on FSP_VERSION1 + depends on HAVE_FSP help Select this option if you have a Video BIOS Table (VBT) image that you would like to add to your ROM. This is normally required if you @@ -823,4 +884,30 @@ config HIGH_TABLE_SIZE Increse it if the default size does not fit the board's needs. This is most likely due to a large ACPI DSDT table is used. +config INTEL_CAR_CQOS + bool "Support Intel Cache Quality of Service" + help + Cache Quality of Service allows more fine-grained control of cache + usage. As result, it is possible to set up a portion of L2 cache for + CAR and use the remainder for actual caching. + +# +# Each bit in QOS mask controls this many bytes. This is calculated as: +# (CACHE_WAYS / CACHE_BITS_PER_MASK) * CACHE_LINE_SIZE * CACHE_SETS +# +config CACHE_QOS_SIZE_PER_BIT + hex + depends on INTEL_CAR_CQOS + default 0x20000 # 128 KB + +config X86_OFFSET_U_BOOT + hex "Offset of U-Boot in ROM image" + depends on HAVE_SYS_TEXT_BASE + default SYS_TEXT_BASE + +config X86_OFFSET_SPL + hex "Offset of SPL in ROM image" + depends on SPL && X86 + default SPL_TEXT_BASE + endmenu diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 6296b55ff8..5b40838e60 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -41,6 +41,7 @@ extra-y += call32.o endif obj-y += intel_common/ +obj-$(CONFIG_INTEL_APOLLOLAKE) += apollolake/ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_INTEL_BRASWELL) += braswell/ obj-$(CONFIG_INTEL_BROADWELL) += broadwell/ @@ -53,7 +54,8 @@ obj-$(CONFIG_INTEL_QUARK) += quark/ obj-$(CONFIG_INTEL_QUEENSBAY) += queensbay/ obj-$(CONFIG_INTEL_TANGIER) += tangier/ obj-$(CONFIG_APIC) += lapic.o ioapic.o -obj-y += irq.o +obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += irq.o +obj-$(CONFIG_QFW) += qfw_cpu.o ifndef CONFIG_$(SPL_)X86_64 obj-$(CONFIG_SMP) += mp_init.o endif diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig new file mode 100644 index 0000000000..fcff176c27 --- /dev/null +++ b/arch/x86/cpu/apollolake/Kconfig @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright 2019 Google LLC +# + +config INTEL_APOLLOLAKE + bool + select FSP_VERSION2 + select HAVE_FSP + select ARCH_MISC_INIT + select USE_CAR + select INTEL_PMC + select TPL_X86_TSC_TIMER_NATIVE + select SPL_PCH_SUPPORT + select TPL_PCH_SUPPORT + select PCH_SUPPORT + select P2SB + imply ENABLE_MRC_CACHE + imply AHCI_PCI + imply SCSI + imply SCSI_AHCI + imply SPI_FLASH + imply USB + imply USB_EHCI_HCD + imply TPL + imply SPL + imply TPL_X86_16BIT_INIT + imply TPL_OF_PLATDATA + imply ACPI_PMC + imply MMC + imply DM_MMC + imply MMC_PCI + imply MMC_SDHCI + imply CMD_MMC + imply VIDEO_FSP + imply PINCTRL_INTEL + imply PINCTRL_INTEL_APL + imply HAVE_VBT + imply HAVE_X86_FIT + imply INTEL_GPIO + imply SMP + +if INTEL_APOLLOLAKE + +config DCACHE_RAM_BASE + default 0xfef00000 + +config DCACHE_RAM_SIZE + default 0xc0000 + +config DCACHE_RAM_MRC_VAR_SIZE + default 0xb0000 + +config CPU_SPECIFIC_OPTIONS + def_bool y + select SMM_TSEG + select X86_RAMTEST + +config SMM_TSEG_SIZE + hex + default 0x800000 + +config MMCONF_BASE_ADDRESS + hex + default 0xe0000000 + +config TPL_SIZE_LIMIT + default 0x7800 + +config CPU_ADDR_BITS + default 39 + +config APL_SPI_FLASH_BOOT + bool "Support booting with SPI-flash driver instead memory-mapped SPI" + select TPL_SPI_FLASH_SUPPORT + select TPL_SPI_SUPPORT + help + This enables SPI and SPI flash in TPL. Without the this only + available boot method is to use memory-mapped SPI. Since this is + actually fast and produces a TPL which is 7KB smaller, memory-mapped + SPI is the default. + +config APL_BOOT_FROM_FAST_SPI_FLASH + bool "Boot using SPI flash driver" + select APL_SPI_FLASH_BOOT + help + This option is separate from APL_SPI_FLASH_BOOT since it is useful to + be able to compare booting speed with the same build. Enable this to + use the SPI-flash driver to load SPL, U-Boot and FSP-M. For technical + reasons FSP-S is currently always loaded from memory-mapped SPI. See + Apollo Lake's arch_fsp_init_r() for details about that. + +config VBT_ADDR + default 0xff3f1000 + +endif diff --git a/arch/x86/cpu/apollolake/Makefile b/arch/x86/cpu/apollolake/Makefile new file mode 100644 index 0000000000..1760df54d8 --- /dev/null +++ b/arch/x86/cpu/apollolake/Makefile @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC + +obj-$(CONFIG_SPL_BUILD) += cpu_spl.o +obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_SPL_BUILD) += systemagent.o +obj-y += cpu_common.o + +ifndef CONFIG_TPL_BUILD +obj-y += cpu.o +obj-y += punit.o +ifdef CONFIG_SPL_BUILD +obj-y += fsp_m.o +endif +endif +ifndef CONFIG_SPL_BUILD +obj-y += fsp_s.o +endif + +obj-y += hostbridge.o +obj-y += itss.o +obj-y += lpc.o +obj-y += p2sb.o +obj-y += pch.o +obj-y += pmc.o +obj-y += uart.o diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c new file mode 100644 index 0000000000..3d05c82a5c --- /dev/null +++ b/arch/x86/cpu/apollolake/cpu.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <asm/cpu_common.h> +#include <asm/cpu_x86.h> + +static int apl_get_info(struct udevice *dev, struct cpu_info *info) +{ + return cpu_intel_get_info(info, INTEL_BCLK_MHZ); +} + +static int apl_get_count(struct udevice *dev) +{ + return 4; +} + +static const struct cpu_ops cpu_x86_apl_ops = { + .get_desc = cpu_x86_get_desc, + .get_info = apl_get_info, + .get_count = apl_get_count, + .get_vendor = cpu_x86_get_vendor, +}; + +static const struct udevice_id cpu_x86_apl_ids[] = { + { .compatible = "intel,apl-cpu" }, + { } +}; + +U_BOOT_DRIVER(cpu_x86_apl_drv) = { + .name = "cpu_x86_apl", + .id = UCLASS_CPU, + .of_match = cpu_x86_apl_ids, + .bind = cpu_x86_bind, + .ops = &cpu_x86_apl_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c new file mode 100644 index 0000000000..ba6bda37bc --- /dev/null +++ b/arch/x86/cpu/apollolake/cpu_common.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <asm/cpu_common.h> +#include <asm/msr.h> + +void cpu_flush_l1d_to_l2(void) +{ + struct msr_t msr; + + msr = msr_read(MSR_POWER_MISC); + msr.lo |= FLUSH_DL1_L2; + msr_write(MSR_POWER_MISC, msr); +} diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c new file mode 100644 index 0000000000..8a39c3128e --- /dev/null +++ b/arch/x86/cpu/apollolake/cpu_spl.c @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + * + * Portions taken from coreboot + */ + +#include <common.h> +#include <acpi_s3.h> +#include <dm.h> +#include <ec_commands.h> +#include <log.h> +#include <spi_flash.h> +#include <spl.h> +#include <syscon.h> +#include <asm/cpu.h> +#include <asm/cpu_common.h> +#include <asm/cpu_x86.h> +#include <asm/fast_spi.h> +#include <asm/intel_pinctrl.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/msr.h> +#include <asm/mtrr.h> +#include <asm/pci.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include <asm/arch/iomap.h> +#include <asm/arch/lpc.h> +#include <asm/arch/pch.h> +#include <asm/arch/systemagent.h> +#include <asm/arch/uart.h> +#include <asm/fsp2/fsp_api.h> +#include <linux/sizes.h> +#include <power/acpi_pmc.h> + +/* Define this here to avoid referencing any drivers for the debug UART 1 */ +#define PCH_DEV_P2SB PCI_BDF(0, 0x0d, 0) + +static void pch_uart_init(void) +{ + /* + * Set up the pinmux so that the UART rx/tx signals are connected + * outside the SoC. + * + * There are about 500 lines of code required to program the GPIO + * configuration for the UARTs. But it boils down to four writes, and + * for the debug UART we want the minimum possible amount of code before + * the UART is running. So just add the magic writes here. See + * apl_hostbridge_early_init_pinctrl() for the full horror. + */ + if (PCI_FUNC(PCH_DEV_UART) == 1) { + writel(0x40000402, 0xd0c50650); + writel(0x3c47, 0xd0c50654); + writel(0x40000400, 0xd0c50658); + writel(0x3c48, 0xd0c5065c); + } else { /* UART2 */ + writel(0x40000402, 0xd0c50670); + writel(0x3c4b, 0xd0c50674); + writel(0x40000400, 0xd0c50678); + writel(0x3c4c, 0xd0c5067c); + } + +#ifdef CONFIG_DEBUG_UART + apl_uart_init(PCH_DEV_UART, CONFIG_DEBUG_UART_BASE); +#endif +} + +static void p2sb_enable_bar(ulong bar) +{ + /* Enable PCR Base address in PCH */ + pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, bar, + PCI_SIZE_32); + pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32); + + /* Enable P2SB MSE */ + pci_x86_write_config(PCH_DEV_P2SB, PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY, + PCI_SIZE_8); +} + +/* + * board_debug_uart_init() - Init the debug UART ready for use + * + * This is the minimum init needed to get the UART running. It avoids any + * drivers or complex code, so that the UART is running as soon as possible. + */ +void board_debug_uart_init(void) +{ + p2sb_enable_bar(IOMAP_P2SB_BAR); + pch_uart_init(); +} + +static int fast_spi_cache_bios_region(void) +{ + uint map_size, offset; + ulong map_base, base; + int ret; + + ret = fast_spi_early_init(PCH_DEV_SPI, IOMAP_SPI_BASE); + if (ret) + return log_msg_ret("early_init", ret); + + ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, &map_base, &map_size, + &offset); + if (ret) + return log_msg_ret("get_mmap", ret); + + base = SZ_4G - map_size; + mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size); + log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size); + + return 0; +} + +static void enable_pm_timer_emulation(struct udevice *pmc) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc); + msr_t msr; + + /* + * The derived frequency is calculated as follows: + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. + * + * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is + * used. + */ + msr.hi = (3579545ULL << 32) / CTC_FREQ; + + /* Set PM1 timer IO port and enable */ + msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR); + debug("PM timer %x %x\n", msr.hi, msr.lo); + msr_write(MSR_EMULATE_PM_TIMER, msr); +} + +static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep) +{ + uint base; + uint size; + + if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_MEC)) { + base = MEC_EMI_BASE; + size = MEC_EMI_SIZE; + } else { + base = EC_HOST_CMD_REGION0; + size = 2 * EC_HOST_CMD_REGION_SIZE; + /* Make sure MEMMAP region follows host cmd region */ + assert(base + size == EC_LPC_ADDR_MEMMAP); + size += EC_MEMMAP_SIZE; + } + + *out_basep = base; + *out_sizep = size; +} + +static void early_ec_init(void) +{ + uint base, size; + + /* + * Set up LPC decoding for the Chrome OS EC I/O port ranges: + * - Ports 62/66, 60/64, and 200->208 + * - Chrome OS EC communication I/O ports + */ + lpc_enable_fixed_io_ranges(LPC_IOE_EC_62_66 | LPC_IOE_KBC_60_64 | + LPC_IOE_LGE_200); + google_chromeec_ioport_range(&base, &size); + lpc_open_pmio_window(base, size); +} + +static int arch_cpu_init_tpl(void) +{ + struct udevice *pmc, *sa, *p2sb, *serial, *spi, *lpc; + int ret; + + ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); + if (ret) + return log_msg_ret("PMC", ret); + + /* Clear global reset promotion bit */ + ret = pmc_global_reset_set_enable(pmc, false); + if (ret) + return log_msg_ret("disable global reset", ret); + + enable_pm_timer_emulation(pmc); + + ret = uclass_first_device_err(UCLASS_P2SB, &p2sb); + if (ret) + return log_msg_ret("p2sb", ret); + ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &sa); + if (ret) + return log_msg_ret("northbridge", ret); + gd->baudrate = CONFIG_BAUDRATE; + ret = uclass_first_device_err(UCLASS_SERIAL, &serial); + if (ret) + return log_msg_ret("serial", ret); + if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) { + ret = uclass_first_device_err(UCLASS_SPI, &spi); + if (ret) + return log_msg_ret("SPI", ret); + } else { + /* Alternative code if we don't have SPI in TPL */ + if (IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH)) + printf("Warning: Enable APL_SPI_FLASHBOOT to use SPI-flash driver in TPL"); + ret = fast_spi_cache_bios_region(); + if (ret) + return log_msg_ret("BIOS cache", ret); + } + ret = pmc_disable_tco(pmc); + if (ret) + return log_msg_ret("disable TCO", ret); + ret = pmc_gpe_init(pmc); + if (ret) + return log_msg_ret("pmc_gpe", ret); + ret = uclass_first_device_err(UCLASS_LPC, &lpc); + if (ret) + return log_msg_ret("lpc", ret); + + early_ec_init(); + + return 0; +} + +/* + * Enables several BARs and devices which are needed for memory init + * - MCH_BASE_ADDR is needed in order to talk to the memory controller + * - HPET is enabled because FSP wants to store a pointer to global data in the + * HPET comparator register + */ +static int arch_cpu_init_spl(void) +{ + struct udevice *pmc, *p2sb; + int ret; + + ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); + if (ret) + return log_msg_ret("Could not probe PMC", ret); + ret = uclass_first_device_err(UCLASS_P2SB, &p2sb); + if (ret) + return log_msg_ret("Cannot set up p2sb", ret); + + lpc_io_setup_comm_a_b(); + + /* TODO(sjg@chromium.org): Enable upper RTC bank here */ + + ret = pmc_init(pmc); + if (ret < 0) + return log_msg_ret("Could not init PMC", ret); +#ifdef CONFIG_HAVE_ACPI_RESUME + ret = pmc_prev_sleep_state(pmc); + if (ret < 0) + return log_msg_ret("Could not get PMC sleep state", ret); + gd->arch.prev_sleep_state = ret; +#endif + + return 0; +} + +int arch_cpu_init(void) +{ + int ret = 0; + + if (spl_phase() == PHASE_TPL) + ret = arch_cpu_init_tpl(); + else if (spl_phase() == PHASE_SPL) + ret = arch_cpu_init_spl(); + if (ret) + printf("%s: Error %d\n", __func__, ret); + + return ret; +} diff --git a/arch/x86/cpu/apollolake/fsp_m.c b/arch/x86/cpu/apollolake/fsp_m.c new file mode 100644 index 0000000000..5308af8ed4 --- /dev/null +++ b/arch/x86/cpu/apollolake/fsp_m.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <asm/arch/iomap.h> +#include <asm/arch/fsp/fsp_configs.h> +#include <asm/arch/fsp/fsp_m_upd.h> +#include <asm/fsp2/fsp_internal.h> +#include <dm/uclass-internal.h> + +/* + * ODT settings: + * If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A and HIGH for ODT_B, + * choose ODT_A_B_HIGH_HIGH. If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A + * and LOW for ODT_B, choose ODT_A_B_HIGH_LOW. + * + * Note that the enum values correspond to the interpreted UPD fields + * within Ch[3:0]_OdtConfig parameters. + */ +enum { + ODT_A_B_HIGH_LOW = 0 << 1, + ODT_A_B_HIGH_HIGH = 1 << 1, + N_WR_24 = 1 << 5, +}; + +/* + * LPDDR4 helper routines for configuring the memory UPD for LPDDR4 operation. + * There are four physical LPDDR4 channels, each 32-bits wide. There are two + * logical channels using two physical channels together to form a 64-bit + * interface to memory for each logical channel. + */ + +enum { + LP4_PHYS_CH0A, + LP4_PHYS_CH0B, + LP4_PHYS_CH1A, + LP4_PHYS_CH1B, + + LP4_NUM_PHYS_CHANNELS, +}; + +/* + * The DQs within a physical channel can be bit-swizzled within each byte. + * Within a channel the bytes can be swapped, but the DQs need to be routed + * with the corresponding DQS (strobe). + */ +enum { + LP4_DQS0, + LP4_DQS1, + LP4_DQS2, + LP4_DQS3, + + LP4_NUM_BYTE_LANES, + DQ_BITS_PER_DQS = 8, +}; + +/* Provide bit swizzling per DQS and byte swapping within a channel */ +struct lpddr4_chan_swizzle_cfg { + u8 dqs[LP4_NUM_BYTE_LANES][DQ_BITS_PER_DQS]; +}; + +struct lpddr4_swizzle_cfg { + struct lpddr4_chan_swizzle_cfg phys[LP4_NUM_PHYS_CHANNELS]; +}; + +static void setup_sdram(struct fsp_m_config *cfg, + const struct lpddr4_swizzle_cfg *swizzle_cfg) +{ + const struct lpddr4_chan_swizzle_cfg *sch; + /* Number of bytes to copy per DQS */ + const size_t sz = DQ_BITS_PER_DQS; + int chan; + + cfg->memory_down = 1; + cfg->scrambler_support = 1; + cfg->channel_hash_mask = 0x36; + cfg->slice_hash_mask = 9; + cfg->interleaved_mode = 2; + cfg->channels_slices_enable = 0; + cfg->min_ref_rate2x_enable = 0; + cfg->dual_rank_support_enable = 1; + + /* LPDDR4 is memory down so no SPD addresses */ + cfg->dimm0_spd_address = 0; + cfg->dimm1_spd_address = 0; + + for (chan = 0; chan < 4; chan++) { + struct fsp_ram_channel *ch = &cfg->chan[chan]; + + ch->rank_enable = 1; + ch->device_width = 1; + ch->dram_density = 2; + ch->option = 3; + ch->odt_config = ODT_A_B_HIGH_HIGH; + } + + /* + * CH0_DQB byte lanes in the bit swizzle configuration field are + * not 1:1. The mapping within the swizzling field is: + * indices [0:7] - byte lane 1 (DQS1) DQ[8:15] + * indices [8:15] - byte lane 0 (DQS0) DQ[0:7] + * indices [16:23] - byte lane 3 (DQS3) DQ[24:31] + * indices [24:31] - byte lane 2 (DQS2) DQ[16:23] + */ + sch = &swizzle_cfg->phys[LP4_PHYS_CH0B]; + memcpy(&cfg->ch_bit_swizzling[0][0], &sch->dqs[LP4_DQS1], sz); + memcpy(&cfg->ch_bit_swizzling[0][8], &sch->dqs[LP4_DQS0], sz); + memcpy(&cfg->ch_bit_swizzling[0][16], &sch->dqs[LP4_DQS3], sz); + memcpy(&cfg->ch_bit_swizzling[0][24], &sch->dqs[LP4_DQS2], sz); + + /* + * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1. + */ + sch = &swizzle_cfg->phys[LP4_PHYS_CH0A]; + memcpy(&cfg->ch_bit_swizzling[1][0], &sch->dqs[LP4_DQS0], sz); + memcpy(&cfg->ch_bit_swizzling[1][8], &sch->dqs[LP4_DQS1], sz); + memcpy(&cfg->ch_bit_swizzling[1][16], &sch->dqs[LP4_DQS2], sz); + memcpy(&cfg->ch_bit_swizzling[1][24], &sch->dqs[LP4_DQS3], sz); + + sch = &swizzle_cfg->phys[LP4_PHYS_CH1B]; + memcpy(&cfg->ch_bit_swizzling[2][0], &sch->dqs[LP4_DQS1], sz); + memcpy(&cfg->ch_bit_swizzling[2][8], &sch->dqs[LP4_DQS0], sz); + memcpy(&cfg->ch_bit_swizzling[2][16], &sch->dqs[LP4_DQS3], sz); + memcpy(&cfg->ch_bit_swizzling[2][24], &sch->dqs[LP4_DQS2], sz); + + /* + * CH0_DQA byte lanes in the bit swizzle configuration field are 1:1. + */ + sch = &swizzle_cfg->phys[LP4_PHYS_CH1A]; + memcpy(&cfg->ch_bit_swizzling[3][0], &sch->dqs[LP4_DQS0], sz); + memcpy(&cfg->ch_bit_swizzling[3][8], &sch->dqs[LP4_DQS1], sz); + memcpy(&cfg->ch_bit_swizzling[3][16], &sch->dqs[LP4_DQS2], sz); + memcpy(&cfg->ch_bit_swizzling[3][24], &sch->dqs[LP4_DQS3], sz); +} + +int fspm_update_config(struct udevice *dev, struct fspm_upd *upd) +{ + struct fsp_m_config *cfg = &upd->config; + struct fspm_arch_upd *arch = &upd->arch; + + arch->nvs_buffer_ptr = NULL; + prepare_mrc_cache(upd); + arch->stack_base = (void *)0xfef96000; + arch->boot_loader_tolum_size = 0; + + arch->boot_mode = FSP_BOOT_WITH_FULL_CONFIGURATION; + cfg->serial_debug_port_type = 2; + cfg->serial_debug_port_device = 2; + cfg->serial_debug_port_stride_size = 2; + cfg->serial_debug_port_address = 0; + + cfg->package = 1; + /* Don't enforce a memory size limit */ + cfg->memory_size_limit = 0; + cfg->low_memory_max_value = 2048; /* 2 GB */ + /* No restrictions on memory above 4GiB */ + cfg->high_memory_max_value = 0; + + /* Always default to attempt to use saved training data */ + cfg->disable_fast_boot = 0; + + const u8 *swizzle_data; + + swizzle_data = dev_read_u8_array_ptr(dev, "lpddr4-swizzle", + LP4_NUM_BYTE_LANES * + DQ_BITS_PER_DQS * + LP4_NUM_PHYS_CHANNELS); + if (!swizzle_data) + return log_msg_ret("Cannot read swizzel data", -EINVAL); + + setup_sdram(cfg, (struct lpddr4_swizzle_cfg *)swizzle_data); + + cfg->pre_mem_gpio_table_ptr = 0; + + cfg->profile = 0xb; + cfg->msg_level_mask = 0; + + /* other */ + cfg->skip_cse_rbp = 1; + cfg->periodic_retraining_disable = 0; + cfg->enable_s3_heci2 = 0; + + return 0; +} + +/* + * The FSP-M binary appears to break the SPI controller. It can be fixed by + * writing the BAR again, so do that here + */ +int fspm_done(struct udevice *dev) +{ + struct udevice *spi; + int ret; + + /* Don't probe the device, since that reads the BAR */ + ret = uclass_find_first_device(UCLASS_SPI, &spi); + if (ret) + return log_msg_ret("SPI", ret); + if (!spi) + return log_msg_ret("no SPI", -ENODEV); + + dm_pci_write_config32(spi, PCI_BASE_ADDRESS_0, + IOMAP_SPI_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY); + + return 0; +} diff --git a/arch/x86/cpu/apollolake/fsp_s.c b/arch/x86/cpu/apollolake/fsp_s.c new file mode 100644 index 0000000000..9804227f80 --- /dev/null +++ b/arch/x86/cpu/apollolake/fsp_s.c @@ -0,0 +1,661 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <acpi_s3.h> +#include <binman.h> +#include <dm.h> +#include <irq.h> +#include <asm/intel_pinctrl.h> +#include <asm/io.h> +#include <asm/intel_regs.h> +#include <asm/msr.h> +#include <asm/msr-index.h> +#include <asm/pci.h> +#include <asm/arch/cpu.h> +#include <asm/arch/systemagent.h> +#include <asm/arch/fsp/fsp_configs.h> +#include <asm/arch/fsp/fsp_s_upd.h> + +#define PCH_P2SB_E0 0xe0 +#define HIDE_BIT BIT(0) + +#define INTEL_GSPI_MAX 3 +#define INTEL_I2C_DEV_MAX 8 +#define MAX_USB2_PORTS 8 + +enum { + CHIPSET_LOCKDOWN_FSP = 0, /* FSP handles locking per UPDs */ + CHIPSET_LOCKDOWN_COREBOOT, /* coreboot handles locking */ +}; + +enum i2c_speed { + I2C_SPEED_STANDARD = 100000, + I2C_SPEED_FAST = 400000, + I2C_SPEED_FAST_PLUS = 1000000, + I2C_SPEED_HIGH = 3400000, + I2C_SPEED_FAST_ULTRA = 5000000, +}; + +/* + * Timing values are in units of clock period, with the clock speed + * provided by the SOC + * + * TODO(sjg@chromium.org): Connect this up to the I2C driver + */ +struct dw_i2c_speed_config { + enum i2c_speed speed; + /* SCL high and low period count */ + u16 scl_lcnt; + u16 scl_hcnt; + /* + * SDA hold time should be 300ns in standard and fast modes + * and long enough for deterministic logic level change in + * fast-plus and high speed modes. + * + * [15:0] SDA TX Hold Time + * [23:16] SDA RX Hold Time + */ + u32 sda_hold; +}; + +/* Serial IRQ control. SERIRQ_QUIET is the default (0) */ +enum serirq_mode { + SERIRQ_QUIET, + SERIRQ_CONTINUOUS, + SERIRQ_OFF, +}; + +/* + * This I2C controller has support for 3 independent speed configs but can + * support both FAST_PLUS and HIGH speeds through the same set of speed + * config registers. These are treated separately so the speed config values + * can be provided via ACPI to the OS. + */ +#define DW_I2C_SPEED_CONFIG_COUNT 4 + +struct dw_i2c_bus_config { + /* Bus should be enabled in TPL with temporary base */ + int early_init; + /* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */ + enum i2c_speed speed; + /* + * If rise_time_ns is non-zero the calculations for lcnt and hcnt + * registers take into account the times of the bus. However, if + * there is a match in speed_config those register values take + * precedence + */ + int rise_time_ns; + int fall_time_ns; + int data_hold_time_ns; + /* Specific bus speed configuration */ + struct dw_i2c_speed_config speed_config[DW_I2C_SPEED_CONFIG_COUNT]; +}; + +struct gspi_cfg { + /* Bus speed in MHz */ + u32 speed_mhz; + /* Bus should be enabled prior to ramstage with temporary base */ + u8 early_init; +}; + +/* + * This structure will hold data required by common blocks. + * These are soc specific configurations which will be filled by soc. + * We'll fill this structure once during init and use the data in common block. + */ +struct soc_intel_common_config { + int chipset_lockdown; + struct gspi_cfg gspi[INTEL_GSPI_MAX]; + struct dw_i2c_bus_config i2c[INTEL_I2C_DEV_MAX]; +}; + +enum pnp_settings { + PNP_PERF, + PNP_POWER, + PNP_PERF_POWER, +}; + +struct usb2_eye_per_port { + u8 per_port_tx_pe_half; + u8 per_port_pe_txi_set; + u8 per_port_txi_set; + u8 hs_skew_sel; + u8 usb_tx_emphasis_en; + u8 per_port_rxi_set; + u8 hs_npre_drv_sel; + u8 override_en; +}; + +struct apl_config { + /* Common structure containing soc config data required by common code*/ + struct soc_intel_common_config common_soc_config; + + /* + * Mapping from PCIe root port to CLKREQ input on the SOC. The SOC has + * four CLKREQ inputs, but six root ports. Root ports without an + * associated CLKREQ signal must be marked with "CLKREQ_DISABLED" + */ + u8 pcie_rp_clkreq_pin[MAX_PCIE_PORTS]; + + /* Enable/disable hot-plug for root ports (0 = disable, 1 = enable) */ + u8 pcie_rp_hotplug_enable[MAX_PCIE_PORTS]; + + /* De-emphasis enable configuration for each PCIe root port */ + u8 pcie_rp_deemphasis_enable[MAX_PCIE_PORTS]; + + /* + * [14:8] DDR mode Number of dealy elements.Each = 125pSec. + * [6:0] SDR mode Number of dealy elements.Each = 125pSec. + */ + u32 emmc_tx_cmd_cntl; + + /* + * [14:8] HS400 mode Number of dealy elements.Each = 125pSec. + * [6:0] SDR104/HS200 mode Number of dealy elements.Each = 125pSec. + */ + u32 emmc_tx_data_cntl1; + + /* + * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec. + * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec. + * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec. + * [6:0] SDR12/Compatibility mode Number of dealy elements. + * Each = 125pSec. + */ + u32 emmc_tx_data_cntl2; + + /* + * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec. + * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec. + * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec. + * [6:0] SDR12/Compatibility mode Number of dealy elements. + * Each = 125pSec. + */ + u32 emmc_rx_cmd_data_cntl1; + + /* + * [14:8] HS400 mode 1 Number of dealy elements.Each = 125pSec. + * [6:0] HS400 mode 2 Number of dealy elements.Each = 125pSec. + */ + u32 emmc_rx_strobe_cntl; + + /* + * [13:8] Auto Tuning mode Number of dealy elements.Each = 125pSec. + * [6:0] SDR104/HS200 Number of dealy elements.Each = 125pSec. + */ + u32 emmc_rx_cmd_data_cntl2; + + /* Select the eMMC max speed allowed */ + u32 emmc_host_max_speed; + + /* Specifies on which IRQ the SCI will internally appear */ + u32 sci_irq; + + /* Configure serial IRQ (SERIRQ) line */ + enum serirq_mode serirq_mode; + + /* Configure LPSS S0ix Enable */ + bool lpss_s0ix_enable; + + /* Enable DPTF support */ + bool dptf_enable; + + /* TCC activation offset value in degrees Celsius */ + int tcc_offset; + + /* + * Configure Audio clk gate and power gate + * IOSF-SB port ID 92 offset 0x530 [5] and [3] + */ + bool hdaudio_clk_gate_enable; + bool hdaudio_pwr_gate_enable; + bool hdaudio_bios_config_lockdown; + + /* SLP S3 minimum assertion width */ + int slp_s3_assertion_width_usecs; + + /* GPIO pin for PERST_0 */ + u32 prt0_gpio; + + /* USB2 eye diagram settings per port */ + struct usb2_eye_per_port usb2eye[MAX_USB2_PORTS]; + + /* GPIO SD card detect pin */ + unsigned int sdcard_cd_gpio; + + /* + * PRMRR size setting with three options + * 0x02000000 - 32MiB + * 0x04000000 - 64MiB + * 0x08000000 - 128MiB + */ + u32 PrmrrSize; + + /* + * Enable SGX feature. + * Enabling SGX feature is 2 step process, + * (1) set sgx_enable = 1 + * (2) set PrmrrSize to supported size + */ + bool sgx_enable; + + /* + * Select PNP Settings. + * (0) Performance, + * (1) Power + * (2) Power & Performance + */ + enum pnp_settings pnp_settings; + + /* + * PMIC PCH_PWROK delay configuration - IPC Configuration + * Upd for changing PCH_PWROK delay configuration : I2C_Slave_Address + * (31:24) + Register_Offset (23:16) + OR Value (15:8) + AND Value (7:0) + */ + u32 pmic_pmc_ipc_ctrl; + + /* + * Options to disable XHCI Link Compliance Mode. Default is FALSE to not + * disable Compliance Mode. Set TRUE to disable Compliance Mode. + * 0:FALSE(Default), 1:True. + */ + bool disable_compliance_mode; + + /* + * Options to change USB3 ModPhy setting for the Integrated Filter (IF) + * value. Default is 0 to not changing default IF value (0x12). Set + * value with the range from 0x01 to 0xff to change IF value. + */ + u32 mod_phy_if_value; + + /* + * Options to bump USB3 LDO voltage. Default is FALSE to not increasing + * LDO voltage. Set TRUE to increase LDO voltage with 40mV. + * 0:FALSE (default), 1:True. + */ + bool mod_phy_voltage_bump; + + /* + * Options to adjust PMIC Vdd2 voltage. Default is 0 to not adjusting + * the PMIC Vdd2 default voltage 1.20v. Upd for changing Vdd2 Voltage + * configuration: I2C_Slave_Address (31:23) + Register_Offset (23:16) + * + OR Value (15:8) + AND Value (7:0) through BUCK5_VID[3:2]: + * 00=1.10v, 01=1.15v, 10=1.24v, 11=1.20v (default). + */ + u32 pmic_vdd2_voltage; + + /* Option to enable VTD feature */ + bool enable_vtd; +}; + +static int get_config(struct udevice *dev, struct apl_config *apl) +{ + const u8 *ptr; + ofnode node; + u32 emmc[4]; + int ret; + + memset(apl, '\0', sizeof(*apl)); + + node = dev_read_subnode(dev, "fsp-s"); + if (!ofnode_valid(node)) + return log_msg_ret("fsp-s settings", -ENOENT); + + ptr = ofnode_read_u8_array_ptr(node, "pcie-rp-clkreq-pin", + MAX_PCIE_PORTS); + if (!ptr) + return log_msg_ret("pcie-rp-clkreq-pin", -EINVAL); + memcpy(apl->pcie_rp_clkreq_pin, ptr, MAX_PCIE_PORTS); + + ret = ofnode_read_u32(node, "prt0-gpio", &apl->prt0_gpio); + if (ret) + return log_msg_ret("prt0-gpio", ret); + ret = ofnode_read_u32(node, "sdcard-cd-gpio", &apl->sdcard_cd_gpio); + if (ret) + return log_msg_ret("sdcard-cd-gpio", ret); + + ret = ofnode_read_u32_array(node, "emmc", emmc, ARRAY_SIZE(emmc)); + if (ret) + return log_msg_ret("emmc", ret); + apl->emmc_tx_data_cntl1 = emmc[0]; + apl->emmc_tx_data_cntl2 = emmc[1]; + apl->emmc_rx_cmd_data_cntl1 = emmc[2]; + apl->emmc_rx_cmd_data_cntl2 = emmc[3]; + + apl->dptf_enable = ofnode_read_bool(node, "dptf-enable"); + + apl->hdaudio_clk_gate_enable = ofnode_read_bool(node, + "hdaudio-clk-gate-enable"); + apl->hdaudio_pwr_gate_enable = ofnode_read_bool(node, + "hdaudio-pwr-gate-enable"); + apl->hdaudio_bios_config_lockdown = ofnode_read_bool(node, + "hdaudio-bios-config-lockdown"); + apl->lpss_s0ix_enable = ofnode_read_bool(node, "lpss-s0ix-enable"); + + /* Santa */ + apl->usb2eye[1].per_port_pe_txi_set = 7; + apl->usb2eye[1].per_port_txi_set = 2; + + return 0; +} + +static void apl_fsp_silicon_init_params_cb(struct apl_config *apl, + struct fsp_s_config *cfg) +{ + u8 port; + + for (port = 0; port < MAX_USB2_PORTS; port++) { + if (apl->usb2eye[port].per_port_tx_pe_half) + cfg->port_usb20_per_port_tx_pe_half[port] = + apl->usb2eye[port].per_port_tx_pe_half; + + if (apl->usb2eye[port].per_port_pe_txi_set) + cfg->port_usb20_per_port_pe_txi_set[port] = + apl->usb2eye[port].per_port_pe_txi_set; + + if (apl->usb2eye[port].per_port_txi_set) + cfg->port_usb20_per_port_txi_set[port] = + apl->usb2eye[port].per_port_txi_set; + + if (apl->usb2eye[port].hs_skew_sel) + cfg->port_usb20_hs_skew_sel[port] = + apl->usb2eye[port].hs_skew_sel; + + if (apl->usb2eye[port].usb_tx_emphasis_en) + cfg->port_usb20_i_usb_tx_emphasis_en[port] = + apl->usb2eye[port].usb_tx_emphasis_en; + + if (apl->usb2eye[port].per_port_rxi_set) + cfg->port_usb20_per_port_rxi_set[port] = + apl->usb2eye[port].per_port_rxi_set; + + if (apl->usb2eye[port].hs_npre_drv_sel) + cfg->port_usb20_hs_npre_drv_sel[port] = + apl->usb2eye[port].hs_npre_drv_sel; + } +} + +int fsps_update_config(struct udevice *dev, ulong rom_offset, + struct fsps_upd *upd) +{ + struct fsp_s_config *cfg = &upd->config; + struct apl_config *apl; + struct binman_entry vbt; + void *buf; + int ret; + + ret = binman_entry_find("intel-vbt", &vbt); + if (ret) + return log_msg_ret("Cannot find VBT", ret); + vbt.image_pos += rom_offset; + buf = malloc(vbt.size); + if (!buf) + return log_msg_ret("Alloc VBT", -ENOMEM); + + /* + * Load VBT before devicetree-specific config. This only supports + * memory-mapped SPI at present. + */ + bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi"); + memcpy(buf, (void *)vbt.image_pos, vbt.size); + bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI); + if (*(u32 *)buf != VBT_SIGNATURE) + return log_msg_ret("VBT signature", -EINVAL); + cfg->graphics_config_ptr = (ulong)buf; + + apl = malloc(sizeof(*apl)); + if (!apl) + return log_msg_ret("config", -ENOMEM); + get_config(dev, apl); + + cfg->ish_enable = 0; + cfg->enable_sata = 0; + cfg->pcie_root_port_en[2] = 0; + cfg->pcie_rp_hot_plug[2] = 0; + cfg->pcie_root_port_en[3] = 0; + cfg->pcie_rp_hot_plug[3] = 0; + cfg->pcie_root_port_en[4] = 0; + cfg->pcie_rp_hot_plug[4] = 0; + cfg->pcie_root_port_en[5] = 0; + cfg->pcie_rp_hot_plug[5] = 0; + cfg->pcie_root_port_en[1] = 0; + cfg->pcie_rp_hot_plug[1] = 0; + cfg->usb_otg = 0; + cfg->i2c6_enable = 0; + cfg->i2c7_enable = 0; + cfg->hsuart3_enable = 0; + cfg->spi1_enable = 0; + cfg->spi2_enable = 0; + cfg->sdio_enabled = 0; + + memcpy(cfg->pcie_rp_clk_req_number, apl->pcie_rp_clkreq_pin, + sizeof(cfg->pcie_rp_clk_req_number)); + + memcpy(cfg->pcie_rp_hot_plug, apl->pcie_rp_hotplug_enable, + sizeof(cfg->pcie_rp_hot_plug)); + + switch (apl->serirq_mode) { + case SERIRQ_QUIET: + cfg->sirq_enable = 1; + cfg->sirq_mode = 0; + break; + case SERIRQ_CONTINUOUS: + cfg->sirq_enable = 1; + cfg->sirq_mode = 1; + break; + case SERIRQ_OFF: + default: + cfg->sirq_enable = 0; + break; + } + + if (apl->emmc_tx_cmd_cntl) + cfg->emmc_tx_cmd_cntl = apl->emmc_tx_cmd_cntl; + if (apl->emmc_tx_data_cntl1) + cfg->emmc_tx_data_cntl1 = apl->emmc_tx_data_cntl1; + if (apl->emmc_tx_data_cntl2) + cfg->emmc_tx_data_cntl2 = apl->emmc_tx_data_cntl2; + if (apl->emmc_rx_cmd_data_cntl1) + cfg->emmc_rx_cmd_data_cntl1 = apl->emmc_rx_cmd_data_cntl1; + if (apl->emmc_rx_strobe_cntl) + cfg->emmc_rx_strobe_cntl = apl->emmc_rx_strobe_cntl; + if (apl->emmc_rx_cmd_data_cntl2) + cfg->emmc_rx_cmd_data_cntl2 = apl->emmc_rx_cmd_data_cntl2; + if (apl->emmc_host_max_speed) + cfg->e_mmc_host_max_speed = apl->emmc_host_max_speed; + + cfg->lpss_s0ix_enable = apl->lpss_s0ix_enable; + + cfg->skip_mp_init = true; + + /* Disable setting of EISS bit in FSP */ + cfg->spi_eiss = 0; + + /* Disable FSP from locking access to the RTC NVRAM */ + cfg->rtc_lock = 0; + + /* Enable Audio clk gate and power gate */ + cfg->hd_audio_clk_gate = apl->hdaudio_clk_gate_enable; + cfg->hd_audio_pwr_gate = apl->hdaudio_pwr_gate_enable; + /* Bios config lockdown Audio clk and power gate */ + cfg->bios_cfg_lock_down = apl->hdaudio_bios_config_lockdown; + apl_fsp_silicon_init_params_cb(apl, cfg); + + cfg->usb_otg = true; + cfg->vtd_enable = apl->enable_vtd; + + return 0; +} + +static void p2sb_set_hide_bit(pci_dev_t dev, int hide) +{ + pci_x86_clrset_config(dev, PCH_P2SB_E0 + 1, HIDE_BIT, + hide ? HIDE_BIT : 0, PCI_SIZE_8); +} + +/* Configure package power limits */ +static int set_power_limits(struct udevice *dev) +{ + msr_t rapl_msr_reg, limit; + u32 power_unit; + u32 tdp, min_power, max_power; + u32 pl2_val; + u32 override_tdp[2]; + int ret; + + /* Get units */ + rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU_UNIT); + power_unit = 1 << (rapl_msr_reg.lo & 0xf); + + /* Get power defaults for this SKU */ + rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU); + tdp = rapl_msr_reg.lo & PKG_POWER_LIMIT_MASK; + pl2_val = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK; + min_power = (rapl_msr_reg.lo >> 16) & PKG_POWER_LIMIT_MASK; + max_power = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK; + + if (min_power > 0 && tdp < min_power) + tdp = min_power; + + if (max_power > 0 && tdp > max_power) + tdp = max_power; + + ret = dev_read_u32_array(dev, "tdp-pl-override-mw", override_tdp, + ARRAY_SIZE(override_tdp)); + if (ret) + return log_msg_ret("tdp-pl-override-mw", ret); + + /* Set PL1 override value */ + if (override_tdp[0]) + tdp = override_tdp[0] * power_unit / 1000; + + /* Set PL2 override value */ + if (override_tdp[1]) + pl2_val = override_tdp[1] * power_unit / 1000; + + /* Set long term power limit to TDP */ + limit.lo = tdp & PKG_POWER_LIMIT_MASK; + /* Set PL1 Pkg Power clamp bit */ + limit.lo |= PKG_POWER_LIMIT_CLAMP; + + limit.lo |= PKG_POWER_LIMIT_EN; + limit.lo |= (MB_POWER_LIMIT1_TIME_DEFAULT & + PKG_POWER_LIMIT_TIME_MASK) << PKG_POWER_LIMIT_TIME_SHIFT; + + /* Set short term power limit PL2 */ + limit.hi = pl2_val & PKG_POWER_LIMIT_MASK; + limit.hi |= PKG_POWER_LIMIT_EN; + + /* Program package power limits in RAPL MSR */ + msr_write(MSR_PKG_POWER_LIMIT, limit); + log_info("RAPL PL1 %d.%dW\n", tdp / power_unit, + 100 * (tdp % power_unit) / power_unit); + log_info("RAPL PL2 %d.%dW\n", pl2_val / power_unit, + 100 * (pl2_val % power_unit) / power_unit); + + /* + * Sett RAPL MMIO register for Power limits. RAPL driver is using MSR + * instead of MMIO, so disable LIMIT_EN bit for MMIO + */ + writel(limit.lo & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL)); + writel(limit.hi & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL + 4)); + + return 0; +} + +int p2sb_unhide(void) +{ + pci_dev_t dev = PCI_BDF(0, 0xd, 0); + ulong val; + + p2sb_set_hide_bit(dev, 0); + + pci_x86_read_config(dev, PCI_VENDOR_ID, &val, PCI_SIZE_16); + + if (val != PCI_VENDOR_ID_INTEL) + return log_msg_ret("p2sb unhide", -EIO); + + return 0; +} + +/* Overwrites the SCI IRQ if another IRQ number is given by device tree */ +static void set_sci_irq(void) +{ + /* Skip this for now */ +} + +int arch_fsps_preinit(void) +{ + struct udevice *itss; + int ret; + + ret = uclass_first_device_err(UCLASS_IRQ, &itss); + if (ret) + return log_msg_ret("no itss", ret); + /* + * Snapshot the current GPIO IRQ polarities. FSP is setting a default + * policy that doesn't honour boards' requirements + */ + irq_snapshot_polarities(itss); + + /* + * Clear the GPI interrupt status and enable registers. These + * registers do not get reset to default state when booting from S5. + */ + ret = pinctrl_gpi_clear_int_cfg(); + if (ret) + return log_msg_ret("gpi_clear", ret); + + return 0; +} + +int arch_fsp_init_r(void) +{ +#ifdef CONFIG_HAVE_ACPI_RESUME + bool s3wake = gd->arch.prev_sleep_state == ACPI_S3; +#else + bool s3wake = false; +#endif + struct udevice *dev, *itss; + int ret; + + /* + * This must be called before any devices are probed. Put any probing + * into arch_fsps_preinit() above. + * + * We don't use CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH here since it will + * force PCI to be probed. + */ + ret = fsp_silicon_init(s3wake, false); + if (ret) + return ret; + + ret = uclass_first_device_err(UCLASS_IRQ, &itss); + if (ret) + return log_msg_ret("no itss", ret); + /* Restore GPIO IRQ polarities back to previous settings */ + irq_restore_polarities(itss); + + /* soc_init() */ + ret = p2sb_unhide(); + if (ret) + return log_msg_ret("unhide p2sb", ret); + + /* Set RAPL MSR for Package power limits*/ + ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev); + if (ret) + return log_msg_ret("Cannot get northbridge", ret); + set_power_limits(dev); + + /* + * FSP-S routes SCI to IRQ 9. With the help of this function you can + * select another IRQ for SCI. + */ + set_sci_irq(); + + return 0; +} diff --git a/arch/x86/cpu/apollolake/hostbridge.c b/arch/x86/cpu/apollolake/hostbridge.c new file mode 100644 index 0000000000..793853d5b5 --- /dev/null +++ b/arch/x86/cpu/apollolake/hostbridge.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <dt-structs.h> +#include <spl.h> +#include <asm/intel_pinctrl.h> +#include <asm/intel_regs.h> +#include <asm/pci.h> +#include <asm/arch/systemagent.h> + +/** + * struct apl_hostbridge_platdata - platform data for hostbridge + * + * @dtplat: Platform data for of-platdata + * @early_pads: Early pad data to set up, each (pad, cfg0, cfg1) + * @early_pads_count: Number of pads to process + * @pciex_region_size: BAR length in bytes + * @bdf: Bus/device/function of hostbridge + */ +struct apl_hostbridge_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_intel_apl_hostbridge dtplat; +#endif + u32 *early_pads; + int early_pads_count; + uint pciex_region_size; + pci_dev_t bdf; +}; + +enum { + PCIEXBAR = 0x60, + PCIEXBAR_LENGTH_256MB = 0, + PCIEXBAR_LENGTH_128MB, + PCIEXBAR_LENGTH_64MB, + + PCIEXBAR_PCIEXBAREN = 1 << 0, + + TSEG = 0xb8, /* TSEG base */ +}; + +static int apl_hostbridge_early_init_pinctrl(struct udevice *dev) +{ + struct apl_hostbridge_platdata *plat = dev_get_platdata(dev); + struct udevice *pinctrl; + int ret; + + ret = uclass_first_device_err(UCLASS_PINCTRL, &pinctrl); + if (ret) + return log_msg_ret("no hostbridge pinctrl", ret); + + return pinctrl_config_pads(pinctrl, plat->early_pads, + plat->early_pads_count); +} + +static int apl_hostbridge_early_init(struct udevice *dev) +{ + struct apl_hostbridge_platdata *plat = dev_get_platdata(dev); + u32 region_size; + ulong base; + u32 reg; + int ret; + + /* Set up the MCHBAR */ + pci_x86_read_config(plat->bdf, MCHBAR, &base, PCI_SIZE_32); + base = MCH_BASE_ADDRESS; + pci_x86_write_config(plat->bdf, MCHBAR, base | 1, PCI_SIZE_32); + + /* + * The PCIEXBAR is assumed to live in the memory mapped IO space under + * 4GiB + */ + pci_x86_write_config(plat->bdf, PCIEXBAR + 4, 0, PCI_SIZE_32); + + switch (plat->pciex_region_size >> 20) { + default: + case 256: + region_size = PCIEXBAR_LENGTH_256MB; + break; + case 128: + region_size = PCIEXBAR_LENGTH_128MB; + break; + case 64: + region_size = PCIEXBAR_LENGTH_64MB; + break; + } + + reg = CONFIG_MMCONF_BASE_ADDRESS | (region_size << 1) + | PCIEXBAR_PCIEXBAREN; + pci_x86_write_config(plat->bdf, PCIEXBAR, reg, PCI_SIZE_32); + + /* + * TSEG defines the base of SMM range. BIOS determines the base + * of TSEG memory which must be at or below Graphics base of GTT + * Stolen memory, hence its better to clear TSEG register early + * to avoid power on default non-zero value (if any). + */ + pci_x86_write_config(plat->bdf, TSEG, 0, PCI_SIZE_32); + + ret = apl_hostbridge_early_init_pinctrl(dev); + if (ret) + return log_msg_ret("pinctrl", ret); + + return 0; +} + +static int apl_hostbridge_ofdata_to_platdata(struct udevice *dev) +{ + struct apl_hostbridge_platdata *plat = dev_get_platdata(dev); + struct udevice *pinctrl; + int ret; + + /* + * The host bridge holds the early pad data needed to get through TPL. + * This is a small amount of data, enough to fit in TPL, so we keep it + * separate from the full pad data, stored in the fsp-s subnode. That + * subnode is not present in TPL, to save space. + */ + ret = uclass_first_device_err(UCLASS_PINCTRL, &pinctrl); + if (ret) + return log_msg_ret("no hostbridge PINCTRL", ret); +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + int root; + + /* Get length of PCI Express Region */ + plat->pciex_region_size = dev_read_u32_default(dev, "pciex-region-size", + 256 << 20); + + root = pci_get_devfn(dev); + if (root < 0) + return log_msg_ret("Cannot get host-bridge PCI address", root); + plat->bdf = root; + + ret = pinctrl_read_pads(pinctrl, dev_ofnode(dev), "early-pads", + &plat->early_pads, &plat->early_pads_count); + if (ret) + return log_msg_ret("early-pads", ret); +#else + struct dtd_intel_apl_hostbridge *dtplat = &plat->dtplat; + int size; + + plat->pciex_region_size = dtplat->pciex_region_size; + plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]); + + /* Assume that if everything is 0, it is empty */ + plat->early_pads = dtplat->early_pads; + size = ARRAY_SIZE(dtplat->early_pads); + plat->early_pads_count = pinctrl_count_pads(pinctrl, plat->early_pads, + size); + +#endif + + return 0; +} + +static int apl_hostbridge_probe(struct udevice *dev) +{ + if (spl_phase() == PHASE_TPL) + return apl_hostbridge_early_init(dev); + + return 0; +} + +static const struct udevice_id apl_hostbridge_ids[] = { + { .compatible = "intel,apl-hostbridge" }, + { } +}; + +U_BOOT_DRIVER(apl_hostbridge_drv) = { + .name = "intel_apl_hostbridge", + .id = UCLASS_NORTHBRIDGE, + .of_match = apl_hostbridge_ids, + .ofdata_to_platdata = apl_hostbridge_ofdata_to_platdata, + .probe = apl_hostbridge_probe, + .platdata_auto_alloc_size = sizeof(struct apl_hostbridge_platdata), +}; diff --git a/arch/x86/cpu/apollolake/itss.c b/arch/x86/cpu/apollolake/itss.c new file mode 100644 index 0000000000..8789f8e6bb --- /dev/null +++ b/arch/x86/cpu/apollolake/itss.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Something to do with Interrupts, but I don't know what ITSS stands for + * + * Copyright (C) 2017 Intel Corporation. + * Copyright (C) 2017 Siemens AG + * Copyright 2019 Google LLC + * + * Taken from coreboot itss.c + */ + +#include <common.h> +#include <dm.h> +#include <dt-structs.h> +#include <irq.h> +#include <p2sb.h> +#include <spl.h> +#include <asm/arch/itss.h> + +struct apl_itss_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + /* Put this first since driver model will copy the data here */ + struct dtd_intel_apl_itss dtplat; +#endif +}; + +/* struct pmc_route - Routing for PMC to GPIO */ +struct pmc_route { + u32 pmc; + u32 gpio; +}; + +struct apl_itss_priv { + struct pmc_route *route; + uint route_count; + u32 irq_snapshot[NUM_IPC_REGS]; +}; + +static int apl_set_polarity(struct udevice *dev, uint irq, bool active_low) +{ + u32 mask; + uint reg; + + if (irq > ITSS_MAX_IRQ) + return -EINVAL; + + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * (irq / IRQS_PER_IPC); + mask = 1 << (irq % IRQS_PER_IPC); + + pcr_clrsetbits32(dev, reg, mask, active_low ? mask : 0); + + return 0; +} + +#ifndef CONFIG_TPL_BUILD +static int apl_snapshot_polarities(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + const int start = GPIO_IRQ_START; + const int end = GPIO_IRQ_END; + int reg_start; + int reg_end; + int i; + + reg_start = start / IRQS_PER_IPC; + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; + + for (i = reg_start; i < reg_end; i++) { + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + + priv->irq_snapshot[i] = pcr_read32(dev, reg); + } + + return 0; +} + +static void show_polarities(struct udevice *dev, const char *msg) +{ + int i; + + log_info("ITSS IRQ Polarities %s:\n", msg); + for (i = 0; i < NUM_IPC_REGS; i++) { + uint reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + + log_info("IPC%d: 0x%08x\n", i, pcr_read32(dev, reg)); + } +} + +static int apl_restore_polarities(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + const int start = GPIO_IRQ_START; + const int end = GPIO_IRQ_END; + int reg_start; + int reg_end; + int i; + + show_polarities(dev, "Before"); + + reg_start = start / IRQS_PER_IPC; + reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC; + + for (i = reg_start; i < reg_end; i++) { + u32 mask; + u16 reg; + int irq_start; + int irq_end; + + irq_start = i * IRQS_PER_IPC; + irq_end = min(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ); + + if (start > irq_end) + continue; + if (end < irq_start) + break; + + /* Track bits within the bounds of of the register */ + irq_start = max(start, irq_start) % IRQS_PER_IPC; + irq_end = min(end, irq_end) % IRQS_PER_IPC; + + /* Create bitmask of the inclusive range of start and end */ + mask = (((1U << irq_end) - 1) | (1U << irq_end)); + mask &= ~((1U << irq_start) - 1); + + reg = PCR_ITSS_IPC0_CONF + sizeof(u32) * i; + pcr_clrsetbits32(dev, reg, mask, mask & priv->irq_snapshot[i]); + } + + show_polarities(dev, "After"); + + return 0; +} +#endif + +static int apl_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + struct pmc_route *route; + int i; + + for (i = 0, route = priv->route; i < priv->route_count; i++, route++) { + if (pmc_gpe_num == route->pmc) + return route->gpio; + } + + return -ENOENT; +} + +static int apl_itss_ofdata_to_platdata(struct udevice *dev) +{ + struct apl_itss_priv *priv = dev_get_priv(dev); + int ret; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct apl_itss_platdata *plat = dev_get_platdata(dev); + struct dtd_intel_apl_itss *dtplat = &plat->dtplat; + + /* + * It would be nice to do this in the bind() method, but with + * of-platdata binding happens in the order that DM finds things in the + * linker list (i.e. alphabetical order by driver name). So the GPIO + * device may well be bound before its parent (p2sb), and this call + * will fail if p2sb is not bound yet. + * + * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc + */ + ret = p2sb_set_port_id(dev, dtplat->intel_p2sb_port_id); + if (ret) + return log_msg_ret("Could not set port id", ret); + priv->route = (struct pmc_route *)dtplat->intel_pmc_routes; + priv->route_count = ARRAY_SIZE(dtplat->intel_pmc_routes) / + sizeof(struct pmc_route); +#else + int size; + + size = dev_read_size(dev, "intel,pmc-routes"); + if (size < 0) + return size; + priv->route = malloc(size); + if (!priv->route) + return -ENOMEM; + ret = dev_read_u32_array(dev, "intel,pmc-routes", (u32 *)priv->route, + size / sizeof(fdt32_t)); + if (ret) + return log_msg_ret("Cannot read pmc-routes", ret); + priv->route_count = size / sizeof(struct pmc_route); +#endif + + return 0; +} + +static const struct irq_ops apl_itss_ops = { + .route_pmc_gpio_gpe = apl_route_pmc_gpio_gpe, + .set_polarity = apl_set_polarity, +#ifndef CONFIG_TPL_BUILD + .snapshot_polarities = apl_snapshot_polarities, + .restore_polarities = apl_restore_polarities, +#endif +}; + +static const struct udevice_id apl_itss_ids[] = { + { .compatible = "intel,apl-itss"}, + { } +}; + +U_BOOT_DRIVER(apl_itss_drv) = { + .name = "intel_apl_itss", + .id = UCLASS_IRQ, + .of_match = apl_itss_ids, + .ops = &apl_itss_ops, + .ofdata_to_platdata = apl_itss_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct apl_itss_platdata), + .priv_auto_alloc_size = sizeof(struct apl_itss_priv), +}; diff --git a/arch/x86/cpu/apollolake/lpc.c b/arch/x86/cpu/apollolake/lpc.c new file mode 100644 index 0000000000..45b2144fc6 --- /dev/null +++ b/arch/x86/cpu/apollolake/lpc.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + * + * From coreboot Apollo Lake support lpc.c + */ + +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <asm/lpc_common.h> +#include <asm/pci.h> +#include <asm/arch/iomap.h> +#include <asm/arch/lpc.h> +#include <linux/log2.h> + +void lpc_enable_fixed_io_ranges(uint io_enables) +{ + pci_x86_clrset_config(PCH_DEV_LPC, LPC_IO_ENABLES, 0, io_enables, + PCI_SIZE_16); +} + +/* + * Find the first unused IO window. + * Returns -1 if not found, 0 for reg 0x84, 1 for reg 0x88 ... + */ +static int find_unused_pmio_window(void) +{ + int i; + ulong lgir; + + for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) { + pci_x86_read_config(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i), + &lgir, PCI_SIZE_32); + + if (!(lgir & LPC_LGIR_EN)) + return i; + } + + return -1; +} + +int lpc_open_pmio_window(uint base, uint size) +{ + int i, lgir_reg_num; + u32 lgir_reg_offset, lgir, window_size, alignment; + ulong bridged_size, bridge_base; + ulong reg; + + log_debug("LPC: Trying to open IO window from %x size %x\n", base, + size); + + bridged_size = 0; + bridge_base = base; + + while (bridged_size < size) { + /* Each IO range register can only open a 256-byte window */ + window_size = min(size, (uint)LPC_LGIR_MAX_WINDOW_SIZE); + + /* Window size must be a power of two for the AMASK to work */ + alignment = 1UL << (order_base_2(window_size)); + window_size = ALIGN(window_size, alignment); + + /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18] */ + lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN; + lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK; + + /* Skip programming if same range already programmed */ + for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) { + pci_x86_read_config(PCH_DEV_LPC, + LPC_GENERIC_IO_RANGE(i), ®, + PCI_SIZE_32); + if (lgir == reg) + return -EALREADY; + } + + lgir_reg_num = find_unused_pmio_window(); + if (lgir_reg_num < 0) { + log_err("LPC: Cannot open IO window: %lx size %lx\n", + bridge_base, size - bridged_size); + log_err("No more IO windows\n"); + + return -ENOSPC; + } + lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num); + + pci_x86_write_config(PCH_DEV_LPC, lgir_reg_offset, lgir, + PCI_SIZE_32); + + log_debug("LPC: Opened IO window LGIR%d: base %lx size %x\n", + lgir_reg_num, bridge_base, window_size); + + bridged_size += window_size; + bridge_base += window_size; + } + + return 0; +} + +void lpc_io_setup_comm_a_b(void) +{ + /* ComA Range 3F8h-3FFh [2:0] */ + u16 com_ranges = LPC_IOD_COMA_RANGE; + u16 com_enable = LPC_IOE_COMA_EN; + + /* Setup I/O Decode Range Register for LPC */ + pci_write_config16(PCH_DEV_LPC, LPC_IO_DECODE, com_ranges); + /* Enable ComA and ComB Port */ + lpc_enable_fixed_io_ranges(com_enable); +} + +static const struct udevice_id apl_lpc_ids[] = { + { .compatible = "intel,apl-lpc" }, + { } +}; + +/* All pads are LPC already configured by the hostbridge, so no probing here */ +U_BOOT_DRIVER(apl_lpc_drv) = { + .name = "intel_apl_lpc", + .id = UCLASS_LPC, + .of_match = apl_lpc_ids, +}; diff --git a/arch/x86/cpu/apollolake/p2sb.c b/arch/x86/cpu/apollolake/p2sb.c new file mode 100644 index 0000000000..eb27861b7a --- /dev/null +++ b/arch/x86/cpu/apollolake/p2sb.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Primary-to-Sideband Bridge + * + * Copyright 2019 Google LLC + */ + +#define LOG_CATEGORY UCLASS_P2SB + +#include <common.h> +#include <dm.h> +#include <dt-structs.h> +#include <p2sb.h> +#include <spl.h> +#include <asm/pci.h> + +struct p2sb_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_intel_apl_p2sb dtplat; +#endif + ulong mmio_base; + pci_dev_t bdf; +}; + +/* PCI config space registers */ +#define HPTC_OFFSET 0x60 +#define HPTC_ADDR_ENABLE_BIT BIT(7) + +/* High Performance Event Timer Configuration */ +#define P2SB_HPTC 0x60 +#define P2SB_HPTC_ADDRESS_ENABLE BIT(7) + +/* + * ADDRESS_SELECT ENCODING_RANGE + * 0 0xfed0 0000 - 0xfed0 03ff + * 1 0xfed0 1000 - 0xfed0 13ff + * 2 0xfed0 2000 - 0xfed0 23ff + * 3 0xfed0 3000 - 0xfed0 33ff + */ +#define P2SB_HPTC_ADDRESS_SELECT_0 (0 << 0) +#define P2SB_HPTC_ADDRESS_SELECT_1 (1 << 0) +#define P2SB_HPTC_ADDRESS_SELECT_2 (2 << 0) +#define P2SB_HPTC_ADDRESS_SELECT_3 (3 << 0) + +/* + * apl_p2sb_early_init() - Enable decoding for HPET range + * + * This is needed by FSP-M which uses the High Precision Event Timer. + * + * @dev: P2SB device + * @return 0 if OK, -ve on error + */ +static int apl_p2sb_early_init(struct udevice *dev) +{ + struct p2sb_platdata *plat = dev_get_platdata(dev); + pci_dev_t pdev = plat->bdf; + + /* + * Enable decoding for HPET memory address range. + * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode + * the High Performance Timer memory address range + * selected by bits 1:0 + */ + pci_x86_write_config(pdev, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT, + PCI_SIZE_8); + + /* Enable PCR Base address in PCH */ + pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0, plat->mmio_base, + PCI_SIZE_32); + pci_x86_write_config(pdev, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32); + + /* Enable P2SB MSE */ + pci_x86_write_config(pdev, PCI_COMMAND, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY, PCI_SIZE_8); + + return 0; +} + +static int apl_p2sb_spl_init(struct udevice *dev) +{ + /* Enable decoding for HPET. Needed for FSP global pointer storage */ + dm_pci_write_config(dev, P2SB_HPTC, P2SB_HPTC_ADDRESS_SELECT_0 | + P2SB_HPTC_ADDRESS_ENABLE, PCI_SIZE_8); + + return 0; +} + +int apl_p2sb_ofdata_to_platdata(struct udevice *dev) +{ + struct p2sb_uc_priv *upriv = dev_get_uclass_priv(dev); + struct p2sb_platdata *plat = dev_get_platdata(dev); + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + int ret; + + if (spl_phase() == PHASE_TPL) { + u32 base[2]; + + /* TPL sets up the initial BAR */ + ret = dev_read_u32_array(dev, "early-regs", base, + ARRAY_SIZE(base)); + if (ret) + return log_msg_ret("Missing/short early-regs", ret); + plat->mmio_base = base[0]; + plat->bdf = pci_get_devfn(dev); + if (plat->bdf < 0) + return log_msg_ret("Cannot get p2sb PCI address", + plat->bdf); + } else { + plat->mmio_base = dev_read_addr_pci(dev); + /* Don't set BDF since it should not be used */ + if (!plat->mmio_base || plat->mmio_base == FDT_ADDR_T_NONE) + return -EINVAL; + } +#else + plat->mmio_base = plat->dtplat.early_regs[0]; + plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]); +#endif + upriv->mmio_base = plat->mmio_base; + debug("p2sb: mmio_base=%x\n", (uint)plat->mmio_base); + + return 0; +} + +static int apl_p2sb_probe(struct udevice *dev) +{ + if (spl_phase() == PHASE_TPL) + return apl_p2sb_early_init(dev); + else if (spl_phase() == PHASE_SPL) + return apl_p2sb_spl_init(dev); + + return 0; +} + +static int p2sb_child_post_bind(struct udevice *dev) +{ +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + int ret; + u32 pid; + + ret = dev_read_u32(dev, "intel,p2sb-port-id", &pid); + if (ret) + return ret; + pplat->pid = pid; +#endif + + return 0; +} + +static const struct udevice_id apl_p2sb_ids[] = { + { .compatible = "intel,apl-p2sb" }, + { } +}; + +U_BOOT_DRIVER(apl_p2sb_drv) = { + .name = "intel_apl_p2sb", + .id = UCLASS_P2SB, + .of_match = apl_p2sb_ids, + .probe = apl_p2sb_probe, + .ofdata_to_platdata = apl_p2sb_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct p2sb_platdata), + .per_child_platdata_auto_alloc_size = + sizeof(struct p2sb_child_platdata), + .child_post_bind = p2sb_child_post_bind, +}; diff --git a/arch/x86/cpu/apollolake/pch.c b/arch/x86/cpu/apollolake/pch.c new file mode 100644 index 0000000000..1a5a985221 --- /dev/null +++ b/arch/x86/cpu/apollolake/pch.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <pch.h> +#include <spl.h> +#include <asm/lpc_common.h> + +#define BIOS_CTRL 0xdc + +static int apl_set_spi_protect(struct udevice *dev, bool protect) +{ + if (spl_phase() == PHASE_SPL) + return lpc_set_spi_protect(dev, BIOS_CTRL, protect); + + return 0; +} + +static const struct pch_ops apl_pch_ops = { + .set_spi_protect = apl_set_spi_protect, +}; + +static const struct udevice_id apl_pch_ids[] = { + { .compatible = "intel,apl-pch" }, + { } +}; + +U_BOOT_DRIVER(apl_pch) = { + .name = "apl_pch", + .id = UCLASS_PCH, + .of_match = apl_pch_ids, + .ops = &apl_pch_ops, +}; diff --git a/arch/x86/cpu/apollolake/pmc.c b/arch/x86/cpu/apollolake/pmc.c new file mode 100644 index 0000000000..683c6082f2 --- /dev/null +++ b/arch/x86/cpu/apollolake/pmc.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Intel Corporation. + * Copyright 2019 Google LLC + * + * Modified from coreboot pmclib.c, pmc.c and pmutil.c + */ + +#define LOG_CATEGORY UCLASS_ACPI_PMC + +#include <common.h> +#include <acpi_s3.h> +#include <dt-structs.h> +#include <dm.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <power/acpi_pmc.h> + +#define GPIO_GPE_CFG 0x1050 + +/* Memory mapped IO registers behind PMC_BASE_ADDRESS */ +#define PRSTS 0x1000 +#define GEN_PMCON1 0x1020 +#define COLD_BOOT_STS BIT(27) +#define COLD_RESET_STS BIT(26) +#define WARM_RESET_STS BIT(25) +#define GLOBAL_RESET_STS BIT(24) +#define SRS BIT(20) +#define MS4V BIT(18) +#define RPS BIT(2) +#define GEN_PMCON1_CLR1_BITS (COLD_BOOT_STS | COLD_RESET_STS | \ + WARM_RESET_STS | GLOBAL_RESET_STS | \ + SRS | MS4V) +#define GEN_PMCON2 0x1024 +#define GEN_PMCON3 0x1028 + +/* Offset of TCO registers from ACPI base I/O address */ +#define TCO_REG_OFFSET 0x60 +#define TCO1_STS 0x64 +#define DMISCI_STS BIT(9) +#define BOOT_STS BIT(18) +#define TCO2_STS 0x66 +#define TCO1_CNT 0x68 +#define TCO_LOCK BIT(12) +#define TCO2_CNT 0x6a + +enum { + ETR = 0x1048, + CF9_LOCK = 1UL << 31, + CF9_GLB_RST = 1 << 20, +}; + +struct apl_pmc_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_intel_apl_pmc dtplat; +#endif + pci_dev_t bdf; +}; + +static int apl_pmc_fill_power_state(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + upriv->tco1_sts = inw(upriv->acpi_base + TCO1_STS); + upriv->tco2_sts = inw(upriv->acpi_base + TCO2_STS); + + upriv->prsts = readl(upriv->pmc_bar0 + PRSTS); + upriv->gen_pmcon1 = readl(upriv->pmc_bar0 + GEN_PMCON1); + upriv->gen_pmcon2 = readl(upriv->pmc_bar0 + GEN_PMCON2); + upriv->gen_pmcon3 = readl(upriv->pmc_bar0 + GEN_PMCON3); + + return 0; +} + +static int apl_prev_sleep_state(struct udevice *dev, int prev_sleep_state) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + /* WAK_STS bit will not be set when waking from G3 state */ + if (!(upriv->pm1_sts & WAK_STS) && + (upriv->gen_pmcon1 & COLD_BOOT_STS)) + prev_sleep_state = ACPI_S5; + + return prev_sleep_state; +} + +static int apl_disable_tco(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + pmc_disable_tco_base(upriv->acpi_base + TCO_REG_OFFSET); + + return 0; +} + +static int apl_global_reset_set_enable(struct udevice *dev, bool enable) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + if (enable) + setbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST); + else + clrbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST); + + return 0; +} + +int apl_pmc_ofdata_to_uc_platdata(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + struct apl_pmc_platdata *plat = dev_get_platdata(dev); + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + u32 base[6]; + int size; + int ret; + + ret = dev_read_u32_array(dev, "early-regs", base, ARRAY_SIZE(base)); + if (ret) + return log_msg_ret("Missing/short early-regs", ret); + upriv->pmc_bar0 = (void *)base[0]; + upriv->pmc_bar2 = (void *)base[2]; + upriv->acpi_base = base[4]; + + /* Since PCI is not enabled, we must get the BDF manually */ + plat->bdf = pci_get_devfn(dev); + if (plat->bdf < 0) + return log_msg_ret("Cannot get PMC PCI address", plat->bdf); + + /* Get the dwX values for pmc gpe settings */ + size = dev_read_size(dev, "gpe0-dw"); + if (size < 0) + return log_msg_ret("Cannot read gpe0-dm", size); + upriv->gpe0_count = size / sizeof(u32); + ret = dev_read_u32_array(dev, "gpe0-dw", upriv->gpe0_dw, + upriv->gpe0_count); + if (ret) + return log_msg_ret("Bad gpe0-dw", ret); + + return pmc_ofdata_to_uc_platdata(dev); +#else + struct dtd_intel_apl_pmc *dtplat = &plat->dtplat; + + plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]); + upriv->pmc_bar0 = (void *)dtplat->early_regs[0]; + upriv->pmc_bar2 = (void *)dtplat->early_regs[2]; + upriv->acpi_base = dtplat->early_regs[4]; + upriv->gpe0_dwx_mask = dtplat->gpe0_dwx_mask; + upriv->gpe0_dwx_shift_base = dtplat->gpe0_dwx_shift_base; + upriv->gpe0_sts_reg = dtplat->gpe0_sts; + upriv->gpe0_sts_reg += upriv->acpi_base; + upriv->gpe0_en_reg = dtplat->gpe0_en; + upriv->gpe0_en_reg += upriv->acpi_base; + upriv->gpe0_count = min((int)ARRAY_SIZE(dtplat->gpe0_dw), GPE0_REG_MAX); + memcpy(upriv->gpe0_dw, dtplat->gpe0_dw, sizeof(dtplat->gpe0_dw)); +#endif + upriv->gpe_cfg = (u32 *)(upriv->pmc_bar0 + GPIO_GPE_CFG); + + return 0; +} + +static int enable_pmcbar(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + struct apl_pmc_platdata *priv = dev_get_platdata(dev); + pci_dev_t pmc = priv->bdf; + + /* + * Set PMC base addresses and enable decoding. BARs 1 and 3 are 64-bit + * BARs. + */ + pci_x86_write_config(pmc, PCI_BASE_ADDRESS_0, (ulong)upriv->pmc_bar0, + PCI_SIZE_32); + pci_x86_write_config(pmc, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32); + pci_x86_write_config(pmc, PCI_BASE_ADDRESS_2, (ulong)upriv->pmc_bar2, + PCI_SIZE_32); + pci_x86_write_config(pmc, PCI_BASE_ADDRESS_3, 0, PCI_SIZE_32); + pci_x86_write_config(pmc, PCI_BASE_ADDRESS_4, upriv->acpi_base, + PCI_SIZE_16); + pci_x86_write_config(pmc, PCI_COMMAND, PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, + PCI_SIZE_16); + + return 0; +} + +static int apl_pmc_probe(struct udevice *dev) +{ + if (spl_phase() == PHASE_TPL) + return enable_pmcbar(dev); + + return 0; +} + +static struct acpi_pmc_ops apl_pmc_ops = { + .init = apl_pmc_fill_power_state, + .prev_sleep_state = apl_prev_sleep_state, + .disable_tco = apl_disable_tco, + .global_reset_set_enable = apl_global_reset_set_enable, +}; + +static const struct udevice_id apl_pmc_ids[] = { + { .compatible = "intel,apl-pmc" }, + { } +}; + +U_BOOT_DRIVER(apl_pmc) = { + .name = "intel_apl_pmc", + .id = UCLASS_ACPI_PMC, + .of_match = apl_pmc_ids, + .ofdata_to_platdata = apl_pmc_ofdata_to_uc_platdata, + .probe = apl_pmc_probe, + .ops = &apl_pmc_ops, + .platdata_auto_alloc_size = sizeof(struct apl_pmc_platdata), +}; diff --git a/arch/x86/cpu/apollolake/punit.c b/arch/x86/cpu/apollolake/punit.c new file mode 100644 index 0000000000..1a131fb0b1 --- /dev/null +++ b/arch/x86/cpu/apollolake/punit.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <asm/cpu.h> +#include <asm/cpu_common.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/arch/systemagent.h> + +/* + * Punit Initialisation code. This all isn't documented, but + * this is the recipe. + */ +static int punit_init(struct udevice *dev) +{ + struct udevice *cpu; + u32 reg; + ulong start; + int ret; + + /* Thermal throttle activation offset */ + ret = uclass_first_device_err(UCLASS_CPU, &cpu); + if (ret) + return log_msg_ret("Cannot find CPU", ret); + cpu_configure_thermal_target(cpu); + + /* + * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR). + * Enable all cores here. + */ + writel(0, MCHBAR_REG(CORE_DISABLE_MASK)); + + /* P-Unit bring up */ + reg = readl(MCHBAR_REG(BIOS_RESET_CPL)); + if (reg == 0xffffffff) { + /* P-unit not found */ + debug("Punit MMIO not available\n"); + return -ENOENT; + } + + /* Set Punit interrupt pin IPIN offset 3D */ + dm_pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x2); + + /* Set PUINT IRQ to 24 and INTPIN LOCK */ + writel(PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER | + PUINT_THERMAL_DEVICE_IRQ_LOCK, + MCHBAR_REG(PUNIT_THERMAL_DEVICE_IRQ)); + + /* Stage0 BIOS Reset Complete (RST_CPL) */ + enable_bios_reset_cpl(); + + /* + * Poll for bit 8 to check if PCODE has completed its action in response + * to BIOS Reset complete. We wait here till 1 ms for the bit to get + * set. + */ + start = get_timer(0); + while (!(readl(MCHBAR_REG(BIOS_RESET_CPL)) & PCODE_INIT_DONE)) { + if (get_timer(start) > 1) { + debug("PCODE Init Done timeout\n"); + return -ETIMEDOUT; + } + udelay(100); + } + debug("PUNIT init complete\n"); + + return 0; +} + +static int apl_punit_probe(struct udevice *dev) +{ + if (spl_phase() == PHASE_SPL) + return punit_init(dev); + + return 0; +} + +static const struct udevice_id apl_syscon_ids[] = { + { .compatible = "intel,apl-punit", .data = X86_SYSCON_PUNIT }, + { } +}; + +U_BOOT_DRIVER(syscon_intel_punit) = { + .name = "intel_punit_syscon", + .id = UCLASS_SYSCON, + .of_match = apl_syscon_ids, + .probe = apl_punit_probe, +}; diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c new file mode 100644 index 0000000000..7ab7243311 --- /dev/null +++ b/arch/x86/cpu/apollolake/spl.c @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <binman_sym.h> +#include <dm.h> +#include <spi.h> +#include <spl.h> +#include <spi_flash.h> +#include <asm/fast_spi.h> +#include <asm/spl.h> +#include <asm/arch/cpu.h> +#include <asm/arch/iomap.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> + +/* This reads the next phase from mapped SPI flash */ +static int rom_load_image(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev) +{ + ulong spl_pos = spl_get_image_pos(); + ulong spl_size = spl_get_image_size(); + struct udevice *dev; + ulong map_base; + size_t map_size; + uint offset; + int ret; + + spl_image->size = CONFIG_SYS_MONITOR_LEN; /* We don't know SPL size */ + spl_image->entry_point = spl_phase() == PHASE_TPL ? + CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE; + spl_image->load_addr = spl_image->entry_point; + spl_image->os = IH_OS_U_BOOT; + spl_image->name = "U-Boot"; + debug("Reading from mapped SPI %lx, size %lx", spl_pos, spl_size); + + if (CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT)) { + ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev); + if (ret) + return log_msg_ret("spi_flash", ret); + if (!dev) + return log_msg_ret("spi_flash dev", -ENODEV); + ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); + if (ret) + return log_msg_ret("mmap", ret); + } else { + ret = fast_spi_get_bios_mmap(PCH_DEV_SPI, &map_base, &map_size, + &offset); + if (ret) + return ret; + } + spl_pos += map_base & ~0xff000000; + debug(", base %lx, pos %lx\n", map_base, spl_pos); + bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi"); + memcpy((void *)spl_image->load_addr, (void *)spl_pos, spl_size); + cpu_flush_l1d_to_l2(); + bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI); + + return 0; +} +SPL_LOAD_IMAGE_METHOD("Mapped SPI", 2, BOOT_DEVICE_SPI_MMAP, rom_load_image); + +#if CONFIG_IS_ENABLED(SPI_FLASH_SUPPORT) + +static int apl_flash_std_read(struct udevice *dev, u32 offset, size_t len, + void *buf) +{ + struct spi_flash *flash = dev_get_uclass_priv(dev); + struct mtd_info *mtd = &flash->mtd; + size_t retlen; + + return log_ret(mtd->_read(mtd, offset, len, &retlen, buf)); +} + +static int apl_flash_probe(struct udevice *dev) +{ + return spi_flash_std_probe(dev); +} + +/* + * Manually set the parent of the SPI flash to SPI, since dtoc doesn't. We also + * need to allocate the parent_platdata since by the time this function is + * called device_bind() has already gone past that step. + */ +static int apl_flash_bind(struct udevice *dev) +{ + if (CONFIG_IS_ENABLED(OF_PLATDATA)) { + struct dm_spi_slave_platdata *plat; + struct udevice *spi; + int ret; + + ret = uclass_first_device_err(UCLASS_SPI, &spi); + if (ret) + return ret; + dev->parent = spi; + + plat = calloc(sizeof(*plat), 1); + if (!plat) + return -ENOMEM; + dev->parent_platdata = plat; + } + + return 0; +} + +static const struct dm_spi_flash_ops apl_flash_ops = { + .read = apl_flash_std_read, +}; + +static const struct udevice_id apl_flash_ids[] = { + { .compatible = "jedec,spi-nor" }, + { } +}; + +U_BOOT_DRIVER(winbond_w25q128fw) = { + .name = "winbond_w25q128fw", + .id = UCLASS_SPI_FLASH, + .of_match = apl_flash_ids, + .bind = apl_flash_bind, + .probe = apl_flash_probe, + .priv_auto_alloc_size = sizeof(struct spi_flash), + .ops = &apl_flash_ops, +}; + +/* This uses a SPI flash device to read the next phase */ +static int spl_fast_spi_load_image(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev) +{ + ulong spl_pos = spl_get_image_pos(); + ulong spl_size = spl_get_image_size(); + struct udevice *dev; + int ret; + + ret = uclass_first_device_err(UCLASS_SPI_FLASH, &dev); + if (ret) + return ret; + + spl_image->size = CONFIG_SYS_MONITOR_LEN; /* We don't know SPL size */ + spl_image->entry_point = spl_phase() == PHASE_TPL ? + CONFIG_SPL_TEXT_BASE : CONFIG_SYS_TEXT_BASE; + spl_image->load_addr = spl_image->entry_point; + spl_image->os = IH_OS_U_BOOT; + spl_image->name = "U-Boot"; + spl_pos &= ~0xff000000; + debug("Reading from flash %lx, size %lx\n", spl_pos, spl_size); + ret = spi_flash_read_dm(dev, spl_pos, spl_size, + (void *)spl_image->load_addr); + cpu_flush_l1d_to_l2(); + if (ret) + return ret; + + return 0; +} +SPL_LOAD_IMAGE_METHOD("Fast SPI", 1, BOOT_DEVICE_FAST_SPI, + spl_fast_spi_load_image); + +void board_boot_order(u32 *spl_boot_list) +{ + bool use_spi_flash = IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH); + + if (use_spi_flash) { + spl_boot_list[0] = BOOT_DEVICE_FAST_SPI; + spl_boot_list[1] = BOOT_DEVICE_SPI_MMAP; + } else { + spl_boot_list[0] = BOOT_DEVICE_SPI_MMAP; + spl_boot_list[1] = BOOT_DEVICE_FAST_SPI; + } +} + +#else + +void board_boot_order(u32 *spl_boot_list) +{ + spl_boot_list[0] = BOOT_DEVICE_SPI_MMAP; +} +#endif diff --git a/arch/x86/cpu/apollolake/systemagent.c b/arch/x86/cpu/apollolake/systemagent.c new file mode 100644 index 0000000000..b6bc2ba14f --- /dev/null +++ b/arch/x86/cpu/apollolake/systemagent.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Intel Corporation. + * Take from coreboot project file of the same name + */ + +#include <common.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/arch/systemagent.h> + +void enable_bios_reset_cpl(void) +{ + /* + * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU + * that BIOS has initialised memory and power management + * + * The FSP-S does not do this. If we leave this as zero then I believe + * the power-aware interrupts don't work in Linux, and CPU 0 always gets + * the interrupt. + */ + setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 3); +} diff --git a/arch/x86/cpu/apollolake/uart.c b/arch/x86/cpu/apollolake/uart.c new file mode 100644 index 0000000000..f2b356eb44 --- /dev/null +++ b/arch/x86/cpu/apollolake/uart.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Special driver to handle of-platdata + * + * Copyright 2019 Google LLC + * + * Some code from coreboot lpss.c + */ + +#include <common.h> +#include <dm.h> +#include <dt-structs.h> +#include <ns16550.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/lpss.h> + +/* Low-power Subsystem (LPSS) clock register */ +enum { + LPSS_CLOCK_CTL_REG = 0x200, + LPSS_CNT_CLOCK_EN = 1, + LPSS_CNT_CLK_UPDATE = 1U << 31, + LPSS_CLOCK_DIV_N_SHIFT = 16, + LPSS_CLOCK_DIV_N_MASK = 0x7fff << LPSS_CLOCK_DIV_N_SHIFT, + LPSS_CLOCK_DIV_M_SHIFT = 1, + LPSS_CLOCK_DIV_M_MASK = 0x7fff << LPSS_CLOCK_DIV_M_SHIFT, + + /* These set the UART input clock speed */ + LPSS_UART_CLK_M_VAL = 0x25a, + LPSS_UART_CLK_N_VAL = 0x7fff, +}; + +static void lpss_clk_update(void *regs, u32 clk_m_val, u32 clk_n_val) +{ + u32 clk_sel; + + clk_sel = clk_n_val << LPSS_CLOCK_DIV_N_SHIFT | + clk_m_val << LPSS_CLOCK_DIV_M_SHIFT; + clk_sel |= LPSS_CNT_CLK_UPDATE | LPSS_CNT_CLOCK_EN; + + writel(clk_sel, regs + LPSS_CLOCK_CTL_REG); +} + +static void uart_lpss_init(void *regs) +{ + /* Take UART out of reset */ + lpss_reset_release(regs); + + /* Set M and N divisor inputs and enable clock */ + lpss_clk_update(regs, LPSS_UART_CLK_M_VAL, LPSS_UART_CLK_N_VAL); +} + +void apl_uart_init(pci_dev_t bdf, ulong base) +{ + /* Set UART base address */ + pci_x86_write_config(bdf, PCI_BASE_ADDRESS_0, base, PCI_SIZE_32); + + /* Enable memory access and bus master */ + pci_x86_write_config(bdf, PCI_COMMAND, PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER, PCI_SIZE_32); + + uart_lpss_init((void *)base); +} + +/* + * This driver uses its own compatible string but almost everything else from + * the standard ns16550 driver. This allows us to provide an of-platdata + * implementation, since the platdata produced by of-platdata does not match + * struct ns16550_platdata. + * + * When running with of-platdata (generally TPL), the platdata is converted to + * something that ns16550 expects. When running withoutof-platdata (SPL, U-Boot + * proper), we use ns16550's ofdata_to_platdata routine. + */ + +static int apl_ns16550_probe(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + + if (!CONFIG_IS_ENABLED(PCI)) + apl_uart_init(plat->bdf, plat->base); + + return ns16550_serial_probe(dev); +} + +static int apl_ns16550_ofdata_to_platdata(struct udevice *dev) +{ +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_intel_apl_ns16550 *dtplat = dev_get_platdata(dev); + struct ns16550_platdata *plat; + + /* + * Convert our platdata to the ns16550's platdata, so we can just use + * that driver + */ + plat = malloc(sizeof(*plat)); + if (!plat) + return -ENOMEM; + plat->base = dtplat->early_regs[0]; + plat->reg_width = 1; + plat->reg_shift = dtplat->reg_shift; + plat->reg_offset = 0; + plat->clock = dtplat->clock_frequency; + plat->fcr = UART_FCR_DEFVAL; + plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]); + dev->platdata = plat; +#else + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; +#endif /* OF_PLATDATA */ + + return 0; +} + +static const struct udevice_id apl_ns16550_serial_ids[] = { + { .compatible = "intel,apl-ns16550" }, + { }, +}; + +U_BOOT_DRIVER(apl_ns16550) = { + .name = "intel_apl_ns16550", + .id = UCLASS_SERIAL, + .of_match = apl_ns16550_serial_ids, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .ops = &ns16550_serial_ops, + .ofdata_to_platdata = apl_ns16550_ofdata_to_platdata, + .probe = apl_ns16550_probe, +}; diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c index dfd8afc35f..15bfc5811c 100644 --- a/arch/x86/cpu/broadwell/sdram.c +++ b/arch/x86/cpu/broadwell/sdram.c @@ -83,7 +83,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data) struct mrc_region entry; int ret; - ret = mrccache_get_region(NULL, &entry); + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); if (ret) return ret; mrc_cache = mrccache_find_current(&entry); @@ -169,12 +169,14 @@ int dram_init(void) pei_data->data_to_save); /* S3 resume: don't save scrambler seed or MRC data */ if (pei_data->boot_mode != SLEEP_STATE_S3) { + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; + /* * This will be copied to SDRAM in reserve_arch(), then written * to SPI flash in mrccache_save() */ - gd->arch.mrc_output = (char *)pei_data->data_to_save; - gd->arch.mrc_output_len = pei_data->data_to_save_size; + mrc->buf = (char *)pei_data->data_to_save; + mrc->len = pei_data->data_to_save_size; } gd->arch.pei_meminfo = pei_data->meminfo; diff --git a/arch/x86/cpu/coreboot/Kconfig b/arch/x86/cpu/coreboot/Kconfig index 93f61f2fa4..c8e6a889d0 100644 --- a/arch/x86/cpu/coreboot/Kconfig +++ b/arch/x86/cpu/coreboot/Kconfig @@ -24,5 +24,6 @@ config SYS_COREBOOT imply CMD_CBFS imply FS_CBFS imply CBMEM_CONSOLE + imply X86_TSC_READ_BASE endif diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 4e59476fc9..d626e38fd1 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -46,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_TPL_BUILD static const char *const x86_vendor_name[] = { [X86_VENDOR_INTEL] = "Intel", [X86_VENDOR_CYRIX] = "Cyrix", @@ -58,6 +59,7 @@ static const char *const x86_vendor_name[] = { [X86_VENDOR_NSC] = "NSC", [X86_VENDOR_SIS] = "SiS", }; +#endif int __weak x86_cleanup_before_linux(void) { @@ -114,6 +116,7 @@ int icache_status(void) return 1; } +#ifndef CONFIG_TPL_BUILD const char *cpu_vendor_name(int vendor) { const char *name; @@ -124,6 +127,7 @@ const char *cpu_vendor_name(int vendor) return name; } +#endif char *cpu_get_name(char *name) { diff --git a/arch/x86/cpu/i386/Makefile b/arch/x86/cpu/i386/Makefile index 0c47252610..18e152074a 100644 --- a/arch/x86/cpu/i386/Makefile +++ b/arch/x86/cpu/i386/Makefile @@ -5,5 +5,7 @@ obj-y += call64.o obj-y += cpu.o +ifndef CONFIG_TPL_BUILD obj-y += interrupt.o +endif obj-y += setjmp.o diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index c66382bdd2..2b27617ca3 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -21,6 +21,7 @@ #include <common.h> #include <cpu_func.h> #include <malloc.h> +#include <spl.h> #include <asm/control_regs.h> #include <asm/cpu.h> #include <asm/mp.h> @@ -58,6 +59,8 @@ struct cpuinfo_x86 { uint8_t x86_mask; }; +/* gcc 7.3 does not wwant to drop x86_vendors, so use #ifdef */ +#ifndef CONFIG_TPL_BUILD /* * List of cpu vendor strings along with their normalized * id values. @@ -78,6 +81,7 @@ static const struct { { X86_VENDOR_NSC, "Geode by NSC", }, { X86_VENDOR_SIS, "SiS SiS SiS ", }, }; +#endif static void load_ds(u32 segment) { @@ -199,6 +203,7 @@ static inline int test_cyrix_52div(void) return (unsigned char) (test >> 8) == 0x02; } +#ifndef CONFIG_TPL_BUILD /* * Detect a NexGen CPU running without BIOS hypercode new enough * to have CPUID. (Thanks to Herbert Oppmann) @@ -219,6 +224,7 @@ static int deep_magic_nexgen_probe(void) : "=a" (ret) : : "cx", "dx"); return ret; } +#endif static bool has_cpuid(void) { @@ -230,6 +236,7 @@ static bool has_mtrr(void) return cpuid_edx(0x00000001) & (1 << 12) ? true : false; } +#ifndef CONFIG_TPL_BUILD static int build_vendor_name(char *vendor_name) { struct cpuid_result result; @@ -242,14 +249,40 @@ static int build_vendor_name(char *vendor_name) return result.eax; } +#endif static void identify_cpu(struct cpu_device_id *cpu) { + cpu->device = 0; /* fix gcc 4.4.4 warning */ + + /* + * Do a quick and dirty check to save space - Intel and AMD only and + * just the vendor. This is enough for most TPL code. + */ + if (spl_phase() == PHASE_TPL) { + struct cpuid_result result; + + result = cpuid(0x00000000); + switch (result.ecx >> 24) { + case 'l': /* GenuineIntel */ + cpu->vendor = X86_VENDOR_INTEL; + break; + case 'D': /* AuthenticAMD */ + cpu->vendor = X86_VENDOR_AMD; + break; + default: + cpu->vendor = X86_VENDOR_ANY; + break; + } + return; + } + +/* gcc 7.3 does not want to drop x86_vendors, so use #ifdef */ +#ifndef CONFIG_TPL_BUILD char vendor_name[16]; int i; vendor_name[0] = '\0'; /* Unset */ - cpu->device = 0; /* fix gcc 4.4.4 warning */ /* Find the id and vendor_name */ if (!has_cpuid()) { @@ -265,9 +298,8 @@ static void identify_cpu(struct cpu_device_id *cpu) /* Detect NexGen with old hypercode */ else if (deep_magic_nexgen_probe()) memcpy(vendor_name, "NexGenDriven", 13); - } - if (has_cpuid()) { - int cpuid_level; + } else { + int cpuid_level; cpuid_level = build_vendor_name(vendor_name); vendor_name[12] = '\0'; @@ -287,6 +319,7 @@ static void identify_cpu(struct cpu_device_id *cpu) break; } } +#endif } static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms) diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 07f27c29ec..cc4e1c962b 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -8,8 +8,18 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += me_status.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o endif + +ifdef CONFIG_INTEL_CAR_CQOS +obj-$(CONFIG_TPL_BUILD) += car2.o +ifndef CONFIG_SPL_BUILD +obj-y += car2_uninit.o +endif +endif + obj-y += cpu.o +obj-y += fast_spi.o obj-y += lpc.o +obj-y += lpss.o ifndef CONFIG_TARGET_EFI_APP obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o ifndef CONFIG_$(SPL_)X86_64 diff --git a/arch/x86/cpu/intel_common/car2.S b/arch/x86/cpu/intel_common/car2.S new file mode 100644 index 0000000000..086f987477 --- /dev/null +++ b/arch/x86/cpu/intel_common/car2.S @@ -0,0 +1,448 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This file was modified from the coreboot version. + * + * Copyright (C) 2015-2016 Intel Corp. + */ + +#include <config.h> +#include <asm/msr-index.h> +#include <asm/mtrr.h> +#include <asm/post.h> +#include <asm/processor.h> +#include <asm/processor-flags.h> + +#define KiB 1024 + +#define IS_POWER_OF_2(x) (!((x) & ((x) - 1))) + +.global car_init +car_init: + post_code(POST_CAR_START) + + /* + * Use the MTRR default type MSR as a proxy for detecting INIT#. + * Reset the system if any known bits are set in that MSR. That is + * an indication of the CPU not being properly reset. + */ +check_for_clean_reset: + mov $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + and $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax + cmp $0, %eax + jz no_reset + /* perform warm reset */ + movw $IO_PORT_RESET, %dx + movb $(SYS_RST | RST_CPU), %al + outb %al, %dx + +no_reset: + post_code(POST_CAR_SIPI) + + /* Clear/disable fixed MTRRs */ + mov $fixed_mtrr_list_size, %ebx + xor %eax, %eax + xor %edx, %edx + +clear_fixed_mtrr: + add $-2, %ebx + movzwl fixed_mtrr_list(%ebx), %ecx + wrmsr + jnz clear_fixed_mtrr + + post_code(POST_CAR_MTRR) + + /* Figure put how many MTRRs we have, and clear them out */ + mov $MTRR_CAP_MSR, %ecx + rdmsr + movzb %al, %ebx /* Number of variable MTRRs */ + mov $MTRR_PHYS_BASE_MSR(0), %ecx + xor %eax, %eax + xor %edx, %edx + +clear_var_mtrr: + wrmsr + inc %ecx + wrmsr + inc %ecx + dec %ebx + jnz clear_var_mtrr + + post_code(POST_CAR_UNCACHEABLE) + + /* Configure default memory type to uncacheable (UC) */ + mov $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + /* Clear enable bits and set default type to UC */ + and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \ + MTRR_DEF_TYPE_FIX_EN), %eax + wrmsr + + /* + * Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB + * based on the physical address size supported for this processor + * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0] + * + * Examples: + * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing + * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing + */ + + movl $0x80000008, %eax /* Address sizes leaf */ + cpuid + sub $32, %al + movzx %al, %eax + xorl %esi, %esi + bts %eax, %esi + dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */ + + post_code(POST_CAR_BASE_ADDRESS) + +#if IS_POWER_OF_2(CONFIG_DCACHE_RAM_SIZE) + /* Configure CAR region as write-back (WB) */ + mov $MTRR_PHYS_BASE_MSR(0), %ecx + mov $CONFIG_DCACHE_RAM_BASE, %eax + or $MTRR_TYPE_WRBACK, %eax + xor %edx,%edx + wrmsr + + /* Configure the MTRR mask for the size region */ + mov $MTRR_PHYS_MASK(0), %ecx + mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */ + dec %eax + not %eax + or $MTRR_PHYS_MASK_VALID, %eax + movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */ + wrmsr +#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */ + /* Configure CAR region as write-back (WB) */ + mov $MTRR_PHYS_BASE_MSR(0), %ecx + mov $CONFIG_DCACHE_RAM_BASE, %eax + or $MTRR_TYPE_WRBACK, %eax + xor %edx,%edx + wrmsr + + mov $MTRR_PHYS_MASK_MSR(0), %ecx + mov $(512 * KiB), %eax /* size mask */ + dec %eax + not %eax + or $MTRR_PHYS_MASK_VALID, %eax + movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */ + wrmsr + + mov $MTRR_PHYS_BASE_MSR(1), %ecx + mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax + or $MTRR_TYPE_WRBACK, %eax + xor %edx,%edx + wrmsr + + mov $MTRR_PHYS_MASK_MSR(1), %ecx + mov $(256 * KiB), %eax /* size mask */ + dec %eax + not %eax + or $MTRR_PHYS_MASK_VALID, %eax + movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */ + wrmsr +#else +#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing" +#endif + post_code(POST_CAR_FILL) + + /* Enable variable MTRRs */ + mov $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + or $MTRR_DEF_TYPE_EN, %eax + wrmsr + + /* Enable caching */ + mov %cr0, %eax + and $~(X86_CR0_CD | X86_CR0_NW), %eax + invd + mov %eax, %cr0 + +#if IS_ENABLED(CONFIG_INTEL_CAR_NEM) + jmp car_nem +#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS) + jmp car_cqos +#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED) + jmp car_nem_enhanced +#else +#error "No CAR mechanism selected: +#endif + jmp car_init_ret + +fixed_mtrr_list: + .word MTRR_FIX_64K_00000_MSR + .word MTRR_FIX_16K_80000_MSR + .word MTRR_FIX_16K_A0000_MSR + .word MTRR_FIX_4K_C0000_MSR + .word MTRR_FIX_4K_C8000_MSR + .word MTRR_FIX_4K_D0000_MSR + .word MTRR_FIX_4K_D8000_MSR + .word MTRR_FIX_4K_E0000_MSR + .word MTRR_FIX_4K_E8000_MSR + .word MTRR_FIX_4K_F0000_MSR + .word MTRR_FIX_4K_F8000_MSR +fixed_mtrr_list_size = . - fixed_mtrr_list + +#if IS_ENABLED(CONFIG_INTEL_CAR_NEM) +.global car_nem +car_nem: + /* Disable cache eviction (setup stage) */ + mov $MSR_EVICT_CTL, %ecx + rdmsr + or $0x1, %eax + wrmsr + + post_code(0x26) + + /* Clear the cache memory region. This will also fill up the cache */ + movl $CONFIG_DCACHE_RAM_BASE, %edi + movl $CONFIG_DCACHE_RAM_SIZE, %ecx + shr $0x02, %ecx + xor %eax, %eax + cld + rep stosl + + post_code(0x27) + + /* Disable cache eviction (run stage) */ + mov $MSR_EVICT_CTL, %ecx + rdmsr + or $0x2, %eax + wrmsr + + post_code(0x28) + + jmp car_init_ret + +#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS) +.global car_cqos +car_cqos: + /* + * Create CBM_LEN_MASK based on CBM_LEN + * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0] + */ + mov $0x10, %eax + mov $0x2, %ecx + cpuid + and $0x1f, %eax + add $1, %al + + mov $1, %ebx + mov %al, %cl + shl %cl, %ebx + sub $1, %ebx + + /* Store the CBM_LEN_MASK in mm3 for later use */ + movd %ebx, %mm3 + + /* + * Disable both L1 and L2 prefetcher. For yet-to-understood reason, + * prefetchers slow down filling cache with rep stos in CQOS mode. + */ + mov $MSR_PREFETCH_CTL, %ecx + rdmsr + or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax + wrmsr + +#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE) +/* + * If CAR size is set to full L2 size, mask is calculated as all-zeros. + * This is not supported by the CPU/uCode. + */ +#error "CQOS CAR may not use whole L2 cache area" +#endif + + /* Calculate how many bits to be used for CAR */ + xor %edx, %edx + mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */ + mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */ + div %ecx /* result is in eax */ + mov %eax, %ecx /* save to ecx */ + mov $1, %ebx + shl %cl, %ebx + sub $1, %ebx /* resulting mask is is in ebx */ + + /* Set this mask for initial cache fill */ + mov $MSR_L2_QOS_MASK(0), %ecx + rdmsr + mov %ebx, %eax + wrmsr + + /* Set CLOS selector to 0 */ + mov $MSR_IA32_PQR_ASSOC, %ecx + rdmsr + and $~MSR_IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */ + wrmsr + + /* We will need to block CAR region from evicts */ + mov $MSR_L2_QOS_MASK(1), %ecx + rdmsr + /* Invert bits that are to be used for cache */ + mov %ebx, %eax + xor $~0, %eax /* invert 32 bits */ + + /* + * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit + * Mask Length. + */ + movd %mm3, %ebx + and %ebx, %eax + wrmsr + + post_code(0x26) + + /* Clear the cache memory region. This will also fill up the cache */ + movl $CONFIG_DCACHE_RAM_BASE, %edi + movl $CONFIG_DCACHE_RAM_SIZE, %ecx + shr $0x02, %ecx + xor %eax, %eax + cld + rep stosl + + post_code(0x27) + + /* Cache is populated. Use mask 1 that will block evicts */ + mov $MSR_IA32_PQR_ASSOC, %ecx + rdmsr + and $~MSR_IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */ + or $1, %edx /* select mask 1 */ + wrmsr + + /* Enable prefetchers */ + mov $MSR_PREFETCH_CTL, %ecx + rdmsr + and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax + wrmsr + + post_code(0x28) + + jmp car_init_ret + +#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED) +.global car_nem_enhanced +car_nem_enhanced: + /* Disable cache eviction (setup stage) */ + mov $MSR_EVICT_CTL, %ecx + rdmsr + or $0x1, %eax + wrmsr + post_code(0x26) + + /* Create n-way set associativity of cache */ + xorl %edi, %edi +find_llc_subleaf: + movl %edi, %ecx + movl $0x04, %eax + cpuid + inc %edi + and $0xe0, %al /* EAX[7:5] = Cache Level */ + cmp $0x60, %al /* Check to see if it is LLC */ + jnz find_llc_subleaf + + /* + * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE + * for 4/8/16 way of LLC + */ + shr $22, %ebx + inc %ebx + /* Calculate n-way associativity of LLC */ + mov %bl, %cl + + /* + * Maximizing RO cacheability while locking in the CAR to a + * single way since that particular way won't be victim candidate + * for evictions. + * This has been done after programing LLC_WAY_MASK_1 MSR + * with desired LLC way as mentioned below. + * + * Hence create Code and Data Size as per request + * Code Size (RO) : Up to 16M + * Data Size (RW) : Up to 256K + */ + movl $0x01, %eax + /* + * LLC Ways -> LLC_WAY_MASK_1: + * 4: 0x000E + * 8: 0x00FE + * 12: 0x0FFE + * 16: 0xFFFE + * + * These MSRs contain one bit per each way of LLC + * - If this bit is '0' - the way is protected from eviction + * - If this bit is '1' - the way is not protected from eviction + */ + shl %cl, %eax + subl $0x02, %eax + movl $MSR_IA32_L3_MASK_1, %ecx + xorl %edx, %edx + wrmsr + /* + * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1 + * + * For SKL SOC, data size remains 256K consistently. + * Hence, creating 1-way associative cache for Data + */ + mov $MSR_IA32_L3_MASK_2, %ecx + mov $0x01, %eax + xorl %edx, %edx + wrmsr + /* + * Set MSR_IA32_PQR_ASSOC = 0x02 + * + * Possible values: + * 0: Default value, no way mask should be applied + * 1: Apply way mask 1 to LLC + * 2: Apply way mask 2 to LLC + * 3: Shouldn't be use in NEM Mode + */ + movl $MSR_IA32_PQR_ASSOC, %ecx + movl $0x02, %eax + xorl %edx, %edx + wrmsr + + movl $CONFIG_DCACHE_RAM_BASE, %edi + movl $CONFIG_DCACHE_RAM_SIZE, %ecx + shr $0x02, %ecx + xor %eax, %eax + cld + rep stosl + /* + * Set MSR_IA32_PQR_ASSOC = 0x01 + * At this stage we apply LLC_WAY_MASK_1 to the cache. + * i.e. way 0 is protected from eviction. + */ + movl $MSR_IA32_PQR_ASSOC, %ecx + movl $0x01, %eax + xorl %edx, %edx + wrmsr + + post_code(0x27) + /* + * Enable No-Eviction Mode Run State by setting + * NO_EVICT_MODE MSR 2E0h bit [1] = '1'. + */ + + movl $MSR_EVICT_CTL, %ecx + rdmsr + orl $0x02, %eax + wrmsr + + post_code(0x28) + + jmp car_init_ret +#endif + +#if CONFIG_IS_ENABLED(X86_16BIT_INIT) +_dt_ucode_base_size: + /* These next two fields are filled in by binman */ +.globl ucode_base +ucode_base: /* Declared in microcode.h */ + .long 0 /* microcode base */ +.globl ucode_size +ucode_size: /* Declared in microcode.h */ + .long 0 /* microcode size */ + .long CONFIG_SYS_MONITOR_BASE /* code region base */ + .long CONFIG_SYS_MONITOR_LEN /* code region size */ +#endif diff --git a/arch/x86/cpu/intel_common/car2_uninit.S b/arch/x86/cpu/intel_common/car2_uninit.S new file mode 100644 index 0000000000..aba3a5381e --- /dev/null +++ b/arch/x86/cpu/intel_common/car2_uninit.S @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2017 Intel Corp. + * Copyright 2019 Google LLC + * Taken from coreboot file exit_car.S + */ + +#include <config.h> +#include <asm/msr-index.h> +#include <asm/mtrr.h> + +.text +.global car_uninit +car_uninit: + + /* + * Retrieve return address from stack as it will get trashed below if + * execution is utilizing the cache-as-ram stack. + */ + pop %ebx + + /* Disable MTRRs */ + mov $(MTRR_DEF_TYPE_MSR), %ecx + rdmsr + and $(~(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)), %eax + wrmsr + +#ifdef CONFIG_INTEL_CAR_NEM +.global car_nem_teardown +car_nem_teardown: + + /* invalidate cache contents */ + invd + + /* Knock down bit 1 then bit 0 of NEM control not combining steps */ + mov $(MSR_EVICT_CTL), %ecx + rdmsr + and $(~(1 << 1)), %eax + wrmsr + and $(~(1 << 0)), %eax + wrmsr + +#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS) +.global car_cqos_teardown +car_cqos_teardown: + + /* Go back to all-evicting mode, set both masks to all-1s */ + mov $MSR_L2_QOS_MASK(0), %ecx + rdmsr + mov $~0, %al + wrmsr + + mov $MSR_L2_QOS_MASK(1), %ecx + rdmsr + mov $~0, %al + wrmsr + + /* Reset CLOS selector to 0 */ + mov $MSR_IA32_PQR_ASSOC, %ecx + rdmsr + and $~MSR_IA32_PQR_ASSOC_MASK, %edx + wrmsr + +#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED) +.global car_nem_enhanced_teardown +car_nem_enhanced_teardown: + + /* invalidate cache contents */ + invd + + /* Knock down bit 1 then bit 0 of NEM control not combining steps */ + mov $(MSR_EVICT_CTL), %ecx + rdmsr + and $(~(1 << 1)), %eax + wrmsr + and $(~(1 << 0)), %eax + wrmsr + + /* Reset CLOS selector to 0 */ + mov $IA32_PQR_ASSOC, %ecx + rdmsr + and $~IA32_PQR_ASSOC_MASK, %edx + wrmsr +#endif + + /* Return to caller */ + jmp *%ebx diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c new file mode 100644 index 0000000000..a6e3d0a5bf --- /dev/null +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/cpu_common.h> +#include <asm/fast_spi.h> +#include <asm/pci.h> + +/* + * Returns bios_start and fills in size of the BIOS region. + */ +static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, + uint *bios_size) +{ + ulong bios_start, bios_end; + + /* + * BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and + * Limit. Base and Limit fields are in units of 4K. + */ + u32 val = readl(®s->bfp); + + bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12; + bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >> + SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12; + *bios_size = bios_end - bios_start; + + return bios_start; +} + +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct fast_spi_regs *regs; + ulong bar, base, mmio_base; + + /* Special case to find mapping without probing the device */ + pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32); + mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK; + regs = (struct fast_spi_regs *)mmio_base; + base = fast_spi_get_bios_region(regs, map_sizep); + *map_basep = (u32)-*map_sizep - base; + *offsetp = base; + + return 0; +} + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) +{ + /* Program Temporary BAR for SPI */ + pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0, + mmio_base | PCI_BASE_ADDRESS_SPACE_MEMORY, + PCI_SIZE_32); + + /* Enable Bus Master and MMIO Space */ + pci_x86_clrset_config(pdev, PCI_COMMAND, 0, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY, PCI_SIZE_8); + + /* + * Disable the BIOS write protect so write commands are allowed. + * Enable Prefetching and caching. + */ + pci_x86_clrset_config(pdev, SPIBAR_BIOS_CONTROL, + SPIBAR_BIOS_CONTROL_EISS | + SPIBAR_BIOS_CONTROL_CACHE_DISABLE, + SPIBAR_BIOS_CONTROL_WPD | + SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE, PCI_SIZE_8); + + return 0; +} diff --git a/arch/x86/cpu/intel_common/lpss.c b/arch/x86/cpu/intel_common/lpss.c new file mode 100644 index 0000000000..26a2d2d1e3 --- /dev/null +++ b/arch/x86/cpu/intel_common/lpss.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Special driver to handle of-platdata + * + * Copyright 2019 Google LLC + * + * Some code from coreboot lpss.c + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/io.h> +#include <asm/lpss.h> + +enum { + LPSS_RESET_CTL_REG = 0x204, + + /* + * Bit 1:0 controls LPSS controller reset. + * + * 00 ->LPSS Host Controller is in reset (Reset Asserted) + * 01/10 ->Reserved + * 11 ->LPSS Host Controller is NOT at reset (Reset Released) + */ + LPSS_CNT_RST_RELEASE = 3, + + /* Power management control and status register */ + PME_CTRL_STATUS = 0x84, + + /* Bit 1:0 Powerstate, controls D0 and D3 state */ + POWER_STATE_MASK = 3, +}; + +/* Take controller out of reset */ +void lpss_reset_release(void *regs) +{ + writel(LPSS_CNT_RST_RELEASE, regs + LPSS_RESET_CTL_REG); +} + +void lpss_set_power_state(struct udevice *dev, enum lpss_pwr_state state) +{ + dm_pci_clrset_config8(dev, PME_CTRL_STATUS, POWER_STATE_MASK, state); +} diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 3adc155818..ed9938f7f7 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -350,14 +350,6 @@ int irq_router_probe(struct udevice *dev) return 0; } -ulong write_pirq_routing_table(ulong addr) -{ - if (!gd->arch.pirq_routing_table) - return addr; - - return copy_pirq_routing_table(addr, gd->arch.pirq_routing_table); -} - static const struct udevice_id irq_router_ids[] = { { .compatible = "intel,irq-router" }, { } @@ -370,8 +362,3 @@ U_BOOT_DRIVER(irq_router_drv) = { .probe = irq_router_probe, .priv_auto_alloc_size = sizeof(struct irq_router), }; - -UCLASS_DRIVER(irq) = { - .id = UCLASS_IRQ, - .name = "irq", -}; diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index 51ca4ad301..cf34f94a91 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -116,7 +116,7 @@ static int prepare_mrc_cache(struct pei_data *pei_data) ret = read_seed_from_cmos(pei_data); if (ret) return ret; - ret = mrccache_get_region(NULL, &entry); + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); if (ret) return ret; mrc_cache = mrccache_find_current(&entry); @@ -538,12 +538,14 @@ int dram_init(void) /* S3 resume: don't save scrambler seed or MRC data */ if (pei_data->boot_mode != PEI_BOOT_RESUME) { + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; + /* * This will be copied to SDRAM in reserve_arch(), then written * to SPI flash in mrccache_save() */ - gd->arch.mrc_output = (char *)pei_data->mrc_output; - gd->arch.mrc_output_len = pei_data->mrc_output_len; + mrc->buf = (char *)pei_data->mrc_output; + mrc->len = pei_data->mrc_output_len; ret = write_seeds_to_cmos(pei_data); if (ret) debug("Failed to write seeds to CMOS: %d\n", ret); diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index fefbf8f728..7b09f90cd5 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -418,69 +418,6 @@ static int init_bsp(struct udevice **devp) return 0; } -#ifdef CONFIG_QFW -static int qemu_cpu_fixup(void) -{ - int ret; - int cpu_num; - int cpu_online; - struct udevice *dev, *pdev; - struct cpu_platdata *plat; - char *cpu; - - /* first we need to find '/cpus' */ - for (device_find_first_child(dm_root(), &pdev); - pdev; - device_find_next_child(&pdev)) { - if (!strcmp(pdev->name, "cpus")) - break; - } - if (!pdev) { - printf("unable to find cpus device\n"); - return -ENODEV; - } - - /* calculate cpus that are already bound */ - cpu_num = 0; - for (uclass_find_first_device(UCLASS_CPU, &dev); - dev; - uclass_find_next_device(&dev)) { - cpu_num++; - } - - /* get actual cpu number */ - cpu_online = qemu_fwcfg_online_cpus(); - if (cpu_online < 0) { - printf("unable to get online cpu number: %d\n", cpu_online); - return cpu_online; - } - - /* bind addtional cpus */ - dev = NULL; - for (; cpu_num < cpu_online; cpu_num++) { - /* - * allocate device name here as device_bind_driver() does - * not copy device name, 8 bytes are enough for - * sizeof("cpu@") + 3 digits cpu number + '\0' - */ - cpu = malloc(8); - if (!cpu) { - printf("unable to allocate device name\n"); - return -ENOMEM; - } - sprintf(cpu, "cpu@%d", cpu_num); - ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev); - if (ret) { - printf("binding cpu@%d failed: %d\n", cpu_num, ret); - return ret; - } - plat = dev_get_parent_platdata(dev); - plat->cpu_id = cpu_num; - } - return 0; -} -#endif - int mp_init(struct mp_params *p) { int num_aps; @@ -494,11 +431,11 @@ int mp_init(struct mp_params *p) if (ret) return ret; -#ifdef CONFIG_QFW - ret = qemu_cpu_fixup(); - if (ret) - return ret; -#endif + if (IS_ENABLED(CONFIG_QFW)) { + ret = qemu_cpu_fixup(); + if (ret) + return ret; + } ret = init_bsp(&cpu); if (ret) { diff --git a/arch/x86/cpu/qfw_cpu.c b/arch/x86/cpu/qfw_cpu.c new file mode 100644 index 0000000000..49e9dfcf69 --- /dev/null +++ b/arch/x86/cpu/qfw_cpu.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Google, Inc + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <qfw.h> +#include <dm/lists.h> +#include <dm/uclass-internal.h> +#include <dm/root.h> + +int qemu_cpu_fixup(void) +{ + int ret; + int cpu_num; + int cpu_online; + struct udevice *dev, *pdev; + struct cpu_platdata *plat; + char *cpu; + + /* first we need to find '/cpus' */ + for (device_find_first_child(dm_root(), &pdev); + pdev; + device_find_next_child(&pdev)) { + if (!strcmp(pdev->name, "cpus")) + break; + } + if (!pdev) { + printf("unable to find cpus device\n"); + return -ENODEV; + } + + /* calculate cpus that are already bound */ + cpu_num = 0; + for (uclass_find_first_device(UCLASS_CPU, &dev); + dev; + uclass_find_next_device(&dev)) { + cpu_num++; + } + + /* get actual cpu number */ + cpu_online = qemu_fwcfg_online_cpus(); + if (cpu_online < 0) { + printf("unable to get online cpu number: %d\n", cpu_online); + return cpu_online; + } + + /* bind addtional cpus */ + dev = NULL; + for (; cpu_num < cpu_online; cpu_num++) { + /* + * allocate device name here as device_bind_driver() does + * not copy device name, 8 bytes are enough for + * sizeof("cpu@") + 3 digits cpu number + '\0' + */ + cpu = malloc(8); + if (!cpu) { + printf("unable to allocate device name\n"); + return -ENOMEM; + } + sprintf(cpu, "cpu@%d", cpu_num); + ret = device_bind_driver(pdev, "cpu_qemu", cpu, &dev); + if (ret) { + printf("binding cpu@%d failed: %d\n", cpu_num, ret); + return ret; + } + plat = dev_get_parent_platdata(dev); + plat->cpu_id = cpu_num; + } + return 0; +} diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c index 995e119fb6..2bf90dcfc6 100644 --- a/arch/x86/cpu/quark/dram.c +++ b/arch/x86/cpu/quark/dram.c @@ -24,7 +24,7 @@ static __maybe_unused int prepare_mrc_cache(struct mrc_params *mrc_params) struct mrc_region entry; int ret; - ret = mrccache_get_region(NULL, &entry); + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); if (ret) return ret; @@ -154,9 +154,11 @@ int dram_init(void) #ifdef CONFIG_ENABLE_MRC_CACHE cache = malloc(sizeof(struct mrc_timings)); if (cache) { + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; + memcpy(cache, &mrc_params.timings, sizeof(struct mrc_timings)); - gd->arch.mrc_output = cache; - gd->arch.mrc_output_len = sizeof(struct mrc_timings); + mrc->buf = cache; + mrc->len = sizeof(struct mrc_timings); } #endif diff --git a/arch/x86/cpu/slimbootloader/Kconfig b/arch/x86/cpu/slimbootloader/Kconfig index 3ea4c9958c..58a9ca01a9 100644 --- a/arch/x86/cpu/slimbootloader/Kconfig +++ b/arch/x86/cpu/slimbootloader/Kconfig @@ -17,3 +17,4 @@ config SYS_SLIMBOOTLOADER imply USB_EHCI_HCD imply USB_XHCI_HCD imply E1000 + imply X86_TSC_READ_BASE diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index c1e9bfbf66..e6c22895b3 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -17,7 +17,10 @@ SECTIONS . = IMAGE_TEXT_BASE; /* Location of bootcode in flash */ __text_start = .; - .text : { *(.text*); } + .text : { + __image_copy_start = .; + *(.text*); + } . = ALIGN(4); diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index d4bdf62be6..be209aaaf8 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -2,6 +2,7 @@ dtb-y += bayleybay.dtb \ cherryhill.dtb \ + chromebook_coral.dtb \ chromebook_link.dtb \ chromebox_panther.dtb \ chromebook_samus.dtb \ diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts new file mode 100644 index 0000000000..24fcbb5063 --- /dev/null +++ b/arch/x86/dts/chromebook_coral.dts @@ -0,0 +1,831 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/dts-v1/; + +#include <dt-bindings/gpio/x86-gpio.h> + +/include/ "skeleton.dtsi" +/include/ "keyboard.dtsi" +/include/ "reset.dtsi" +/include/ "rtc.dtsi" +/include/ "tsc_timer.dtsi" + +#ifdef CONFIG_CHROMEOS +#include "chromeos-x86.dtsi" +#include "flashmap-x86-ro.dtsi" +#include "flashmap-16mb-rw.dtsi" +#endif + +#include <asm/intel_pinctrl_defs.h> +#include <asm/arch-apollolake/cpu.h> +#include <asm/arch-apollolake/gpio.h> +#include <asm/arch-apollolake/iomap.h> +#include <asm/arch-apollolake/pm.h> + +/ { + model = "Google Coral"; + compatible = "google,coral", "intel,apollolake"; + + aliases { + cros-ec0 = &cros_ec; + fsp = &fsp_s; + spi0 = &spi; + }; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = &serial; + }; + + cpus { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + u-boot,dm-pre-reloc; + device_type = "cpu"; + compatible = "intel,apl-cpu"; + reg = <0>; + intel,apic-id = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "intel,apl-cpu"; + reg = <1>; + intel,apic-id = <2>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "intel,apl-cpu"; + reg = <2>; + intel,apic-id = <4>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "intel,apl-cpu"; + reg = <3>; + intel,apic-id = <6>; + }; + + }; + + keyboard { + intel,duplicate-por; + }; + + pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000 + 0x42000000 0x0 0xb0000000 0xb0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xefff>; + u-boot,skip-auto-config-until-reloc; + + host_bridge: host-bridge@0,0 { + u-boot,dm-pre-reloc; + reg = <0x00000000 0 0 0 0>; + compatible = "intel,apl-hostbridge"; + pciex-region-size = <0x10000000>; + /* + * Parameters used by the FSP-S binary blob. This is + * really unfortunate since these parameters mostly + * relate to drivers but we need them in one place. We + * could put them in the driver nodes easily, but then + * would have to scan each node to find them. So just + * dump them here for now. + */ + fsp_s: fsp-s { + }; + }; + + punit@0,1 { + u-boot,dm-pre-reloc; + reg = <0x00000800 0 0 0 0>; + compatible = "intel,apl-punit"; + }; + + p2sb: p2sb@d,0 { + u-boot,dm-pre-reloc; + reg = <0x02006810 0 0 0 0>; + compatible = "intel,apl-p2sb"; + early-regs = <IOMAP_P2SB_BAR 0x100000>; + + n { + compatible = "intel,apl-pinctrl"; + u-boot,dm-pre-reloc; + intel,p2sb-port-id = <PID_GPIO_N>; + gpio_n: gpio-n { + compatible = "intel,gpio"; + u-boot,dm-pre-reloc; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + nw { + u-boot,dm-pre-reloc; + compatible = "intel,apl-pinctrl"; + intel,p2sb-port-id = <PID_GPIO_NW>; + #gpio-cells = <2>; + gpio_nw: gpio-nw { + compatible = "intel,gpio"; + u-boot,dm-pre-reloc; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + w { + u-boot,dm-pre-reloc; + compatible = "intel,apl-pinctrl"; + intel,p2sb-port-id = <PID_GPIO_W>; + #gpio-cells = <2>; + gpio_w: gpio-w { + compatible = "intel,gpio"; + u-boot,dm-pre-reloc; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + sw { + u-boot,dm-pre-reloc; + compatible = "intel,apl-pinctrl"; + intel,p2sb-port-id = <PID_GPIO_SW>; + #gpio-cells = <2>; + gpio_sw: gpio-sw { + compatible = "intel,gpio"; + u-boot,dm-pre-reloc; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + itss { + u-boot,dm-pre-reloc; + compatible = "intel,apl-itss"; + intel,p2sb-port-id = <PID_ITSS>; + intel,pmc-routes = < + PMC_GPE_SW_31_0 GPIO_GPE_SW_31_0 + PMC_GPE_SW_63_32 GPIO_GPE_SW_63_32 + PMC_GPE_NW_31_0 GPIO_GPE_NW_31_0 + PMC_GPE_NW_63_32 GPIO_GPE_NW_63_32 + PMC_GPE_NW_95_64 GPIO_GPE_NW_95_64 + PMC_GPE_N_31_0 GPIO_GPE_N_31_0 + PMC_GPE_N_63_32 GPIO_GPE_N_63_32 + PMC_GPE_W_31_0 GPIO_GPE_W_31_0>; + }; + }; + + pmc@d,1 { + u-boot,dm-pre-reloc; + reg = <0x6900 0 0 0 0>; + + /* + * Values for BAR0, BAR2 and ACPI_BASE for when PCI + * auto-configure is not available + */ + early-regs = <0xfe042000 0x2000 + 0xfe044000 0x2000 + IOMAP_ACPI_BASE IOMAP_ACPI_SIZE>; + compatible = "intel,apl-pmc"; + gpe0-dwx-mask = <0xf>; + gpe0-dwx-shift-base = <4>; + + /* + * GPE configuration + * Note that GPE events called out in ASL code rely on + * this route, i.e., if this route changes then the + * affected GPE * offset bits also need to be changed. + * This sets the PMC register GPE_CFG fields. + */ + gpe0-dw = <PMC_GPE_N_31_0 + PMC_GPE_N_63_32 + PMC_GPE_SW_31_0>; + gpe0-sts = <0x20>; + gpe0-en = <0x30>; + }; + + spi: fast-spi@d,2 { + u-boot,dm-pre-reloc; + reg = <0x02006a10 0 0 0 0>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,fast-spi"; + early-regs = <IOMAP_SPI_BASE 0x1000>; + intel,hardware-seq = <1>; + + fwstore_spi: spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + u-boot,dm-pre-reloc; + reg = <0>; + compatible = "winbond,w25q128fw", + "jedec,spi-nor"; + rw-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x008e0000 0x00010000>; + u-boot,dm-pre-reloc; + }; + rw-var-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x008f0000 0x0001000>; + u-boot,dm-pre-reloc; + }; + }; + }; + + serial: serial@18,2 { + reg = <0x0200c210 0 0 0 0>; + u-boot,dm-pre-reloc; + compatible = "intel,apl-ns16550"; + early-regs = <0xde000000 0x20>; + reg-shift = <2>; + clock-frequency = <1843200>; + current-speed = <115200>; + }; + + pch: pch@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,apl-pch"; + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + + lpc { + compatible = "intel,apl-lpc"; + #address-cells = <1>; + #size-cells = <0>; + u-boot,dm-pre-reloc; + cros_ec: cros-ec { + u-boot,dm-pre-reloc; + compatible = "google,cros-ec-lpc"; + reg = <0x204 1 0x200 1 0x880 0x80>; + + /* + * Describes the flash memory within + * the EC + */ + #address-cells = <1>; + #size-cells = <1>; + flash@8000000 { + reg = <0x08000000 0x20000>; + erase-value = <0xff>; + }; + }; + }; + }; + }; + +}; + +&host_bridge { + /* + * PL1 override 12000 mW: the energy calculation is wrong with the + * current VR solution. Experiments show that SoC TDP max (6W) can be + * reached when RAPL PL1 is set to 12W. Set RAPL PL2 to 15W. + */ + tdp-pl-override-mw = <12000 15000>; + + early-pads = < + /* These two are for the debug UART */ + GPIO_46 /* UART2 RX */ + (PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP) + (PAD_CFG1_PULL_NATIVE | PAD_CFG1_IOSSTATE_TX_LAST_RXE) + + GPIO_47 /* UART2 TX */ + (PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP) + (PAD_CFG1_PULL_NATIVE | PAD_CFG1_IOSSTATE_TX_LAST_RXE) + + GPIO_75 /* I2S1_BCLK -- PCH_WP */ + (PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP) + (PAD_CFG1_PULL_UP_20K | PAD_CFG1_IOSSTATE_TXD_RXE) + + /* I2C2 - TPM */ + GPIO_128 /* LPSS_I2C2_SDA */ + (PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP) + (PAD_CFG1_PULL_UP_2K | PAD_CFG1_IOSSTATE_TX_LAST_RXE) + GPIO_129 /* LPSS_I2C2_SCL */ + (PAD_CFG0_MODE_NF1 | PAD_CFG0_LOGICAL_RESET_DEEP) + (PAD_CFG1_PULL_UP_2K | PAD_CFG1_IOSSTATE_TX_LAST_RXE) + GPIO_28 /* TPM IRQ */ + (PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP | + PAD_CFG0_TX_DISABLE | PAD_CFG0_ROUTE_IOAPIC | + PAD_CFG0_TRIG_LEVEL | PAD_CFG0_RX_POL_INVERT) + (PAD_CFG1_PULL_NONE | PAD_CFG1_IOSSTATE_TXD_RXE) + + /* + * WLAN_PE_RST - default to deasserted just in case FSP + * misbehaves + */ + GPIO_122 /* SIO_SPI_2_RXD */ + (PAD_CFG0_MODE_GPIO | PAD_CFG0_LOGICAL_RESET_DEEP | + PAD_CFG0_RX_DISABLE | 0) + (PAD_CFG1_PULL_NONE | PAD_CFG1_IOSSTATE_TX_LAST_RXE) + + /* LPC */ + PAD_CFG_NF(LPC_ILB_SERIRQ, UP_20K, DEEP, NF1) /* LPC_SERIRQ */ + PAD_CFG_NF(LPC_CLKOUT0, NONE, DEEP, NF1) /* LPC_CLKOUT0 */ + PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1) + PAD_CFG_NF(LPC_AD0, UP_20K, DEEP, NF1) /* LPC_AD0 */ + PAD_CFG_NF(LPC_AD1, UP_20K, DEEP, NF1) /* LPC_AD1 */ + PAD_CFG_NF(LPC_AD2, UP_20K, DEEP, NF1) /* LPC_AD2 */ + PAD_CFG_NF(LPC_AD3, UP_20K, DEEP, NF1) /* LPC_AD3 */ + PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */ + PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */ + >; + + lpddr4-swizzle = /bits/ 8 < + /* LP4_PHYS_CH0A */ + + /* DQA[0:7] pins of LPDDR4 module */ + 6 7 5 4 3 1 0 2 + /* DQA[8:15] pins of LPDDR4 module */ + 12 10 11 13 14 8 9 15 + /* DQB[0:7] pins of LPDDR4 module with offset of 16 */ + 16 22 23 20 18 17 19 21 + /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ + 30 28 29 25 24 26 27 31 + + /* LP4_PHYS_CH0B */ + /* DQA[0:7] pins of LPDDR4 module */ + 7 3 5 2 6 0 1 4 + /* DQA[8:15] pins of LPDDR4 module */ + 9 14 12 13 10 11 8 15 + /* DQB[0:7] pins of LPDDR4 module with offset of 16 */ + 20 22 23 16 19 17 18 21 + /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ + 28 24 26 27 29 30 31 25 + + /* LP4_PHYS_CH1A */ + + /* DQA[0:7] pins of LPDDR4 module */ + 2 1 6 7 5 4 3 0 + /* DQA[8:15] pins of LPDDR4 module */ + 11 10 8 9 12 15 13 14 + /* DQB[0:7] pins of LPDDR4 module with offset of 16 */ + 17 23 19 16 21 22 20 18 + /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ + 31 29 26 25 28 27 24 30 + + /* LP4_PHYS_CH1B */ + + /* DQA[0:7] pins of LPDDR4 module */ + 4 3 7 5 6 1 0 2 + /* DQA[8:15] pins of LPDDR4 module */ + 15 9 8 11 14 13 12 10 + /* DQB[0:7] pins of LPDDR4 module with offset of 16 */ + 20 23 22 21 18 19 16 17 + /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ + 25 28 30 31 26 27 24 29>; +}; + +&fsp_s { + u-boot,dm-pre-proper; + + /* Disable unused clkreq of PCIe root ports */ + pcie-rp-clkreq-pin = /bits/ 8 <0 /* wifi/bt */ + CLKREQ_DISABLED + CLKREQ_DISABLED + CLKREQ_DISABLED + CLKREQ_DISABLED + CLKREQ_DISABLED>; + + /* + * GPIO for PERST_0 + * If the Board has PERST_0 signal, assign the GPIO + * If the Board does not have PERST_0, assign GPIO_PRT0_UDEF + * + * This are not used yet, so comment them out for now. + * + * prt0-gpio = <GPIO_122>; + * + * GPIO for SD card detect + * sdcard-cd-gpio = <GPIO_177>; + */ + + /* + * Order is emmc-tx-data-cntl1, emmc-tx-data-cntl2, + * emmc-rx-cmd-data-cntl1, emmc-rx-cmd-data-cntl2 + * + * EMMC TX DATA Delay 1 + * Refer to EDS-Vol2-22.3 + * [14:8] steps of delay for HS400, each 125ps + * [6:0] steps of delay for SDR104/HS200, each 125ps + + /* + * EMMC TX DATA Delay 2 + * Refer to EDS-Vol2-22.3. + * [30:24] steps of delay for SDR50, each 125ps + * [22:16] steps of delay for DDR50, each 125ps + * [14:8] steps of delay for SDR25/HS50, each 125ps + * [6:0] steps of delay for SDR12, each 125ps + */ + + /* + * EMMC RX CMD/DATA Delay 1 + * Refer to EDS-Vol2-22.3. + * [30:24] steps of delay for SDR50, each 125ps + * [22:16] steps of delay for DDR50, each 125ps + * [14:8] steps of delay for SDR25/HS50, each 125ps + * [6:0] steps of delay for SDR12, each 125ps + */ + + /* + * EMMC RX CMD/DATA Delay 2 + * Refer to EDS-Vol2-22.3. + * [17:16] stands for Rx Clock before Output Buffer + * [14:8] steps of delay for Auto Tuning Mode, each 125ps + * [6:0] steps of delay for HS200, each 125ps + */ + emmc = <0x0c16 0x28162828 0x00181717 0x10008>; + + /* Enable DPTF */ + dptf-enable; + + /* Enable Audio Clock and Power gating */ + hdaudio-clk-gate-enable; + hdaudio-pwr-gate-enable; + hdaudio-bios-config-lockdown; + + /* Enable lpss s0ix */ + lpss-s0ix-enable; + + /* + * TODO(sjg@chromium.org): Move this to the I2C nodes + * Intel Common SoC Config + *+-------------------+---------------------------+ + *| Field | Value | + *+-------------------+---------------------------+ + *| I2C0 | Audio | + *| I2C2 | TPM | + *| I2C3 | Touchscreen | + *| I2C4 | Trackpad | + *| I2C5 | Digitizer | + *+-------------------+---------------------------+ + * + common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise-time-ns = 104, + .fall-time-ns = 52, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise-time-ns = 57, + .fall-time-ns = 28, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise-time-ns = 76, + .fall-time-ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise-time-ns = 114, + .fall-time-ns = 164, + .data_hold_time_ns = 350, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise-time-ns = 152, + .fall-time-ns = 30, + }, + }" + */ + + /* Minimum SLP S3 assertion width 28ms */ + slp-s3-assertion-width-usecs = <28000>; + + pads = < + /* PCIE_WAKE[0:3]_N */ + PAD_CFG_GPI_SCI_LOW(GPIO_205, UP_20K, DEEP, EDGE_SINGLE) /* WLAN */ + PAD_CFG_GPI(GPIO_206, UP_20K, DEEP) /* Unused */ + PAD_CFG_GPI(GPIO_207, UP_20K, DEEP) /* Unused */ + PAD_CFG_GPI(GPIO_208, UP_20K, DEEP) /* Unused */ + + /* EMMC interface */ + PAD_CFG_NF(GPIO_156, DN_20K, DEEP, NF1) /* EMMC_CLK */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_157, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D0 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_158, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D1 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_159, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D2 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_160, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D3 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_161, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D4 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_162, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D5 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_163, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D6 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_164, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_D7 */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_165, UP_20K, DEEP, NF1, HIZCRX1, DISPUPD) /* EMMC_CMD */ + PAD_CFG_NF(GPIO_182, DN_20K, DEEP, NF1) /* EMMC_RCLK */ + + /* SDIO -- unused */ + PAD_CFG_GPI(GPIO_166, UP_20K, DEEP) /* SDIO_CLK */ + PAD_CFG_GPI(GPIO_167, UP_20K, DEEP) /* SDIO_D0 */ + /* Configure SDIO to enable power gating */ + PAD_CFG_NF(GPIO_168, UP_20K, DEEP, NF1) /* SDIO_D1 */ + PAD_CFG_GPI(GPIO_169, UP_20K, DEEP) /* SDIO_D2 */ + PAD_CFG_GPI(GPIO_170, UP_20K, DEEP) /* SDIO_D3 */ + PAD_CFG_GPI(GPIO_171, UP_20K, DEEP) /* SDIO_CMD */ + + /* SDCARD */ + /* Pull down clock by 20K */ + PAD_CFG_NF(GPIO_172, DN_20K, DEEP, NF1) /* SDCARD_CLK */ + PAD_CFG_NF(GPIO_173, UP_20K, DEEP, NF1) /* SDCARD_D0 */ + PAD_CFG_NF(GPIO_174, UP_20K, DEEP, NF1) /* SDCARD_D1 */ + PAD_CFG_NF(GPIO_175, UP_20K, DEEP, NF1) /* SDCARD_D2 */ + PAD_CFG_NF(GPIO_176, UP_20K, DEEP, NF1) /* SDCARD_D3 */ + /* Card detect is active LOW with external pull up */ + PAD_CFG_NF(GPIO_177, NONE, DEEP, NF1) /* SDCARD_CD_N */ + PAD_CFG_NF(GPIO_178, UP_20K, DEEP, NF1) /* SDCARD_CMD */ + /* CLK feedback, internal signal, needs 20K pull down */ + PAD_CFG_NF(GPIO_179, DN_20K, DEEP, NF1) /* SDCARD_CLK_FB */ + /* No h/w write proect for uSD cards, pull down by 20K */ + PAD_CFG_NF(GPIO_186, DN_20K, DEEP, NF1) /* SDCARD_LVL_WP */ + /* EN_SD_SOCKET_PWR_L for SD slot power control. Default on */ + PAD_CFG_GPO(GPIO_183, 0, DEEP) /* SDIO_PWR_DOWN_N */ + + /* SMBus -- unused */ + PAD_CFG_GPI(SMB_ALERTB, UP_20K, DEEP) /* SMB_ALERT _N */ + PAD_CFG_GPI(SMB_CLK, UP_20K, DEEP) /* SMB_CLK */ + PAD_CFG_GPI(SMB_DATA, UP_20K, DEEP) /* SMB_DATA */ + + /* LPC */ + PAD_CFG_NF(LPC_ILB_SERIRQ, UP_20K, DEEP, NF1) /* LPC_SERIRQ */ + PAD_CFG_NF(LPC_CLKOUT0, NONE, DEEP, NF1) /* LPC_CLKOUT0 */ + PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1) + PAD_CFG_NF(LPC_AD0, UP_20K, DEEP, NF1) /* LPC_AD0 */ + PAD_CFG_NF(LPC_AD1, UP_20K, DEEP, NF1) /* LPC_AD1 */ + PAD_CFG_NF(LPC_AD2, UP_20K, DEEP, NF1) /* LPC_AD2 */ + PAD_CFG_NF(LPC_AD3, UP_20K, DEEP, NF1) /* LPC_AD3 */ + PAD_CFG_NF(LPC_CLKRUNB, UP_20K, DEEP, NF1) /* LPC_CLKRUN_N */ + PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1) /* LPC_FRAME_N */ + + /* I2C0 - Audio */ + PAD_CFG_NF(GPIO_124, UP_2K, DEEP, NF1) /* LPSS_I2C0_SDA */ + PAD_CFG_NF(GPIO_125, UP_2K, DEEP, NF1) /* LPSS_I2C0_SCL */ + + /* I2C1 - NFC with external pulls */ + PAD_CFG_NF(GPIO_126, NONE, DEEP, NF1) /* LPSS_I2C1_SDA */ + PAD_CFG_NF(GPIO_127, NONE, DEEP, NF1) /* LPSS_I2C1_SCL */ + + /* I2C2 - TPM */ + PAD_CFG_NF(GPIO_128, UP_2K, DEEP, NF1) /* LPSS_I2C2_SDA */ + PAD_CFG_NF(GPIO_129, UP_2K, DEEP, NF1) /* LPSS_I2C2_SCL */ + + /* I2C3 - touch */ + PAD_CFG_NF(GPIO_130, UP_2K, DEEP, NF1) /* LPSS_I2C3_SDA */ + PAD_CFG_NF(GPIO_131, UP_2K, DEEP, NF1) /* LPSS_I2C3_SCL */ + + /* I2C4 - trackpad */ + /* LPSS_I2C4_SDA */ + PAD_CFG_NF_IOSSTATE(GPIO_132, UP_2K, DEEP, NF1, HIZCRX1) + /* LPSS_I2C4_SCL */ + PAD_CFG_NF_IOSSTATE(GPIO_133, UP_2K, DEEP, NF1, HIZCRX1) + + /* I2C5 -- pen with external pulls */ + PAD_CFG_NF(GPIO_134, NONE, DEEP, NF1) /* LPSS_I2C5_SDA */ + PAD_CFG_NF(GPIO_135, NONE, DEEP, NF1) /* LPSS_I2C5_SCL */ + + /* I2C6-7 -- unused */ + PAD_CFG_GPI(GPIO_136, UP_20K, DEEP) /* LPSS_I2C6_SDA */ + PAD_CFG_GPI(GPIO_137, UP_20K, DEEP) /* LPSS_I2C6_SCL */ + PAD_CFG_GPI(GPIO_138, UP_20K, DEEP) /* LPSS_I2C7_SDA */ + PAD_CFG_GPI(GPIO_139, UP_20K, DEEP) /* LPSS_I2C7_SCL */ + + /* Audio Amp - I2S6 */ + PAD_CFG_NF(GPIO_146, NATIVE, DEEP, NF2) /* ISH_GPIO_0 - I2S6_BCLK */ + PAD_CFG_NF(GPIO_147, NATIVE, DEEP, NF2) /* ISH_GPIO_1 - I2S6_WS_SYNC */ + PAD_CFG_GPI(GPIO_148, UP_20K, DEEP) /* ISH_GPIO_2 - unused */ + PAD_CFG_NF(GPIO_149, NATIVE, DEEP, NF2) /* ISH_GPIO_3 - I2S6_SDO */ + + /* NFC Reset */ + PAD_CFG_GPO(GPIO_150, 1, DEEP) /* ISH_GPIO_4 */ + + PAD_CFG_GPI(GPIO_151, UP_20K, DEEP) /* ISH_GPIO_5 - unused */ + + /* Touch enable */ + PAD_CFG_GPO(GPIO_152, 1, DEEP) /* ISH_GPIO_6 */ + + PAD_CFG_GPI(GPIO_153, UP_20K, DEEP) /* ISH_GPIO_7 - unused */ + PAD_CFG_GPI(GPIO_154, UP_20K, DEEP) /* ISH_GPIO_8 - unused */ + PAD_CFG_GPI(GPIO_155, UP_20K, DEEP) /* ISH_GPIO_9 - unused */ + + /* PCIE_CLKREQ[0:3]_N */ + PAD_CFG_NF(GPIO_209, NONE, DEEP, NF1) /* WLAN with external pull */ + PAD_CFG_GPI(GPIO_210, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_211, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_212, UP_20K, DEEP) /* unused */ + + /* OSC_CLK_OUT_[0:4] -- unused */ + PAD_CFG_GPI(OSC_CLK_OUT_0, UP_20K, DEEP) + PAD_CFG_GPI(OSC_CLK_OUT_1, UP_20K, DEEP) + PAD_CFG_GPI(OSC_CLK_OUT_2, UP_20K, DEEP) + PAD_CFG_GPI(OSC_CLK_OUT_3, UP_20K, DEEP) + PAD_CFG_GPI(OSC_CLK_OUT_4, UP_20K, DEEP) + + /* PMU Signals */ + PAD_CFG_GPI(PMU_AC_PRESENT, UP_20K, DEEP) /* PMU_AC_PRESENT - unused */ + PAD_CFG_NF(PMU_BATLOW_B, UP_20K, DEEP, NF1) /* PMU_BATLOW_N */ + PAD_CFG_NF(PMU_PLTRST_B, NONE, DEEP, NF1) /* PMU_PLTRST_N */ + PAD_CFG_NF(PMU_PWRBTN_B, UP_20K, DEEP, NF1) /* PMU_PWRBTN_N */ + PAD_CFG_NF(PMU_RESETBUTTON_B, NONE, DEEP, NF1) /* PMU_RSTBTN_N */ + PAD_CFG_NF_IOSSTATE(PMU_SLP_S0_B, NONE, DEEP, NF1, IGNORE) /* PMU_SLP_S0_N */ + PAD_CFG_NF(PMU_SLP_S3_B, NONE, DEEP, NF1) /* PMU_SLP_S3_N */ + PAD_CFG_NF(PMU_SLP_S4_B, NONE, DEEP, NF1) /* PMU_SLP_S4_N */ + PAD_CFG_NF(PMU_SUSCLK, NONE, DEEP, NF1) /* PMU_SUSCLK */ + PAD_CFG_GPO(PMU_WAKE_B, 1, DEEP) /* EN_PP3300_EMMC */ + PAD_CFG_NF(SUS_STAT_B, NONE, DEEP, NF1) /* SUS_STAT_N */ + PAD_CFG_NF(SUSPWRDNACK, NONE, DEEP, NF1) /* SUSPWRDNACK */ + + /* DDI[0:1] SDA and SCL -- unused */ + PAD_CFG_GPI(GPIO_187, UP_20K, DEEP) /* HV_DDI0_DDC_SDA */ + PAD_CFG_GPI(GPIO_188, UP_20K, DEEP) /* HV_DDI0_DDC_SCL */ + PAD_CFG_GPI(GPIO_189, UP_20K, DEEP) /* HV_DDI1_DDC_SDA */ + PAD_CFG_GPI(GPIO_190, UP_20K, DEEP) /* HV_DDI1_DDC_SCL */ + + /* MIPI I2C -- unused */ + PAD_CFG_GPI(GPIO_191, UP_20K, DEEP) /* MIPI_I2C_SDA */ + PAD_CFG_GPI(GPIO_192, UP_20K, DEEP) /* MIPI_I2C_SCL */ + + /* Panel 0 control */ + PAD_CFG_NF(GPIO_193, NATIVE, DEEP, NF1) /* PNL0_VDDEN */ + PAD_CFG_NF(GPIO_194, NATIVE, DEEP, NF1) /* PNL0_BKLTEN */ + PAD_CFG_NF(GPIO_195, NATIVE, DEEP, NF1) /* PNL0_BKLTCTL */ + + /* Panel 1 control -- unused */ + PAD_CFG_NF(GPIO_196, NATIVE, DEEP, NF1) /* PNL1_VDDEN */ + PAD_CFG_NF(GPIO_197, NATIVE, DEEP, NF1) /* PNL1_BKLTEN */ + PAD_CFG_NF(GPIO_198, NATIVE, DEEP, NF1) /* PNL1_BKLTCTL */ + + /* Hot plug detect */ + PAD_CFG_NF(GPIO_199, UP_20K, DEEP, NF2) /* HV_DDI1_HPD */ + PAD_CFG_NF(GPIO_200, UP_20K, DEEP, NF2) /* HV_DDI0_HPD */ + + /* MDSI signals -- unused */ + PAD_CFG_GPI(GPIO_201, UP_20K, DEEP) /* MDSI_A_TE */ + PAD_CFG_GPI(GPIO_202, UP_20K, DEEP) /* MDSI_A_TE */ + + /* USB overcurrent pins */ + PAD_CFG_NF(GPIO_203, UP_20K, DEEP, NF1) /* USB_OC0_N */ + PAD_CFG_NF(GPIO_204, UP_20K, DEEP, NF1) /* USB_OC1_N */ + + /* PMC SPI -- almost entirely unused */ + PAD_CFG_GPI(PMC_SPI_FS0, UP_20K, DEEP) + PAD_CFG_NF(PMC_SPI_FS1, UP_20K, DEEP, NF2) /* HV_DDI2_HPD -- EDP HPD */ + PAD_CFG_GPI(PMC_SPI_FS2, UP_20K, DEEP) + PAD_CFG_GPI(PMC_SPI_RXD, UP_20K, DEEP) + PAD_CFG_GPI(PMC_SPI_TXD, UP_20K, DEEP) + PAD_CFG_GPI(PMC_SPI_CLK, UP_20K, DEEP) + + /* PMIC Signals Unused signals related to an old PMIC interface */ + PAD_CFG_NF_IOSSTATE(PMIC_RESET_B, NATIVE, DEEP, NF1, IGNORE) /* PMIC_RESET_B */ + PAD_CFG_GPI(GPIO_213, NONE, DEEP) /* unused external pull */ + PAD_CFG_GPI(GPIO_214, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_215, UP_20K, DEEP) /* unused */ + PAD_CFG_NF(PMIC_THERMTRIP_B, UP_20K, DEEP, NF1) /* THERMTRIP_N */ + PAD_CFG_GPI(PMIC_STDBY, UP_20K, DEEP) /* unused */ + PAD_CFG_NF(PROCHOT_B, UP_20K, DEEP, NF1) /* PROCHOT_N */ + PAD_CFG_NF(PMIC_I2C_SCL, UP_1K, DEEP, NF1) /* PMIC_I2C_SCL */ + PAD_CFG_NF(PMIC_I2C_SDA, UP_1K, DEEP, NF1) /* PMIC_I2C_SDA */ + + /* I2S1 -- largely unused */ + PAD_CFG_GPI(GPIO_74, UP_20K, DEEP) /* I2S1_MCLK */ + PAD_CFG_GPI(GPIO_75, UP_20K, DEEP) /* I2S1_BCLK -- PCH_WP */ + PAD_CFG_GPO(GPIO_76, 0, DEEP) /* I2S1_WS_SYNC -- SPK_PA_EN */ + PAD_CFG_GPI(GPIO_77, UP_20K, DEEP) /* I2S1_SDI */ + PAD_CFG_GPO(GPIO_78, 1, DEEP) /* I2S1_SDO -- EN_PP3300_DX_LTE_SOC */ + + /* DMIC or I2S4 */ + /* AVS_DMIC_CLK_A1 */ + PAD_CFG_NF_IOSSTATE(GPIO_79, NATIVE, DEEP, NF1, IGNORE) + PAD_CFG_NF(GPIO_80, NATIVE, DEEP, NF1) /* AVS_DMIC_CLK_B1 */ + PAD_CFG_NF(GPIO_81, NATIVE, DEEP, NF1) /* AVS_DMIC_DATA_1 */ + PAD_CFG_GPI(GPIO_82, DN_20K, DEEP) /* unused -- strap */ + PAD_CFG_NF(GPIO_83, NATIVE, DEEP, NF1) /* AVS_DMIC_DATA_2 */ + + /* I2S2 -- Headset amp */ + PAD_CFG_NF(GPIO_84, NATIVE, DEEP, NF1) /* AVS_I2S2_MCLK */ + PAD_CFG_NF(GPIO_85, NATIVE, DEEP, NF1) /* AVS_I2S2_BCLK */ + PAD_CFG_NF(GPIO_86, NATIVE, DEEP, NF1) /* AVS_I2S2_SW_SYNC */ + PAD_CFG_NF(GPIO_87, NATIVE, DEEP, NF1) /* AVS_I2S2_SDI */ + PAD_CFG_NF(GPIO_88, NATIVE, DEEP, NF1) /* AVS_I2S2_SDO */ + + /* I2S3 -- largely unused */ + PAD_CFG_GPI(GPIO_89, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_90, UP_20K, DEEP) /* GPS_HOST_WAKE */ + PAD_CFG_GPO(GPIO_91, 1, DEEP) /* GPS_EN */ + PAD_CFG_GPI(GPIO_92, DN_20K, DEEP) /* unused -- strap */ + + /* Fast SPI */ + PAD_CFG_NF_IOSSTATE(GPIO_97, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_CS0_B */ + PAD_CFG_GPI(GPIO_98, UP_20K, DEEP) /* FST_SPI_CS1_B -- unused */ + PAD_CFG_NF_IOSSTATE(GPIO_99, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_MOSI_IO0 */ + PAD_CFG_NF_IOSSTATE(GPIO_100, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_MISO_IO1 */ + PAD_CFG_GPI(GPIO_101, NONE, DEEP) /* FST_IO2 -- MEM_CONFIG0 */ + PAD_CFG_GPI(GPIO_102, NONE, DEEP) /* FST_IO3 -- MEM_CONFIG1 */ + PAD_CFG_NF_IOSSTATE(GPIO_103, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_CLK */ + PAD_CFG_NF_IOSSTATE(FST_SPI_CLK_FB, NATIVE, DEEP, NF1, IGNORE) /* FST_SPI_CLK_FB */ + PAD_CFG_NF_IOSSTATE(GPIO_106, NATIVE, DEEP, NF3, IGNORE) /* FST_SPI_CS2_N */ + + /* SIO_SPI_0 - Used for FP */ + PAD_CFG_NF(GPIO_104, NATIVE, DEEP, NF1) /* SIO_SPI_0_CLK */ + PAD_CFG_NF(GPIO_105, NATIVE, DEEP, NF1) /* SIO_SPI_0_FS0 */ + PAD_CFG_NF(GPIO_109, NATIVE, DEEP, NF1) /* SIO_SPI_0_RXD */ + PAD_CFG_NF(GPIO_110, NATIVE, DEEP, NF1) /* SIO_SPI_0_TXD */ + + /* SIO_SPI_1 -- largely unused */ + PAD_CFG_GPI(GPIO_111, UP_20K, DEEP) /* SIO_SPI_1_CLK */ + PAD_CFG_GPI(GPIO_112, UP_20K, DEEP) /* SIO_SPI_1_FS0 */ + PAD_CFG_GPI(GPIO_113, UP_20K, DEEP) /* SIO_SPI_1_FS1 */ + /* Headset interrupt */ + PAD_CFG_GPI_APIC_LOW(GPIO_116, NONE, DEEP) /* SIO_SPI_1_RXD */ + PAD_CFG_GPI(GPIO_117, UP_20K, DEEP) /* SIO_SPI_1_TXD */ + + /* SIO_SPI_2 -- unused */ + PAD_CFG_GPI(GPIO_118, UP_20K, DEEP) /* SIO_SPI_2_CLK */ + PAD_CFG_GPI(GPIO_119, UP_20K, DEEP) /* SIO_SPI_2_FS0 */ + PAD_CFG_GPI(GPIO_120, UP_20K, DEEP) /* SIO_SPI_2_FS1 */ + PAD_CFG_GPI(GPIO_121, UP_20K, DEEP) /* SIO_SPI_2_FS2 */ + /* WLAN_PE_RST - default to deasserted */ + PAD_CFG_GPO(GPIO_122, 0, DEEP) /* SIO_SPI_2_RXD */ + PAD_CFG_GPI(GPIO_123, UP_20K, DEEP) /* SIO_SPI_2_TXD */ + + /* Debug tracing */ + PAD_CFG_GPI(GPIO_0, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_1, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_2, UP_20K, DEEP) + PAD_CFG_GPI_SCI_HIGH(GPIO_3, DN_20K, DEEP, LEVEL) /* FP_INT */ + PAD_CFG_GPI(GPIO_4, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_5, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_6, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_7, UP_20K, DEEP) + PAD_CFG_GPI(GPIO_8, UP_20K, DEEP) + + PAD_CFG_GPI_APIC_LOW(GPIO_9, NONE, DEEP) /* dTPM IRQ */ + PAD_CFG_GPI(GPIO_10, DN_20K, DEEP) /* Board phase enforcement */ + PAD_CFG_GPI_SCI_LOW(GPIO_11, NONE, DEEP, EDGE_SINGLE) /* EC SCI */ + PAD_CFG_GPI(GPIO_12, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI_APIC_LOW(GPIO_13, NONE, DEEP) /* PEN_INT_ODL */ + PAD_CFG_GPI_APIC_HIGH(GPIO_14, DN_20K, DEEP) /* FP_INT */ + PAD_CFG_GPI_SCI_LOW(GPIO_15, NONE, DEEP, EDGE_SINGLE) /* TRACKPAD_INT_1V8_ODL */ + PAD_CFG_GPI(GPIO_16, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_17, UP_20K, DEEP) /* 1 vs 4 DMIC config */ + PAD_CFG_GPI_APIC_LOW(GPIO_18, NONE, DEEP) /* Trackpad IRQ */ + PAD_CFG_GPI(GPIO_19, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI_APIC_LOW(GPIO_20, UP_20K, DEEP) /* NFC IRQ */ + PAD_CFG_GPI_APIC_LOW(GPIO_21, NONE, DEEP) /* Touch IRQ */ + PAD_CFG_GPI_SCI_LOW(GPIO_22, NONE, DEEP, EDGE_SINGLE) /* EC wake */ + PAD_CFG_GPI(GPIO_23, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_24, NONE, DEEP) /* PEN_PDCT_ODL */ + PAD_CFG_GPI(GPIO_25, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_26, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI(GPIO_27, UP_20K, DEEP) /* unused */ + PAD_CFG_GPI_APIC_LOW(GPIO_28, NONE, DEEP) /* TPM IRQ */ + PAD_CFG_GPO(GPIO_29, 1, DEEP) /* FP reset */ + PAD_CFG_GPI_APIC_LOW(GPIO_30, NONE, DEEP) /* KB IRQ */ + PAD_CFG_GPO(GPIO_31, 0, DEEP) /* NFC FW DL */ + PAD_CFG_NF(GPIO_32, NONE, DEEP, NF5) /* SUS_CLK2 */ + PAD_CFG_GPI_APIC_LOW(GPIO_33, NONE, DEEP) /* PMIC IRQ */ + PAD_CFG_GPI(GPIO_34, UP_20K, DEEP) /* unused */ + PAD_CFG_GPO(GPIO_35, 0, DEEP) /* PEN_RESET - active high */ + PAD_CFG_GPO(GPIO_36, 0, DEEP) /* touch reset */ + PAD_CFG_GPI(GPIO_37, UP_20K, DEEP) /* unused */ + + /* LPSS_UART[0:2] */ + PAD_CFG_GPI(GPIO_38, NONE, DEEP) /* LPSS_UART0_RXD - MEM_CONFIG2*/ + /* Next 2 are straps */ + PAD_CFG_GPI(GPIO_39, DN_20K, DEEP) /* LPSS_UART0_TXD - unused */ + PAD_CFG_GPI(GPIO_40, DN_20K, DEEP) /* LPSS_UART0_RTS - unused */ + PAD_CFG_GPI(GPIO_41, NONE, DEEP) /* LPSS_UART0_CTS - EC_IN_RW */ + PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1) /* LPSS_UART1_RXD */ + PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1) /* LPSS_UART1_TXD */ + PAD_CFG_GPO(GPIO_44, 1, DEEP) /* GPS_RST_ODL */ + PAD_CFG_GPI(GPIO_45, NONE, DEEP) /* LPSS_UART1_CTS - MEM_CONFIG3 */ + PAD_CFG_NF(GPIO_46, NATIVE, DEEP, NF1) /* LPSS_UART2_RXD */ + PAD_CFG_NF_IOSSTATE(GPIO_47, NATIVE, DEEP, NF1, TX1_RX_DCR_X0) /* UART2 TX */ + PAD_CFG_GPI(GPIO_48, UP_20K, DEEP) /* LPSS_UART2_RTS - unused */ + PAD_CFG_GPI_SMI_LOW(GPIO_49, NONE, DEEP, EDGE_SINGLE) /* LPSS_UART2_CTS - EC_SMI_L */ + + /* Camera interface -- completely unused */ + PAD_CFG_GPI(GPIO_62, UP_20K, DEEP) /* GP_CAMERASB00 */ + PAD_CFG_GPI(GPIO_63, UP_20K, DEEP) /* GP_CAMERASB01 */ + PAD_CFG_GPI(GPIO_64, UP_20K, DEEP) /* GP_CAMERASB02 */ + PAD_CFG_GPI(GPIO_65, UP_20K, DEEP) /* GP_CAMERASB03 */ + PAD_CFG_GPI(GPIO_66, UP_20K, DEEP) /* GP_CAMERASB04 */ + PAD_CFG_GPI(GPIO_67, UP_20K, DEEP) /* GP_CAMERASB05 */ + PAD_CFG_GPI(GPIO_68, UP_20K, DEEP) /* GP_CAMERASB06 */ + PAD_CFG_GPI(GPIO_69, UP_20K, DEEP) /* GP_CAMERASB07 */ + PAD_CFG_GPI(GPIO_70, UP_20K, DEEP) /* GP_CAMERASB08 */ + PAD_CFG_GPI(GPIO_71, UP_20K, DEEP) /* GP_CAMERASB09 */ + PAD_CFG_GPI(GPIO_72, UP_20K, DEEP) /* GP_CAMERASB10 */ + PAD_CFG_GPI(GPIO_73, UP_20K, DEEP) /* GP_CAMERASB11 */ + >; +}; diff --git a/arch/x86/dts/u-boot.dtsi b/arch/x86/dts/u-boot.dtsi index 0e87b88e10..f0f8c71761 100644 --- a/arch/x86/dts/u-boot.dtsi +++ b/arch/x86/dts/u-boot.dtsi @@ -37,62 +37,110 @@ }; #endif #ifdef CONFIG_TPL +#ifdef CONFIG_HAVE_MICROCODE u-boot-tpl-with-ucode-ptr { offset = <CONFIG_TPL_TEXT_BASE>; }; u-boot-tpl-dtb { }; - u-boot-spl { - offset = <CONFIG_SPL_TEXT_BASE>; - }; - u-boot-spl-dtb { +#endif + spl { + type = "section"; + offset = <CONFIG_X86_OFFSET_SPL>; + u-boot-spl { + }; + u-boot-spl-dtb { + }; }; u-boot { - offset = <CONFIG_SYS_TEXT_BASE>; + type = "section"; + offset = <CONFIG_X86_OFFSET_U_BOOT>; + u-boot-nodtb { + }; + u-boot-dtb { + }; }; #elif defined(CONFIG_SPL) u-boot-spl-with-ucode-ptr { - offset = <CONFIG_SPL_TEXT_BASE>; + offset = <CONFIG_X86_OFFSET_SPL>; }; u-boot-dtb-with-ucode2 { type = "u-boot-dtb-with-ucode"; }; u-boot { - /* - * TODO(sjg@chromium.org): - * Normally we use CONFIG_SYS_TEXT_BASE as the flash offset. But - * for boards with textbase in SDRAM we cannot do this. Just use - * an assumed-valid value (1MB before the end of flash) here so - * that we can actually build an image for coreboot, etc. - * We need a better solution, perhaps a separate Kconfig. - */ -#if CONFIG_SYS_TEXT_BASE == 0x1110000 - offset = <0xfff00000>; + offset = <CONFIG_X86_OFFSET_U_BOOT>; + }; #else +# ifdef CONFIG_SPL + u-boot { offset = <CONFIG_SYS_TEXT_BASE>; -#endif }; -#else +# else + /* If there is no SPL then we need to put microcode in U-Boot */ u-boot-with-ucode-ptr { - offset = <CONFIG_SYS_TEXT_BASE>; + offset = <CONFIG_X86_OFFSET_U_BOOT>; }; +# endif #endif +#ifdef CONFIG_HAVE_MICROCODE u-boot-dtb-with-ucode { }; u-boot-ucode { align = <16>; }; +#else + u-boot-dtb { + }; +#endif +#ifdef CONFIG_HAVE_X86_FIT + intel-fit { + }; + intel-fit-ptr { + }; +#endif #ifdef CONFIG_HAVE_MRC intel-mrc { offset = <CONFIG_X86_MRC_ADDR>; }; #endif -#ifdef CONFIG_HAVE_FSP +#ifdef CONFIG_FSP_VERSION1 intel-fsp { filename = CONFIG_FSP_FILE; offset = <CONFIG_FSP_ADDR>; }; #endif +#ifdef CONFIG_FSP_VERSION2 + intel-descriptor { + filename = CONFIG_FLASH_DESCRIPTOR_FILE; + }; + intel-ifwi { + filename = CONFIG_IFWI_INPUT_FILE; + convert-fit; + + section { + size = <0x8000>; + ifwi-replace; + ifwi-subpart = "IBBP"; + ifwi-entry = "IBBL"; + u-boot-tpl { + }; + x86-start16-tpl { + offset = <0x7800>; + }; + x86-reset16-tpl { + offset = <0x7ff0>; + }; + }; + }; + intel-fsp-m { + filename = CONFIG_FSP_FILE_M; + }; + intel-fsp-s { + filename = CONFIG_FSP_FILE_S; + }; +#endif + fdtmap { + }; #ifdef CONFIG_HAVE_CMC intel-cmc { filename = CONFIG_CMC_FILE; @@ -138,5 +186,8 @@ offset = <CONFIG_RESET_VEC_LOC>; }; #endif + image-header { + location = "end"; + }; }; #endif diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h new file mode 100644 index 0000000000..5e906c5e7d --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/cpu.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef _ASM_ARCH_CPU_H +#define _ASM_ARCH_CPU_H + +/* Common Timer Copy (CTC) frequency - 19.2MHz */ +#define CTC_FREQ 19200000 + +#define MAX_PCIE_PORTS 6 +#define CLKREQ_DISABLED 0xf + +#ifndef __ASSEMBLY__ +/* Flush L1D to L2 */ +void cpu_flush_l1d_to_l2(void); +#endif + +#endif /* _ASM_ARCH_CPU_H */ diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h new file mode 100644 index 0000000000..9185d94b2b --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __FSP_CONFIGS_H__ +#define __FSP_CONFIGS_H__ + +#define FSPT_UPD_SIGNATURE 0x545F4450554C5041 /* 'APLUPD_T' */ +#define FSPM_UPD_SIGNATURE 0x4D5F4450554C5041 /* 'APLUPD_M' */ +#define FSPS_UPD_SIGNATURE 0x535F4450554C5041 /* 'APLUPD_S' */ +#define VBT_SIGNATURE 0x54425624 + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h new file mode 100644 index 0000000000..93bee5b2d1 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright 2019 Google LLC + */ + +#ifndef __ASM_ARCH_FSP_M_UDP_H +#define __ASM_ARCH_FSP_M_UDP_H + +#include <asm/fsp2/fsp_api.h> + +#define FSP_DRAM_CHANNELS 4 + +struct __packed fspm_arch_upd { + u8 revision; + u8 reserved[3]; + void *nvs_buffer_ptr; + void *stack_base; + u32 stack_size; + u32 boot_loader_tolum_size; + u32 boot_mode; + u8 reserved1[8]; +}; + +struct __packed fsp_ram_channel { + u8 rank_enable; + u8 device_width; + u8 dram_density; + u8 option; + u8 odt_config; + u8 tristate_clk1; + u8 mode2_n; + u8 odt_levels; +}; + +struct __packed fsp_m_config { + u32 serial_debug_port_address; + u8 serial_debug_port_type; + u8 serial_debug_port_device; + u8 serial_debug_port_stride_size; + u8 mrc_fast_boot; + u8 igd; + u8 igd_dvmt50_pre_alloc; + u8 igd_aperture_size; + u8 gtt_size; + u8 primary_video_adaptor; + u8 package; + u8 profile; + u8 memory_down; + + u8 ddr3_l_page_size; + u8 ddr3_lasr; + u8 scrambler_support; + u8 interleaved_mode; + u16 channel_hash_mask; + u16 slice_hash_mask; + u8 channels_slices_enable; + u8 min_ref_rate2x_enable; + u8 dual_rank_support_enable; + u8 rmt_mode; + u16 memory_size_limit; + u16 low_memory_max_value; + + u16 high_memory_max_value; + u8 disable_fast_boot; + u8 dimm0_spd_address; + u8 dimm1_spd_address; + struct fsp_ram_channel chan[FSP_DRAM_CHANNELS]; + u8 rmt_check_run; + u16 rmt_margin_check_scale_high_threshold; + u8 ch_bit_swizzling[FSP_DRAM_CHANNELS][32]; + u32 msg_level_mask; + u8 unused_upd_space0[4]; + + u8 pre_mem_gpio_table_pin_num[4]; + u32 pre_mem_gpio_table_ptr; + u8 pre_mem_gpio_table_entry_num; + u8 enhance_port8xh_decoding; + u8 spd_write_enable; + u8 mrc_data_saving; + u32 oem_loading_base; + + u8 oem_file_name[16]; + + void *mrc_boot_data_ptr; + u8 e_mmc_trace_len; + u8 skip_cse_rbp; + u8 npk_en; + u8 fw_trace_en; + u8 fw_trace_destination; + u8 recover_dump; + u8 msc0_wrap; + u8 msc1_wrap; + u32 msc0_size; + + u32 msc1_size; + u8 pti_mode; + u8 pti_training; + u8 pti_speed; + u8 punit_mlvl; + + u8 pmc_mlvl; + u8 sw_trace_en; + u8 periodic_retraining_disable; + u8 enable_reset_system; + + u8 enable_s3_heci2; + u8 unused_upd_space1[3]; + + void *variable_nvs_buffer_ptr; + u8 reserved_fspm_upd[12]; +}; + +/** FSP-M UPD Configuration */ +struct __packed fspm_upd { + struct fsp_upd_header header; + struct fspm_arch_upd arch; + struct fsp_m_config config; + u8 unused_upd_space2[158]; + u16 upd_terminator; +}; + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h new file mode 100644 index 0000000000..4a868e80ba --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (c) 2016, Intel Corporation. All rights reserved. + * Copyright 2019 Google LLC + */ +#ifndef __ASM_ARCH_FSP_S_UDP_H +#define __ASM_ARCH_FSP_S_UDP_H + +#include <asm/fsp2/fsp_api.h> + +struct __packed fsp_s_config { + u8 active_processor_cores; + u8 disable_core1; + u8 disable_core2; + u8 disable_core3; + u8 vmx_enable; + u8 proc_trace_mem_size; + u8 proc_trace_enable; + u8 eist; + u8 boot_p_state; + u8 enable_cx; + u8 c1e; + u8 bi_proc_hot; + u8 pkg_c_state_limit; + u8 c_state_auto_demotion; + u8 c_state_un_demotion; + u8 max_core_c_state; + u8 pkg_c_state_demotion; + u8 pkg_c_state_un_demotion; + u8 turbo_mode; + u8 hda_verb_table_entry_num; + u32 hda_verb_table_ptr; + u8 p2sb_unhide; + u8 ipu_en; + u8 ipu_acpi_mode; + u8 force_wake; + u32 gtt_mm_adr; + u32 gm_adr; + u8 pavp_lock; + u8 graphics_freq_modify; + u8 graphics_freq_req; + u8 graphics_video_freq; + u8 pm_lock; + u8 dop_clock_gating; + u8 unsolicited_attack_override; + u8 wopcm_support; + u8 wopcm_size; + u8 power_gating; + u8 unit_level_clock_gating; + u8 fast_boot; + u8 dyn_sr; + u8 sa_ipu_enable; + u8 pm_support; + u8 enable_render_standby; + u32 logo_size; + u32 logo_ptr; + u32 graphics_config_ptr; + u8 pavp_enable; + u8 pavp_pr3; + u8 cd_clock; + u8 pei_graphics_peim_init; + u8 write_protection_enable[5]; + u8 read_protection_enable[5]; + u16 protected_range_limit[5]; + u16 protected_range_base[5]; + u8 gmm; + u8 clk_gating_pgcb_clk_trunk; + u8 clk_gating_sb; + u8 clk_gating_sb_clk_trunk; + u8 clk_gating_sb_clk_partition; + u8 clk_gating_core; + u8 clk_gating_dma; + u8 clk_gating_reg_access; + u8 clk_gating_host; + u8 clk_gating_partition; + u8 clk_gating_trunk; + u8 hda_enable; + u8 dsp_enable; + u8 pme; + u8 hd_audio_io_buffer_ownership; + u8 hd_audio_io_buffer_voltage; + u8 hd_audio_vc_type; + u8 hd_audio_link_frequency; + u8 hd_audio_i_disp_link_frequency; + u8 hd_audio_i_disp_link_tmode; + u8 dsp_endpoint_dmic; + u8 dsp_endpoint_bluetooth; + u8 dsp_endpoint_i2s_skp; + u8 dsp_endpoint_i2s_hp; + u8 audio_ctl_pwr_gate; + u8 audio_dsp_pwr_gate; + u8 mmt; + u8 hmt; + u8 hd_audio_pwr_gate; + u8 hd_audio_clk_gate; + u32 dsp_feature_mask; + u32 dsp_pp_module_mask; + u8 bios_cfg_lock_down; + u8 hpet; + u8 hpet_bdf_valid; + u8 hpet_bus_number; + u8 hpet_device_number; + u8 hpet_function_number; + u8 io_apic_bdf_valid; + u8 io_apic_bus_number; + u8 io_apic_device_number; + u8 io_apic_function_number; + u8 io_apic_entry24_119; + u8 io_apic_id; + u8 io_apic_range_select; + u8 ish_enable; + u8 bios_interface; + u8 bios_lock; + u8 spi_eiss; + u8 bios_lock_sw_smi_number; + u8 lpss_s0ix_enable; + u8 unused_upd_space0[1]; + u8 i2c_clk_gate_cfg[8]; + u8 hsuart_clk_gate_cfg[4]; + u8 spi_clk_gate_cfg[3]; + u8 i2c0_enable; + u8 i2c1_enable; + u8 i2c2_enable; + u8 i2c3_enable; + u8 i2c4_enable; + u8 i2c5_enable; + u8 i2c6_enable; + u8 i2c7_enable; + u8 hsuart0_enable; + u8 hsuart1_enable; + u8 hsuart2_enable; + u8 hsuart3_enable; + u8 spi0_enable; + u8 spi1_enable; + u8 spi2_enable; + u8 os_dbg_enable; + u8 dci_en; + u32 uart2_kernel_debug_base_address; + u8 pcie_clock_gating_disabled; + u8 pcie_root_port8xh_decode; + u8 pcie8xh_decode_port_index; + u8 pcie_root_port_peer_memory_write_enable; + u8 pcie_aspm_sw_smi_number; + u8 unused_upd_space1[1]; + u8 pcie_root_port_en[6]; + u8 pcie_rp_hide[6]; + u8 pcie_rp_slot_implemented[6]; + u8 pcie_rp_hot_plug[6]; + u8 pcie_rp_pm_sci[6]; + u8 pcie_rp_ext_sync[6]; + u8 pcie_rp_transmitter_half_swing[6]; + u8 pcie_rp_acs_enabled[6]; + u8 pcie_rp_clk_req_supported[6]; + u8 pcie_rp_clk_req_number[6]; + u8 pcie_rp_clk_req_detect[6]; + u8 advanced_error_reporting[6]; + u8 pme_interrupt[6]; + u8 unsupported_request_report[6]; + u8 fatal_error_report[6]; + u8 no_fatal_error_report[6]; + u8 correctable_error_report[6]; + u8 system_error_on_fatal_error[6]; + u8 system_error_on_non_fatal_error[6]; + u8 system_error_on_correctable_error[6]; + u8 pcie_rp_speed[6]; + u8 physical_slot_number[6]; + u8 pcie_rp_completion_timeout[6]; + u8 ptm_enable[6]; + u8 pcie_rp_aspm[6]; + u8 pcie_rp_l1_substates[6]; + u8 pcie_rp_ltr_enable[6]; + u8 pcie_rp_ltr_config_lock[6]; + u8 pme_b0_s5_dis; + u8 pci_clock_run; + u8 timer8254_clk_setting; + u8 enable_sata; + u8 sata_mode; + u8 sata_salp_support; + u8 sata_pwr_opt_enable; + u8 e_sata_speed_limit; + u8 speed_limit; + u8 unused_upd_space2[1]; + u8 sata_ports_enable[2]; + u8 sata_ports_dev_slp[2]; + u8 sata_ports_hot_plug[2]; + u8 sata_ports_interlock_sw[2]; + u8 sata_ports_external[2]; + u8 sata_ports_spin_up[2]; + u8 sata_ports_solid_state_drive[2]; + u8 sata_ports_enable_dito_config[2]; + u8 sata_ports_dm_val[2]; + u8 unused_upd_space3[2]; + u16 sata_ports_dito_val[2]; + u16 sub_system_vendor_id; + u16 sub_system_id; + u8 crid_settings; + u8 reset_select; + u8 sdcard_enabled; + u8 e_mmc_enabled; + u8 e_mmc_host_max_speed; + u8 ufs_enabled; + u8 sdio_enabled; + u8 gpp_lock; + u8 sirq_enable; + u8 sirq_mode; + u8 start_frame_pulse; + u8 smbus_enable; + u8 arp_enable; + u8 unused_upd_space4; + u16 num_rsvd_smbus_addresses; + u8 rsvd_smbus_address_table[128]; + u8 disable_compliance_mode; + u8 usb_per_port_ctl; + u8 usb30_mode; + u8 unused_upd_space5[1]; + u8 port_usb20_enable[8]; + u8 port_us20b_over_current_pin[8]; + u8 usb_otg; + u8 hsic_support_enable; + u8 port_usb30_enable[6]; + u8 port_us30b_over_current_pin[6]; + u8 ssic_port_enable[2]; + u16 dlane_pwr_gating; + u8 vtd_enable; + u8 lock_down_global_smi; + u16 reset_wait_timer; + u8 rtc_lock; + u8 sata_test_mode; + u8 ssic_rate[2]; + u16 dynamic_power_gating; + u16 pcie_rp_ltr_max_snoop_latency[6]; + u8 pcie_rp_snoop_latency_override_mode[6]; + u8 unused_upd_space6[2]; + u16 pcie_rp_snoop_latency_override_value[6]; + u8 pcie_rp_snoop_latency_override_multiplier[6]; + u8 skip_mp_init; + u8 dci_auto_detect; + u16 pcie_rp_ltr_max_non_snoop_latency[6]; + u8 pcie_rp_non_snoop_latency_override_mode[6]; + u8 tco_timer_halt_lock; + u8 pwr_btn_override_period; + u16 pcie_rp_non_snoop_latency_override_value[6]; + u8 pcie_rp_non_snoop_latency_override_multiplier[6]; + u8 pcie_rp_slot_power_limit_scale[6]; + u8 pcie_rp_slot_power_limit_value[6]; + u8 disable_native_power_button; + u8 power_butter_debounce_mode; + u32 sdio_tx_cmd_cntl; + u32 sdio_tx_data_cntl1; + u32 sdio_tx_data_cntl2; + u32 sdio_rx_cmd_data_cntl1; + u32 sdio_rx_cmd_data_cntl2; + u32 sdcard_tx_cmd_cntl; + u32 sdcard_tx_data_cntl1; + u32 sdcard_tx_data_cntl2; + u32 sdcard_rx_cmd_data_cntl1; + u32 sdcard_rx_strobe_cntl; + u32 sdcard_rx_cmd_data_cntl2; + u32 emmc_tx_cmd_cntl; + u32 emmc_tx_data_cntl1; + u32 emmc_tx_data_cntl2; + u32 emmc_rx_cmd_data_cntl1; + u32 emmc_rx_strobe_cntl; + u32 emmc_rx_cmd_data_cntl2; + u32 emmc_master_sw_cntl; + u8 pcie_rp_selectable_deemphasis[6]; + u8 monitor_mwait_enable; + u8 hd_audio_dsp_uaa_compliance; + u32 ipc[4]; + u8 sata_ports_disable_dynamic_pg[2]; + u8 init_s3_cpu; + u8 skip_punit_init; + u8 unused_upd_space7[4]; + u8 port_usb20_per_port_tx_pe_half[8]; + u8 port_usb20_per_port_pe_txi_set[8]; + u8 port_usb20_per_port_txi_set[8]; + u8 port_usb20_hs_skew_sel[8]; + u8 port_usb20_i_usb_tx_emphasis_en[8]; + u8 port_usb20_per_port_rxi_set[8]; + u8 port_usb20_hs_npre_drv_sel[8]; + u8 reserved_fsps_upd[16]; +}; + +/** struct fsps_upd - FSP-S Configuration */ +struct __packed fsps_upd { + struct fsp_upd_header header; + struct fsp_s_config config; + u8 unused_upd_space2[46]; + u16 upd_terminator; +}; + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h new file mode 100644 index 0000000000..b14f28b236 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __FSP_VPD_H +#define __FSP_VPD_H + +/* Nothing to declare here for FSP2 */ + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/gpio.h b/arch/x86/include/asm/arch-apollolake/gpio.h new file mode 100644 index 0000000000..10879c168e --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/gpio.h @@ -0,0 +1,485 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Definitions for the GPIO subsystem on Apollolake + * + * Copyright (C) 2015 - 2017 Intel Corp. + * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) + * + * Placed in a separate file since some of these definitions can be used from + * assembly code + * + * Taken from gpio_apl.h in coreboot + */ + +#ifndef _ASM_ARCH_GPIO_H_ +#define _ASM_ARCH_GPIO_H_ + +/* Port ids */ +#define PID_GPIO_SW 0xC0 +#define PID_GPIO_S 0xC2 +#define PID_GPIO_W 0xC7 +#define PID_GPIO_NW 0xC4 +#define PID_GPIO_N 0xC5 +#define PID_ITSS 0xD0 +#define PID_RTC 0xD1 + +/* + * Miscellaneous Configuration register(MISCCFG). These are community-specific + * registers and are meant to house miscellaneous configuration fields per + * community. There are 8 GPIO groups: GPP_0 -> GPP_8 (Group 3 is absent) + */ +#define GPIO_MISCCFG 0x10 /* Miscellaneous Configuration offset */ +#define GPIO_GPE_SW_31_0 0 /* SOUTHWEST GPIO# 0 ~ 31 belong to GROUP0 */ +#define GPIO_GPE_SW_63_32 1 /* SOUTHWEST GPIO# 32 ~ 42 belong to GROUP1 */ +#define GPIO_GPE_W_31_0 2 /* WEST GPIO# 0 ~ 25 belong to GROUP2 */ +#define GPIO_GPE_NW_31_0 4 /* NORTHWEST GPIO# 0 ~ 17 belong to GROUP4 */ +#define GPIO_GPE_NW_63_32 5 /* NORTHWEST GPIO# 32 ~ 63 belong to GROUP5 */ +#define GPIO_GPE_NW_95_64 6 /* NORTHWEST GPIO# 64 ~ 76 belong to GROUP6 */ +#define GPIO_GPE_N_31_0 7 /* NORTH GPIO# 0 ~ 31 belong to GROUP7 */ +#define GPIO_GPE_N_63_32 8 /* NORTH GPIO# 32 ~ 61 belong to GROUP8 */ + +#define GPIO_MAX_NUM_PER_GROUP 32 + +/* + * Host Software Pad Ownership Register. + * The pins in the community are divided into 3 groups: + * GPIO 0 ~ 31, GPIO 32 ~ 63, GPIO 64 ~ 95 + */ +#define HOSTSW_OWN_REG_0 0x80 + +#define PAD_CFG_BASE 0x500 + +#define GPI_INT_STS_0 0x100 +#define GPI_INT_EN_0 0x110 + +#define GPI_SMI_STS_0 0x140 +#define GPI_SMI_EN_0 0x150 + +#define NUM_N_PADS (PAD_N(SVID0_CLK) + 1) +#define NUM_NW_PADS (PAD_NW(GPIO_123) + 1) +#define NUM_W_PADS (PAD_W(SUSPWRDNACK) + 1) +#define NUM_SW_PADS (PAD_SW(LPC_FRAMEB) + 1) + +#define NUM_N_GPI_REGS \ + (ALIGN(NUM_N_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define NUM_NW_GPI_REGS \ + (ALIGN(NUM_NW_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define NUM_W_GPI_REGS \ + (ALIGN(NUM_W_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define NUM_SW_GPI_REGS \ + (ALIGN(NUM_SW_PADS, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +/* + * Total number of GPI status registers across all GPIO communities in the SOC + */ +#define NUM_GPI_STATUS_REGS (NUM_N_GPI_REGS + NUM_NW_GPI_REGS \ + + NUM_W_GPI_REGS + NUM_SW_GPI_REGS) + +/* North community pads */ +#define GPIO_0 0 +#define GPIO_1 1 +#define GPIO_2 2 +#define GPIO_3 3 +#define GPIO_4 4 +#define GPIO_5 5 +#define GPIO_6 6 +#define GPIO_7 7 +#define GPIO_8 8 +#define GPIO_9 9 +#define GPIO_10 10 +#define GPIO_11 11 +#define GPIO_12 12 +#define GPIO_13 13 +#define GPIO_14 14 +#define GPIO_15 15 +#define GPIO_16 16 +#define GPIO_17 17 +#define GPIO_18 18 +#define GPIO_19 19 +#define GPIO_20 20 +#define GPIO_21 21 +#define GPIO_22 22 +#define GPIO_23 23 +#define GPIO_24 24 +#define GPIO_25 25 +#define GPIO_26 26 +#define GPIO_27 27 +#define GPIO_28 28 +#define GPIO_29 29 +#define GPIO_30 30 +#define GPIO_31 31 +#define GPIO_32 32 +#define GPIO_33 33 +#define GPIO_34 34 +#define GPIO_35 35 +#define GPIO_36 36 +#define GPIO_37 37 +#define GPIO_38 38 +#define GPIO_39 39 +#define GPIO_40 40 +#define GPIO_41 41 +#define GPIO_42 42 +#define GPIO_43 43 +#define GPIO_44 44 +#define GPIO_45 45 +#define GPIO_46 46 +#define GPIO_47 47 +#define GPIO_48 48 +#define GPIO_49 49 +#define GPIO_62 50 +#define GPIO_63 51 +#define GPIO_64 52 +#define GPIO_65 53 +#define GPIO_66 54 +#define GPIO_67 55 +#define GPIO_68 56 +#define GPIO_69 57 +#define GPIO_70 58 +#define GPIO_71 59 +#define GPIO_72 60 +#define GPIO_73 61 +#define JTAG_TCK 62 +#define JTAG_TRST_B 63 +#define JTAG_TMS 64 +#define JTAG_TDI 65 +#define JTAG_CX_PMODE 66 +#define JTAG_CX_PREQ_B 67 +#define JTAGX 68 +#define JTAG_CX_PRDY_B 69 +#define JTAG_TDO 70 +#define CNV_BRI_DT 71 +#define CNV_BRI_RSP 72 +#define CNV_RGI_DT 73 +#define CNV_RGI_RSP 74 +#define SVID0_ALERT_B 75 +#define SVID0_DATA 76 +#define SVID0_CLK 77 + +/* Northwest community pads */ +#define GPIO_187 78 +#define GPIO_188 79 +#define GPIO_189 80 +#define GPIO_190 81 +#define GPIO_191 82 +#define GPIO_192 83 +#define GPIO_193 84 +#define GPIO_194 85 +#define GPIO_195 86 +#define GPIO_196 87 +#define GPIO_197 88 +#define GPIO_198 89 +#define GPIO_199 90 +#define GPIO_200 91 +#define GPIO_201 92 +#define GPIO_202 93 +#define GPIO_203 94 +#define GPIO_204 95 +#define PMC_SPI_FS0 96 +#define PMC_SPI_FS1 97 +#define PMC_SPI_FS2 98 +#define PMC_SPI_RXD 99 +#define PMC_SPI_TXD 100 +#define PMC_SPI_CLK 101 +#define PMIC_PWRGOOD 102 +#define PMIC_RESET_B 103 +#define GPIO_213 104 +#define GPIO_214 105 +#define GPIO_215 106 +#define PMIC_THERMTRIP_B 107 +#define PMIC_STDBY 108 +#define PROCHOT_B 109 +#define PMIC_I2C_SCL 110 +#define PMIC_I2C_SDA 111 +#define GPIO_74 112 +#define GPIO_75 113 +#define GPIO_76 114 +#define GPIO_77 115 +#define GPIO_78 116 +#define GPIO_79 117 +#define GPIO_80 118 +#define GPIO_81 119 +#define GPIO_82 120 +#define GPIO_83 121 +#define GPIO_84 122 +#define GPIO_85 123 +#define GPIO_86 124 +#define GPIO_87 125 +#define GPIO_88 126 +#define GPIO_89 127 +#define GPIO_90 128 +#define GPIO_91 129 +#define GPIO_92 130 +#define GPIO_97 131 +#define GPIO_98 132 +#define GPIO_99 133 +#define GPIO_100 134 +#define GPIO_101 135 +#define GPIO_102 136 +#define GPIO_103 137 +#define FST_SPI_CLK_FB 138 +#define GPIO_104 139 +#define GPIO_105 140 +#define GPIO_106 141 +#define GPIO_109 142 +#define GPIO_110 143 +#define GPIO_111 144 +#define GPIO_112 145 +#define GPIO_113 146 +#define GPIO_116 147 +#define GPIO_117 148 +#define GPIO_118 149 +#define GPIO_119 150 +#define GPIO_120 151 +#define GPIO_121 152 +#define GPIO_122 153 +#define GPIO_123 154 + +/* West community pads */ +#define GPIO_124 155 +#define GPIO_125 156 +#define GPIO_126 157 +#define GPIO_127 158 +#define GPIO_128 159 +#define GPIO_129 160 +#define GPIO_130 161 +#define GPIO_131 162 +#define GPIO_132 163 +#define GPIO_133 164 +#define GPIO_134 165 +#define GPIO_135 166 +#define GPIO_136 167 +#define GPIO_137 168 +#define GPIO_138 169 +#define GPIO_139 170 +#define GPIO_146 171 +#define GPIO_147 172 +#define GPIO_148 173 +#define GPIO_149 174 +#define GPIO_150 175 +#define GPIO_151 176 +#define GPIO_152 177 +#define GPIO_153 178 +#define GPIO_154 179 +#define GPIO_155 180 +#define GPIO_209 181 +#define GPIO_210 182 +#define GPIO_211 183 +#define GPIO_212 184 +#define OSC_CLK_OUT_0 185 +#define OSC_CLK_OUT_1 186 +#define OSC_CLK_OUT_2 187 +#define OSC_CLK_OUT_3 188 +#define OSC_CLK_OUT_4 189 +#define PMU_AC_PRESENT 190 +#define PMU_BATLOW_B 191 +#define PMU_PLTRST_B 192 +#define PMU_PWRBTN_B 193 +#define PMU_RESETBUTTON_B 194 +#define PMU_SLP_S0_B 195 +#define PMU_SLP_S3_B 196 +#define PMU_SLP_S4_B 197 +#define PMU_SUSCLK 198 +#define PMU_WAKE_B 199 +#define SUS_STAT_B 200 +#define SUSPWRDNACK 201 + +/* Southwest community pads */ +#define GPIO_205 202 +#define GPIO_206 203 +#define GPIO_207 204 +#define GPIO_208 205 +#define GPIO_156 206 +#define GPIO_157 207 +#define GPIO_158 208 +#define GPIO_159 209 +#define GPIO_160 210 +#define GPIO_161 211 +#define GPIO_162 212 +#define GPIO_163 213 +#define GPIO_164 214 +#define GPIO_165 215 +#define GPIO_166 216 +#define GPIO_167 217 +#define GPIO_168 218 +#define GPIO_169 219 +#define GPIO_170 220 +#define GPIO_171 221 +#define GPIO_172 222 +#define GPIO_179 223 +#define GPIO_173 224 +#define GPIO_174 225 +#define GPIO_175 226 +#define GPIO_176 227 +#define GPIO_177 228 +#define GPIO_178 229 +#define GPIO_186 230 +#define GPIO_182 231 +#define GPIO_183 232 +#define SMB_ALERTB 233 +#define SMB_CLK 234 +#define SMB_DATA 235 +#define LPC_ILB_SERIRQ 236 +#define LPC_CLKOUT0 237 +#define LPC_CLKOUT1 238 +#define LPC_AD0 239 +#define LPC_AD1 240 +#define LPC_AD2 241 +#define LPC_AD3 242 +#define LPC_CLKRUNB 243 +#define LPC_FRAMEB 244 + +/* PERST_0 not defined */ +#define GPIO_PRT0_UDEF 0xFF + +#define TOTAL_PADS 245 +#define N_OFFSET GPIO_0 +#define NW_OFFSET GPIO_187 +#define W_OFFSET GPIO_124 +#define SW_OFFSET GPIO_205 + +/* Macros for translating a global pad offset to a local offset */ +#define PAD_N(pad) (pad - N_OFFSET) +#define PAD_NW(pad) (pad - NW_OFFSET) +#define PAD_W(pad) (pad - W_OFFSET) +#define PAD_SW(pad) (pad - SW_OFFSET) + +/* Linux names of the GPIO devices */ +#define GPIO_COMM_N_NAME "INT3452:00" +#define GPIO_COMM_NW_NAME "INT3452:01" +#define GPIO_COMM_W_NAME "INT3452:02" +#define GPIO_COMM_SW_NAME "INT3452:03" + +/* Following is used in gpio asl */ +#define GPIO_COMM_NAME "INT3452" +#define GPIO_COMM_0_DESC \ + "General Purpose Input/Output (GPIO) Controller - North" +#define GPIO_COMM_1_DESC \ + "General Purpose Input/Output (GPIO) Controller - Northwest" +#define GPIO_COMM_2_DESC \ + "General Purpose Input/Output (GPIO) Controller - West" +#define GPIO_COMM_3_DESC \ + "General Purpose Input/Output (GPIO) Controller - Southwest" + +#define GPIO_COMM0_PID PID_GPIO_N +#define GPIO_COMM1_PID PID_GPIO_NW +#define GPIO_COMM2_PID PID_GPIO_W +#define GPIO_COMM3_PID PID_GPIO_SW + +/* + * IOxAPIC IRQs for the GPIOs, overlap is expected as we encourage to use + * shared IRQ instead of direct IRQ, in case of overlapping, we can easily + * program one of the overlap to shared IRQ to avoid the conflict. + */ + +/* NorthWest community pads */ +#define PMIC_I2C_SDA_IRQ 0x32 +#define GPIO_74_IRQ 0x33 +#define GPIO_75_IRQ 0x34 +#define GPIO_76_IRQ 0x35 +#define GPIO_77_IRQ 0x36 +#define GPIO_78_IRQ 0x37 +#define GPIO_79_IRQ 0x38 +#define GPIO_80_IRQ 0x39 +#define GPIO_81_IRQ 0x3A +#define GPIO_82_IRQ 0x3B +#define GPIO_83_IRQ 0x3C +#define GPIO_84_IRQ 0x3D +#define GPIO_85_IRQ 0x3E +#define GPIO_86_IRQ 0x3F +#define GPIO_87_IRQ 0x40 +#define GPIO_88_IRQ 0x41 +#define GPIO_89_IRQ 0x42 +#define GPIO_90_IRQ 0x43 +#define GPIO_91_IRQ 0x44 +#define GPIO_97_IRQ 0x49 +#define GPIO_98_IRQ 0x4A +#define GPIO_99_IRQ 0x4B +#define GPIO_100_IRQ 0x4C +#define GPIO_101_IRQ 0x4D +#define GPIO_102_IRQ 0x4E +#define GPIO_103_IRQ 0x4F +#define GPIO_104_IRQ 0x50 +#define GPIO_105_IRQ 0x51 +#define GPIO_106_IRQ 0x52 +#define GPIO_109_IRQ 0x54 +#define GPIO_110_IRQ 0x55 +#define GPIO_111_IRQ 0x56 +#define GPIO_112_IRQ 0x57 +#define GPIO_113_IRQ 0x58 +#define GPIO_116_IRQ 0x5B +#define GPIO_117_IRQ 0x5C +#define GPIO_118_IRQ 0x5D +#define GPIO_119_IRQ 0x5E +#define GPIO_120_IRQ 0x5F +#define GPIO_121_IRQ 0x60 +#define GPIO_122_IRQ 0x61 +#define GPIO_123_IRQ 0x62 + +/* North community pads */ +#define GPIO_0_IRQ 0x63 +#define GPIO_1_IRQ 0x64 +#define GPIO_2_IRQ 0x65 +#define GPIO_3_IRQ 0x66 +#define GPIO_4_IRQ 0x67 +#define GPIO_5_IRQ 0x68 +#define GPIO_6_IRQ 0x69 +#define GPIO_7_IRQ 0x6A +#define GPIO_8_IRQ 0x6B +#define GPIO_9_IRQ 0x6C +#define GPIO_10_IRQ 0x6D +#define GPIO_11_IRQ 0x6E +#define GPIO_12_IRQ 0x6F +#define GPIO_13_IRQ 0x70 +#define GPIO_14_IRQ 0x71 +#define GPIO_15_IRQ 0x72 +#define GPIO_16_IRQ 0x73 +#define GPIO_17_IRQ 0x74 +#define GPIO_18_IRQ 0x75 +#define GPIO_19_IRQ 0x76 +#define GPIO_20_IRQ 0x77 +#define GPIO_21_IRQ 0x32 +#define GPIO_22_IRQ 0x33 +#define GPIO_23_IRQ 0x34 +#define GPIO_24_IRQ 0x35 +#define GPIO_25_IRQ 0x36 +#define GPIO_26_IRQ 0x37 +#define GPIO_27_IRQ 0x38 +#define GPIO_28_IRQ 0x39 +#define GPIO_29_IRQ 0x3A +#define GPIO_30_IRQ 0x3B +#define GPIO_31_IRQ 0x3C +#define GPIO_32_IRQ 0x3D +#define GPIO_33_IRQ 0x3E +#define GPIO_34_IRQ 0x3F +#define GPIO_35_IRQ 0x40 +#define GPIO_36_IRQ 0x41 +#define GPIO_37_IRQ 0x42 +#define GPIO_38_IRQ 0x43 +#define GPIO_39_IRQ 0x44 +#define GPIO_40_IRQ 0x45 +#define GPIO_41_IRQ 0x46 +#define GPIO_42_IRQ 0x47 +#define GPIO_43_IRQ 0x48 +#define GPIO_44_IRQ 0x49 +#define GPIO_45_IRQ 0x4A +#define GPIO_46_IRQ 0x4B +#define GPIO_47_IRQ 0x4C +#define GPIO_48_IRQ 0x4D +#define GPIO_49_IRQ 0x4E +#define GPIO_62_IRQ 0x5B +#define GPIO_63_IRQ 0x5C +#define GPIO_64_IRQ 0x5D +#define GPIO_65_IRQ 0x5E +#define GPIO_66_IRQ 0x5F +#define GPIO_67_IRQ 0x60 +#define GPIO_68_IRQ 0x61 +#define GPIO_69_IRQ 0x62 +#define GPIO_70_IRQ 0x63 +#define GPIO_71_IRQ 0x64 +#define GPIO_72_IRQ 0x65 +#define GPIO_73_IRQ 0x66 + +#endif /* _ASM_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/arch-apollolake/iomap.h b/arch/x86/include/asm/arch-apollolake/iomap.h new file mode 100644 index 0000000000..4ce1017055 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/iomap.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017 Intel Corporation. + * Take from coreboot project file of the same name + */ + +#ifndef _ASM_ARCH_IOMAP_H +#define _ASM_ARCH_IOMAP_H + +#define R_ACPI_PM1_TMR 0x8 + +/* Put p2sb at 0xd0000000 in TPL */ +#define IOMAP_P2SB_BAR 0xd0000000 + +#define IOMAP_SPI_BASE 0xfe010000 + +#define IOMAP_ACPI_BASE 0x400 +#define IOMAP_ACPI_SIZE 0x100 + +/* + * Use UART2. To use UART1 you need to set '2' to '1', change device tree serial + * node name and 'reg' property, and update CONFIG_DEBUG_UART_BASE. + */ +#define PCH_DEV_UART PCI_BDF(0, 0x18, 2) + +#define PCH_DEV_LPC PCI_BDF(0, 0x1f, 0) +#define PCH_DEV_SPI PCI_BDF(0, 0x0d, 2) + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/itss.h b/arch/x86/include/asm/arch-apollolake/itss.h new file mode 100644 index 0000000000..1e29503974 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/itss.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017 Intel Corporation. + * Copyright 2019 Google LLC + * + * Modified from coreboot itss.h + */ + +#ifndef _ASM_ARCH_ITSS_H +#define _ASM_ARCH_ITSS_H + +#define GPIO_IRQ_START 50 +#define GPIO_IRQ_END ITSS_MAX_IRQ + +#define ITSS_MAX_IRQ 119 +#define IRQS_PER_IPC 32 +#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC) + +/* Max PXRC registers in ITSS */ +#define MAX_PXRC_CONFIG (PCR_ITSS_PIRQH_ROUT - PCR_ITSS_PIRQA_ROUT + 1) + +/* PIRQA Routing Control Register */ +#define PCR_ITSS_PIRQA_ROUT 0x3100 +/* PIRQB Routing Control Register */ +#define PCR_ITSS_PIRQB_ROUT 0x3101 +/* PIRQC Routing Control Register */ +#define PCR_ITSS_PIRQC_ROUT 0x3102 +/* PIRQD Routing Control Register */ +#define PCR_ITSS_PIRQD_ROUT 0x3103 +/* PIRQE Routing Control Register */ +#define PCR_ITSS_PIRQE_ROUT 0x3104 +/* PIRQF Routing Control Register */ +#define PCR_ITSS_PIRQF_ROUT 0x3105 +/* PIRQG Routing Control Register */ +#define PCR_ITSS_PIRQG_ROUT 0x3106 +/* PIRQH Routing Control Register */ +#define PCR_ITSS_PIRQH_ROUT 0x3107 +/* ITSS Interrupt polarity control */ +#define PCR_ITSS_IPC0_CONF 0x3200 +/* ITSS Power reduction control */ +#define PCR_ITSS_ITSSPRC 0x3300 + +#endif /* _ASM_ARCH_ITSS_H */ diff --git a/arch/x86/include/asm/arch-apollolake/lpc.h b/arch/x86/include/asm/arch-apollolake/lpc.h new file mode 100644 index 0000000000..5d2adad319 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/lpc.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017 Intel Corporation. + * Take from coreboot project file of the same name + */ + +#ifndef _ASM_ARCH_LPC_H +#define _ASM_ARCH_LPC_H + +#define LPC_SERIRQ_CTL 0x64 +#define LPC_SCNT_EN BIT(7) +#define LPC_SCNT_MODE BIT(6) +#define LPC_IO_DECODE 0x80 +#define LPC_IOD_COMA_RANGE (0 << 0) /* 0x3F8 - 0x3FF COMA*/ +#define LPC_IOD_COMB_RANGE (1 << 4) /* 0x2F8 - 0x2FF COMB*/ +/* + * Use IO_<peripheral>_<IO port> style macros defined in lpc_lib.h + * to enable decoding of I/O locations for a peripheral + */ +#define LPC_IO_ENABLES 0x82 +#define LPC_GENERIC_IO_RANGE(n) ((((n) & 0x3) * 4) + 0x84) +#define LPC_LGIR_AMASK_MASK (0xfc << 16) +#define LPC_LGIR_ADDR_MASK 0xfffc +#define LPC_LGIR_EN BIT(0) +#define LPC_LGIR_MAX_WINDOW_SIZE 256 +#define LPC_GENERIC_MEM_RANGE 0x98 +#define LPC_LGMR_ADDR_MASK 0xffff0000 +#define LPC_LGMR_EN BIT(0) +#define LPC_LGMR_WINDOW_SIZE (64 * KiB) +#define LPC_BIOS_CNTL 0xdc +#define LPC_BC_BILD BIT(7) +#define LPC_BC_LE BIT(1) +#define LPC_BC_EISS BIT(5) +#define LPC_PCCTL 0xE0 /* PCI Clock Control */ +#define LPC_PCCTL_CLKRUN_EN BIT(0) + +/* + * IO decode enable macros are in the format IO_<peripheral>_<IO port>. + * For example, to open ports 0x60, 0x64 for the keyboard controller, + * use IOE_KBC_60_64 macro. For IOE_ macros that do not specify a port range, + * the port range is selectable via the IO decodes register. + */ +#define LPC_IOE_EC_4E_4F BIT(13) +#define LPC_IOE_SUPERIO_2E_2F BIT(12) +#define LPC_IOE_EC_62_66 BIT(11) +#define LPC_IOE_KBC_60_64 BIT(10) +#define LPC_IOE_HGE_208 BIT(9) +#define LPC_IOE_LGE_200 BIT(8) +#define LPC_IOE_FDD_EN BIT(3) +#define LPC_IOE_LPT_EN BIT(2) +#define LPC_IOE_COMB_EN BIT(1) +#define LPC_IOE_COMA_EN BIT(0) +#define LPC_NUM_GENERIC_IO_RANGES 4 + +#define LPC_IO_ENABLES 0x82 + +/** + * lpc_enable_fixed_io_ranges() - enable the fixed I/O ranges + * + * @io_enables: Mask of things to enable (LPC_IOE_.) + */ +void lpc_enable_fixed_io_ranges(uint io_enables); + +/** + * lpc_open_pmio_window() - Open an IO port range + * + * @base: Base I/O address (e.g. 0x800) + * @size: Size of window (e.g. 0x100) + * @return 0 if OK, -ENOSPC if there are no more windows available, -EALREADY + * if already set up + */ +int lpc_open_pmio_window(uint base, uint size); + +/** + * lpc_io_setup_comm_a_b() - Set up basic serial UARTs + * + * Set up the LPC to handle I/O to the COMA/COMB serial UART addresses + * 2f8-2ff and 3f8-3ff. + */ +void lpc_io_setup_comm_a_b(void); + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/pch.h b/arch/x86/include/asm/arch-apollolake/pch.h new file mode 100644 index 0000000000..bf3e1670d2 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/pch.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef _ASM_ARCH_PCH_H +#define _ASM_ARCH_PCH_H + +#endif /* _ASM_ARCH_PCH_H */ diff --git a/arch/x86/include/asm/arch-apollolake/pm.h b/arch/x86/include/asm/arch-apollolake/pm.h new file mode 100644 index 0000000000..6718290c4f --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/pm.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.) + */ + +#ifndef _ASM_ARCH_PM_H +#define _ASM_ARCH_PM_H + +#define PMC_GPE_SW_31_0 0 +#define PMC_GPE_SW_63_32 1 +#define PMC_GPE_NW_31_0 3 +#define PMC_GPE_NW_63_32 4 +#define PMC_GPE_NW_95_64 5 +#define PMC_GPE_N_31_0 6 +#define PMC_GPE_N_63_32 7 +#define PMC_GPE_W_31_0 9 + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/systemagent.h b/arch/x86/include/asm/arch-apollolake/systemagent.h new file mode 100644 index 0000000000..206d8903fa --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/systemagent.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017 Intel Corporation. + * Take from coreboot project file of the same name + */ + +#ifndef _ASM_ARCH_SYSTEMAGENT_H +#define _ASM_ARCH_SYSTEMAGENT_H + +/* Device 0:0.0 PCI configuration space */ +#define MCHBAR 0x48 + +/* RAPL Package Power Limit register under MCHBAR */ +#define PUNIT_THERMAL_DEVICE_IRQ 0x700C +#define PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER 0x18 +#define PUINT_THERMAL_DEVICE_IRQ_LOCK 0x80000000 +#define BIOS_RESET_CPL 0x7078 +#define PCODE_INIT_DONE BIT(8) +#define MCHBAR_RAPL_PPL 0x70A8 +#define CORE_DISABLE_MASK 0x7168 +#define CAPID0_A 0xE4 +#define VTD_DISABLE BIT(23) +#define DEFVTBAR 0x6c80 +#define GFXVTBAR 0x6c88 +#define VTBAR_ENABLED 0x01 +#define VTBAR_MASK GENMASK_ULL(39, 12) +#define VTBAR_SIZE 0x1000 + +/** + * enable_bios_reset_cpl() - Tell the system agent that memory/power are ready + * + * This should be called when U-Boot has set up the memory and power + * management. + */ +void enable_bios_reset_cpl(void); + +#endif diff --git a/arch/x86/include/asm/arch-apollolake/uart.h b/arch/x86/include/asm/arch-apollolake/uart.h new file mode 100644 index 0000000000..d4fffe6525 --- /dev/null +++ b/arch/x86/include/asm/arch-apollolake/uart.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef _ASM_ARCH_UART_H +#define _ASM_ARCH_UART_H + +/** + * apl_uart_init() - Set up the APL UART device and clock + * + * This enables the PCI device, sets up the MMIO region and turns on the clock + * using LPSS. + * + * The UART won't actually work unless the GPIO settings are correct and the + * signals actually exit the SoC. See board_debug_uart_init() for that. + */ +int apl_uart_init(pci_dev_t bdf, ulong base); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/cpu.h b/arch/x86/include/asm/arch-broadwell/cpu.h index 3bc3bd6609..2b39a76fbd 100644 --- a/arch/x86/include/asm/arch-broadwell/cpu.h +++ b/arch/x86/include/asm/arch-broadwell/cpu.h @@ -27,7 +27,6 @@ #define MSR_VR_CURRENT_CONFIG 0x601 #define MSR_VR_MISC_CONFIG 0x603 -#define MSR_PKG_POWER_SKU 0x614 #define MSR_DDR_RAPL_LIMIT 0x618 #define MSR_VR_MISC_CONFIG2 0x636 diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h index 4839ebc312..5c066294bc 100644 --- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h +++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h @@ -43,7 +43,6 @@ #define MSR_PP1_CURRENT_CONFIG 0x602 #define PP1_CURRENT_LIMIT_SNB (35 << 3) /* 35 A */ #define PP1_CURRENT_LIMIT_IVB (50 << 3) /* 50 A */ -#define MSR_PKG_POWER_SKU 0x614 #define IVB_CONFIG_TDP_MIN_CPUID 0x306a2 #define MSR_CONFIG_TDP_LEVEL1 0x649 diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h new file mode 100644 index 0000000000..6894298526 --- /dev/null +++ b/arch/x86/include/asm/fast_spi.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 Intel Corporation. + */ + +#ifndef ASM_FAST_SPI_H +#define ASM_FAST_SPI_H + +/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs { + u32 bfp; + u32 hsfsts_ctl; + u32 faddr; + u32 dlock; + + u32 fdata[0x10]; + + u32 fracc; + u32 freg[12]; + u32 fpr[5]; + u32 gpr0; + u32 spare2; + u32 sts_ctl; + u16 preop; + u16 optype; + u8 opmenu[8]; + + u32 spare3; + u32 fdoc; + u32 fdod; + u32 spare4; + u32 afc; + u32 vscc[2]; + u32 ptinx; + u32 ptdata; +}; +check_member(fast_spi_regs, ptdata, 0xd0); + +/* Bit definitions for BFPREG (0x00) register */ +#define SPIBAR_BFPREG_PRB_MASK 0x7fff +#define SPIBAR_BFPREG_PRL_SHIFT 16 +#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT) + +/* PCI configuration registers */ +#define SPIBAR_BIOS_CONTROL 0xdc +#define SPIBAR_BIOS_CONTROL_WPD BIT(0) +#define SPIBAR_BIOS_CONTROL_LOCK_ENABLE BIT(1) +#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE BIT(2) +#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE BIT(3) +#define SPIBAR_BIOS_CONTROL_EISS BIT(5) +#define SPIBAR_BIOS_CONTROL_BILD BIT(7) + +/** + * fast_spi_get_bios_mmap() - Get memory map for SPI flash + * + * @pdev: PCI device to use (this is the Fast SPI device) + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 (always) + */ +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp); + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base); + +#endif /* ASM_FAST_SPI_H */ diff --git a/arch/x86/include/asm/fsp/fsp_api.h b/arch/x86/include/asm/fsp/fsp_api.h new file mode 100644 index 0000000000..e9ac86b2da --- /dev/null +++ b/arch/x86/include/asm/fsp/fsp_api.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __ASM_FSP_API_H +#define __ASM_FSP_API_H + +enum fsp_phase { + /* Notification code for post PCI enuermation */ + INIT_PHASE_PCI = 0x20, + /* Notification code before transferring control to the payload */ + INIT_PHASE_BOOT = 0x40 +}; + +struct fsp_notify_params { + /* Notification phase used for NotifyPhase API */ + enum fsp_phase phase; +}; + +/* FspNotify API function prototype */ +typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params); + +#endif diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h index 4ac27d26f5..29e511415c 100644 --- a/arch/x86/include/asm/fsp/fsp_support.h +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -144,13 +144,6 @@ int fsp_init_phase_pci(void); int fsp_scan_for_ram_size(void); /** - * fsp_prepare_mrc_cache() - Find the DRAM training data from the MRC cache - * - * @return pointer to data, or NULL if no cache or no data found in the cache - */ -void *fsp_prepare_mrc_cache(void); - -/** * fsp_notify() - FSP notification wrapper function * * @fsp_hdr: Pointer to FSP information header diff --git a/arch/x86/include/asm/fsp1/fsp_api.h b/arch/x86/include/asm/fsp1/fsp_api.h index f2d70799f3..524da5feb7 100644 --- a/arch/x86/include/asm/fsp1/fsp_api.h +++ b/arch/x86/include/asm/fsp1/fsp_api.h @@ -4,11 +4,11 @@ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> */ -#ifndef __FSP_API_H__ -#define __FSP_API_H__ +#ifndef __FSP1_API_H__ +#define __FSP1_API_H__ #include <linux/linkage.h> - +#include <asm/fsp/fsp_api.h> /* * FSP common configuration structure. * This needs to be included in the platform-specific struct fsp_config_data. @@ -46,22 +46,7 @@ struct common_buf { u32 reserved[6]; /* Reserved */ }; -enum fsp_phase { - /* Notification code for post PCI enuermation */ - INIT_PHASE_PCI = 0x20, - /* Notification code before transfering control to the payload */ - INIT_PHASE_BOOT = 0x40 -}; - -struct fsp_notify_params { - /* Notification phase used for NotifyPhase API */ - enum fsp_phase phase; -}; - /* FspInit API function prototype */ typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params); -/* FspNotify API function prototype */ -typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params); - #endif diff --git a/arch/x86/include/asm/fsp2/fsp_api.h b/arch/x86/include/asm/fsp2/fsp_api.h new file mode 100644 index 0000000000..af1e8857b9 --- /dev/null +++ b/arch/x86/include/asm/fsp2/fsp_api.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.) + * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) + * Mostly taken from coreboot fsp2_0/memory_init.c + */ + +#ifndef __ASM_FSP2_API_H +#define __ASM_FSP2_API_H + +#include <asm/fsp/fsp_api.h> + +struct fspm_upd; +struct fsps_upd; +struct hob_header; + +enum fsp_boot_mode { + FSP_BOOT_WITH_FULL_CONFIGURATION = 0x00, + FSP_BOOT_WITH_MINIMAL_CONFIGURATION = 0x01, + FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES = 0x02, + FSP_BOOT_ON_S4_RESUME = 0x05, + FSP_BOOT_ON_S3_RESUME = 0x11, + FSP_BOOT_ON_FLASH_UPDATE = 0x12, + FSP_BOOT_IN_RECOVERY_MODE = 0x20 +}; + +struct __packed fsp_upd_header { + u64 signature; + u8 revision; + u8 reserved[23]; +}; + +/** + * fsp_memory_init() - Init the SDRAM + * + * @s3wake: true if we are booting from resume, so cannot reinit the mememory + * from scatch since we will lose its contents + * @use_spi_flash: true to use the fast SPI driver to read FSP, otherwise use + * mapped SPI + * @return 0 if OK, -ve on error + */ +int fsp_memory_init(bool s3wake, bool use_spi_flash); + +typedef asmlinkage int (*fsp_memory_init_func)(struct fspm_upd *params, + struct hob_header **hobp); + +/** + * fsp_silicon_init() - Init the silicon + * + * This calls the FSP's 'silicon init' entry point + * + * @s3wake: true if we are booting from resume, so cannot reinit the mememory + * from scatch since we will lose its contents + * @use_spi_flash: true to use the fast SPI driver to read FSP, otherwise use + * mapped SPI + * @return 0 if OK, -ve on error + */ +int fsp_silicon_init(bool s3wake, bool use_spi_flash); + +typedef asmlinkage int (*fsp_silicon_init_func)(struct fsps_upd *params); + +#endif diff --git a/arch/x86/include/asm/fsp2/fsp_internal.h b/arch/x86/include/asm/fsp2/fsp_internal.h new file mode 100644 index 0000000000..f751fbf961 --- /dev/null +++ b/arch/x86/include/asm/fsp2/fsp_internal.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) + * Mostly taken from coreboot + */ + +#ifndef __ASM_FSP_INTERNAL_H +#define __ASM_FSP_INTERNAL_H + +struct binman_entry; +struct fsp_header; +struct fspm_upd; +struct fsps_upd; + +enum fsp_type_t { + FSP_M, + FSP_S, +}; + +int fsp_get_header(ulong offset, ulong size, bool use_spi_flash, + struct fsp_header **fspp); + +/** + * fsp_locate_fsp() - Locate an FSP component + * + * This finds an FSP component by various methods. It is not as general-purpose + * as it looks, since it expects FSP-M to be requested in SPL (only), and FSP-S + * to be requested in U-Boot proper. + * + * @type: Component to locate + * @entry: Returns location of component + * @use_spi_flash: true to read using the Fast SPI driver, false to use + * memory-mapped SPI flash + * @devp: Returns northbridge device + * @hdrp: Returns FSP header + * @rom_offsetp: If non-NULL, returns the offset to add to any image position to + * find the memory-mapped location of that position. For example, for ROM + * position 0x1000, it will be mapped into 0x1000 + *rom_offsetp. + */ +int fsp_locate_fsp(enum fsp_type_t type, struct binman_entry *entry, + bool use_spi_flash, struct udevice **devp, + struct fsp_header **hdrp, ulong *rom_offsetp); + +/** + * arch_fsps_preinit() - Perform init needed before calling FSP-S + * + * This allows use of probed drivers and PCI so is a convenient place to do any + * init that is needed before FSP-S is called. After this, U-Boot relocates and + * calls arch_fsp_init_r() before PCI is probed, and that function is not + * allowed to probe PCI before calling FSP-S. + */ +int arch_fsps_preinit(void); + +/** + * fspm_update_config() - Set up the config structure for FSP-M + * + * @dev: Hostbridge device containing config + * @upd: Config data to fill in + * @return 0 if OK, -ve on error + */ +int fspm_update_config(struct udevice *dev, struct fspm_upd *upd); + +/** + * fspm_done() - Indicate that memory init is complete + * + * This allows the board to do whatever post-init it needs before things + * continue. + * + * @dev: Hostbridge device + * @return 0 if OK, -ve on error + */ +int fspm_done(struct udevice *dev); + +/** + * fsps_update_config() - Set up the config structure for FSP-S + * + * @dev: Hostbridge device containing config + * @rom_offset: Value to add to convert from ROM offset to memory-mapped address + * @upd: Config data to fill in + * @return 0 if OK, -ve on error + */ +int fsps_update_config(struct udevice *dev, ulong rom_offset, + struct fsps_upd *upd); + +/** + * prepare_mrc_cache() - Read the MRC cache into the product-data struct + * + * This looks for cached Memory-reference code (MRC) data and stores it into + * @upd for use by the FSP-M binary. + * + * @return 0 if OK, -ENOENT if no data (whereupon the caller can continue and + * expect a slower boot), other -ve value on other error + */ +int prepare_mrc_cache(struct fspm_upd *upd); + +#endif diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 7f3ada06f6..f4c1839104 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -10,6 +10,7 @@ #ifndef __ASSEMBLY__ #include <asm/processor.h> +#include <asm/mrccache.h> enum pei_boot_mode_t { PEI_BOOT_NONE = 0, @@ -66,6 +67,21 @@ struct mtrr_request { uint64_t size; }; +/** + * struct mrc_output - holds the MRC data + * + * @buf: MRC training data to save for the next boot. This is set to point to + * the raw data after SDRAM init is complete. Then mrccache_setup() + * turns it into a proper cache record with a checksum + * @len: Length of @buf + * @cache: Resulting cache record + */ +struct mrc_output { + char *buf; + uint len; + struct mrc_data_container *cache; +}; + /* Architecture-specific global data */ struct arch_global_data { u64 gdt[X86_GDT_NUM_ENTRIES] __aligned(16); @@ -90,12 +106,12 @@ struct arch_global_data { struct mtrr_request mtrr_req[MAX_MTRR_REQUESTS]; int mtrr_req_count; int has_mtrr; - /* MRC training data to save for the next boot */ - char *mrc_output; - unsigned int mrc_output_len; + /* MRC training data */ + struct mrc_output mrc[MRC_TYPE_COUNT]; ulong table; /* Table pointer from previous loader */ int turbo_state; /* Current turbo state */ struct irq_routing_table *pirq_routing_table; + int dw_i2c_num_cards; /* Used by designware i2c driver */ #ifdef CONFIG_SEABIOS u32 high_table_ptr; u32 high_table_limit; @@ -104,6 +120,9 @@ struct arch_global_data { int prev_sleep_state; /* Previous sleep state ACPI_S0/1../5 */ ulong backup_mem; /* Backup memory address for S3 */ #endif +#ifdef CONFIG_FSP_VERSION2 + struct fsp_header *fsp_s_hdr; /* Pointer to FSP-S header */ +#endif }; #endif diff --git a/arch/x86/include/asm/intel_pinctrl.h b/arch/x86/include/asm/intel_pinctrl.h new file mode 100644 index 0000000000..72fd9246cb --- /dev/null +++ b/arch/x86/include/asm/intel_pinctrl.h @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2017 Intel Corporation. + * Copyright 2019 Google LLC + * + * Modified from coreboot gpio.h + */ + +#ifndef __ASM_INTEL_PINCTRL_H +#define __ASM_INTEL_PINCTRL_H + +#include <dm/pinctrl.h> + +/** + * struct pad_config - config for a pad + * @pad: offset of pad within community + * @pad_config: Pad config data corresponding to DW0, DW1, etc. + */ +struct pad_config { + int pad; + u32 pad_config[4]; +}; + +#include <asm/arch/gpio.h> + +/* GPIO community IOSF sideband clock gating */ +#define MISCCFG_GPSIDEDPCGEN BIT(5) +/* GPIO community RCOMP clock gating */ +#define MISCCFG_GPRCOMPCDLCGEN BIT(4) +/* GPIO community RTC clock gating */ +#define MISCCFG_GPRTCDLCGEN BIT(3) +/* GFX controller clock gating */ +#define MISCCFG_GSXSLCGEN BIT(2) +/* GPIO community partition clock gating */ +#define MISCCFG_GPDPCGEN BIT(1) +/* GPIO community local clock gating */ +#define MISCCFG_GPDLCGEN BIT(0) +/* Enable GPIO community power management configuration */ +#define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \ + MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \ + | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN) + +/* + * GPIO numbers may not be contiguous and instead will have a different + * starting pin number for each pad group. + */ +#define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ + group_pad_base) \ + { \ + .first_pad = (start_of_group) - (first_of_community), \ + .size = (end_of_group) - (start_of_group) + 1, \ + .acpi_pad_base = (group_pad_base), \ + } + +/* + * A pad base of -1 indicates that this group uses contiguous numbering + * and a pad base should not be used for this group. + */ +#define PAD_BASE_NONE -1 + +/* The common/default group numbering is contiguous */ +#define INTEL_GPP(first_of_community, start_of_group, end_of_group) \ + INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ + PAD_BASE_NONE) + +/** + * struct reset_mapping - logical to actual value for PADRSTCFG in DW0 + * + * Note that the values are expected to be within the field placement of the + * register itself. i.e. if the reset field is at 31:30 then the values within + * logical and chipset should occupy 31:30. + */ +struct reset_mapping { + u32 logical; + u32 chipset; +}; + +/** + * struct pad_group - describes the groups within each community + * + * @first_pad: offset of first pad of the group relative to the community + * @size: size of the group + * @acpi_pad_base: starting pin number for the pads in this group when they are + * used in ACPI. This is only needed if the pins are not contiguous across + * groups. Most groups will have this set to PAD_BASE_NONE and use + * contiguous numbering for ACPI. + */ +struct pad_group { + int first_pad; + uint size; + int acpi_pad_base; +}; + +/** + * struct pad_community - community of pads + * + * This describes a community, or each group within a community when multiple + * groups exist inside a community + * + * @name: Community name + * @acpi_path: ACPI path + * @num_gpi_regs: number of gpi registers in community + * @max_pads_per_group: number of pads in each group; number of pads bit-mapped + * in each GPI status/en and Host Own Reg + * @first_pad: first pad in community + * @last_pad: last pad in community + * @host_own_reg_0: offset to Host Ownership Reg 0 + * @gpi_int_sts_reg_0: offset to GPI Int STS Reg 0 + * @gpi_int_en_reg_0: offset to GPI Int Enable Reg 0 + * @gpi_smi_sts_reg_0: offset to GPI SMI STS Reg 0 + * @gpi_smi_en_reg_0: offset to GPI SMI EN Reg 0 + * @pad_cfg_base: offset to first PAD_GFG_DW0 Reg + * @gpi_status_offset: specifies offset in struct gpi_status + * @port: PCR Port ID + * @reset_map: PADRSTCFG logical to chipset mapping + * @num_reset_vals: number of values in @reset_map + * @groups; list of groups for this community + * @num_groups: number of groups + */ +struct pad_community { + const char *name; + const char *acpi_path; + size_t num_gpi_regs; + size_t max_pads_per_group; + uint first_pad; + uint last_pad; + u16 host_own_reg_0; + u16 gpi_int_sts_reg_0; + u16 gpi_int_en_reg_0; + u16 gpi_smi_sts_reg_0; + u16 gpi_smi_en_reg_0; + u16 pad_cfg_base; + u8 gpi_status_offset; + u8 port; + const struct reset_mapping *reset_map; + size_t num_reset_vals; + const struct pad_group *groups; + size_t num_groups; +}; + +/** + * struct intel_pinctrl_priv - private data for each pinctrl device + * + * @comm: Pad community for this device + * @num_cfgs: Number of configuration words for each pad + * @itss: ITSS device (for interrupt handling) + * @itss_pol_cfg: Use to program Interrupt Polarity Control (IPCx) register + * Each bit represents IRQx Active High Polarity Disable configuration: + * when set to 1, the interrupt polarity associated with IRQx is inverted + * to appear as Active Low to IOAPIC and vice versa + */ +struct intel_pinctrl_priv { + const struct pad_community *comm; + int num_cfgs; + struct udevice *itss; + bool itss_pol_cfg; +}; + +/* Exported common operations for the pinctrl driver */ +extern const struct pinctrl_ops intel_pinctrl_ops; + +/* Exported common probe function for the pinctrl driver */ +int intel_pinctrl_probe(struct udevice *dev); + +/** + * intel_pinctrl_ofdata_to_platdata() - Handle common platdata setup + * + * @dev: Pinctrl device + * @comm: Pad community for this device + * @num_cfgs: Number of configuration words for each pad + * @return 0 if OK, -EDOM if @comm is NULL, other -ve value on other error + */ +int intel_pinctrl_ofdata_to_platdata(struct udevice *dev, + const struct pad_community *comm, + int num_cfgs); + +/** + * pinctrl_route_gpe() - set GPIO groups for the general-purpose-event blocks + * + * The values from PMC register GPE_CFG are passed which is then mapped to + * proper groups for MISCCFG. This basically sets the MISCCFG register bits: + * dw0 = gpe0_route[11:8]. This is ACPI GPE0b. + * dw1 = gpe0_route[15:12]. This is ACPI GPE0c. + * dw2 = gpe0_route[19:16]. This is ACPI GPE0d. + * + * @dev: ITSS device + * @gpe0b: Value for GPE0B + * @gpe0c: Value for GPE0C + * @gpe0d: Value for GPE0D + * @return 0 if OK, -ve on error + */ +int pinctrl_route_gpe(struct udevice *dev, uint gpe0b, uint gpe0c, uint gpe0d); + +/** + * pinctrl_config_pads() - Configure a list of pads + * + * Configures multiple pads using the provided data from the device tree. + * + * @dev: pinctrl device (any will do) + * @pads: Pad data, consisting of a pad number followed by num_cfgs entries + * containing the data for that pad (num_cfgs is set by the pinctrl device) + * @pads_count: Number of pads to configure + * @return 0 if OK, -ve on error + */ +int pinctrl_config_pads(struct udevice *dev, u32 *pads, int pads_count); + +/** + * pinctrl_gpi_clear_int_cfg() - Set up the interrupts for use + * + * This enables the interrupt inputs and clears the status register bits + * + * @return 0 if OK, -ve on error + */ +int pinctrl_gpi_clear_int_cfg(void); + +/** + * pinctrl_config_pads_for_node() - Configure pads + * + * Set up the pads using the data in a given node + * + * @dev: pinctrl device (any will do) + * @node: Node containing the 'pads' property with the data in it + * @return 0 if OK, -ve on error + */ +int pinctrl_config_pads_for_node(struct udevice *dev, ofnode node); + +/** + * pinctrl_read_pads() - Read pad data from a node + * + * @dev: pinctrl device (any will do, it is just used to get config) + * @node: Node to read pad data from + * @prop: Property name to use (e.g. "pads") + * @padsp: Returns a pointer to an allocated array of pad data, in the format: + * <pad> + * <pad_config0> + * <pad_config1> + * ... + * + * The number of pad config values is set by the pinctrl controller. + * The caller must free this array. + * @pad_countp: Returns the number of pads read + * @ereturn 0 if OK, -ve on error + */ +int pinctrl_read_pads(struct udevice *dev, ofnode node, const char *prop, + u32 **padsp, int *pad_countp); + +/** + * pinctrl_count_pads() - Count the number of pads in a pad array + * + * This used used with of-platdata where the array may be smaller than its + * maximum size. This function searches for the last pad in the array by finding + * the first 'zero' record + * + * This works out the number of records in the array. Each record has one word + * for the pad and num_cfgs words for the config. + * + * @dev: pinctrl device (any will do) + * @pads: Array of pad data + * @size: Size of pad data in bytes + * @return number of pads represented by the data + */ +int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size); + +/** + * intel_pinctrl_get_config_reg_addr() - Get address of the pin config registers + * + * @dev: Pinctrl device + * @offset: GPIO offset within this device + * @return register offset within the GPIO p2sb region + */ +u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset); + +/** + * intel_pinctrl_get_config_reg() - Get the value of a GPIO register + * + * @dev: Pinctrl device + * @offset: GPIO offset within this device + * @return register value within the GPIO p2sb region + */ +u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint offset); + +/** + * intel_pinctrl_get_pad() - Get pad information for a pad + * + * This is used by the GPIO controller to find the pinctrl used by a pad. + * + * @pad: Pad to check + * @devp: Returns pinctrl device containing that pad + * @offsetp: Returns offset of pad within that pinctrl device + */ +int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp); + +/** + * intel_pinctrl_get_acpi_pin() - Get the ACPI pin for a pinctrl pin + * + * Maps a pinctrl pin (in terms of its offset within the pins controlled by that + * pinctrl) to an ACPI GPIO pin-table entry. + * + * @dev: Pinctrl device to check + * @offset: Offset of pin within that device (0 = first) + * @return associated ACPI GPIO pin-table entry, or standard pin number if the + * ACPI pad base is not set + */ +int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint offset); + +#endif diff --git a/arch/x86/include/asm/intel_pinctrl_defs.h b/arch/x86/include/asm/intel_pinctrl_defs.h new file mode 100644 index 0000000000..6da06bb52b --- /dev/null +++ b/arch/x86/include/asm/intel_pinctrl_defs.h @@ -0,0 +1,373 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015-2016 Intel Corp. + * Copyright 2019 Google LLC + * + * Modified from coreboot gpio_defs.h + */ + +#ifndef _ASM_INTEL_PINCTRL_DEFS_H_ +#define _ASM_INTEL_PINCTRL_DEFS_H_ + +/* This file is included by device trees, so avoid BIT() macros */ + +#define PAD_CFG0_TX_STATE_BIT 0 +#define PAD_CFG0_TX_STATE (1 << PAD_CFG0_TX_STATE_BIT) +#define PAD_CFG0_RX_STATE_BIT 1 +#define PAD_CFG0_RX_STATE (1 << PAD_CFG0_RX_STATE_BIT) +#define PAD_CFG0_TX_DISABLE (1 << 8) +#define PAD_CFG0_RX_DISABLE (1 << 9) + +#define PAD_CFG0_MODE_SHIFT 10 +#define PAD_CFG0_MODE_MASK (7 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_GPIO (0 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF1 (1 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF2 (2 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF3 (3 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF4 (4 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF5 (5 << PAD_CFG0_MODE_SHIFT) +#define PAD_CFG0_MODE_NF6 (6 << PAD_CFG0_MODE_SHIFT) + +#define PAD_CFG0_ROUTE_MASK (0xf << 17) +#define PAD_CFG0_ROUTE_NMI (1 << 17) +#define PAD_CFG0_ROUTE_SMI (1 << 18) +#define PAD_CFG0_ROUTE_SCI (1 << 19) +#define PAD_CFG0_ROUTE_IOAPIC (1 << 20) +#define PAD_CFG0_RXTENCFG_MASK (3 << 21) +#define PAD_CFG0_RXINV_MASK (1 << 23) +#define PAD_CFG0_RX_POL_INVERT (1 << 23) +#define PAD_CFG0_RX_POL_NONE (0 << 23) +#define PAD_CFG0_PREGFRXSEL (1 << 24) +#define PAD_CFG0_TRIG_MASK (3 << 25) +#define PAD_CFG0_TRIG_LEVEL (0 << 25) +#define PAD_CFG0_TRIG_EDGE_SINGLE (1 << 25) /* controlled by RX_INVERT*/ +#define PAD_CFG0_TRIG_OFF (2 << 25) +#define PAD_CFG0_TRIG_EDGE_BOTH (3 << 25) +#define PAD_CFG0_RXRAW1_MASK (1 << 28) +#define PAD_CFG0_RXPADSTSEL_MASK (1 << 29) +#define PAD_CFG0_RESET_MASK (3 << 30) +#define PAD_CFG0_LOGICAL_RESET_PWROK (0U << 30) +#define PAD_CFG0_LOGICAL_RESET_DEEP (1U << 30) +#define PAD_CFG0_LOGICAL_RESET_PLTRST (2U << 30) +#define PAD_CFG0_LOGICAL_RESET_RSMRST (3U << 30) + +/* + * Use the fourth bit in IntSel field to indicate gpio ownership. This field is + * RO and hence not used during gpio configuration. + */ +#define PAD_CFG1_GPIO_DRIVER (0x1 << 4) +#define PAD_CFG1_IRQ_MASK (0xff << 0) +#define PAD_CFG1_IOSTERM_MASK (0x3 << 8) +#define PAD_CFG1_IOSTERM_SAME (0x0 << 8) +#define PAD_CFG1_IOSTERM_DISPUPD (0x1 << 8) +#define PAD_CFG1_IOSTERM_ENPD (0x2 << 8) +#define PAD_CFG1_IOSTERM_ENPU (0x3 << 8) +#define PAD_CFG1_PULL_MASK (0xf << 10) +#define PAD_CFG1_PULL_NONE (0x0 << 10) +#define PAD_CFG1_PULL_DN_5K (0x2 << 10) +#define PAD_CFG1_PULL_DN_20K (0x4 << 10) +#define PAD_CFG1_PULL_UP_1K (0x9 << 10) +#define PAD_CFG1_PULL_UP_5K (0xa << 10) +#define PAD_CFG1_PULL_UP_2K (0xb << 10) +#define PAD_CFG1_PULL_UP_20K (0xc << 10) +#define PAD_CFG1_PULL_UP_667 (0xd << 10) +#define PAD_CFG1_PULL_NATIVE (0xf << 10) + +/* Tx enabled driving last value driven, Rx enabled */ +#define PAD_CFG1_IOSSTATE_TX_LAST_RXE (0x0 << 14) +/* + * Tx enabled driving 0, Rx disabled and Rx driving 0 back to its controller + * internally + */ +#define PAD_CFG1_IOSSTATE_TX0_RX_DCR_X0 (0x1 << 14) +/* + * Tx enabled driving 0, Rx disabled and Rx driving 1 back to its controller + * internally + */ +#define PAD_CFG1_IOSSTATE_TX0_RX_DCR_X1 (0x2 << 14) +/* + * Tx enabled driving 1, Rx disabled and Rx driving 0 back to its controller + * internally + */ +#define PAD_CFG1_IOSSTATE_TX1_RX_DCR_X0 (0x3 << 14) +/* + * Tx enabled driving 1, Rx disabled and Rx driving 1 back to its controller + * internally + */ +#define PAD_CFG1_IOSSTATE_TX1_RX_DCR_X1 (0x4 << 14) +/* Tx enabled driving 0, Rx enabled */ +#define PAD_CFG1_IOSSTATE_TX0_RXE (0x5 << 14) +/* Tx enabled driving 1, Rx enabled */ +#define PAD_CFG1_IOSSTATE_TX1_RXE (0x6 << 14) +/* Hi-Z, Rx driving 0 back to its controller internally */ +#define PAD_CFG1_IOSSTATE_HIZCRX0 (0x7 << 14) +/* Hi-Z, Rx driving 1 back to its controller internally */ +#define PAD_CFG1_IOSSTATE_HIZCRX1 (0x8 << 14) +/* Tx disabled, Rx enabled */ +#define PAD_CFG1_IOSSTATE_TXD_RXE (0x9 << 14) +#define PAD_CFG1_IOSSTATE_IGNORE (0xf << 14) /* Ignore Iostandby */ +/* mask to extract Iostandby bits */ +#define PAD_CFG1_IOSSTATE_MASK (0xf << 14) +#define PAD_CFG1_IOSSTATE_SHIFT 14 /* set Iostandby bits [17:14] */ + +#define PAD_CFG2_DEBEN 1 +/* Debounce Duration = (2 ^ PAD_CFG2_DEBOUNCE_x_RTC) * RTC clock duration */ +#define PAD_CFG2_DEBOUNCE_8_RTC (0x3 << 1) +#define PAD_CFG2_DEBOUNCE_16_RTC (0x4 << 1) +#define PAD_CFG2_DEBOUNCE_32_RTC (0x5 << 1) +#define PAD_CFG2_DEBOUNCE_64_RTC (0x6 << 1) +#define PAD_CFG2_DEBOUNCE_128_RTC (0x7 << 1) +#define PAD_CFG2_DEBOUNCE_256_RTC (0x8 << 1) +#define PAD_CFG2_DEBOUNCE_512_RTC (0x9 << 1) +#define PAD_CFG2_DEBOUNCE_1K_RTC (0xa << 1) +#define PAD_CFG2_DEBOUNCE_2K_RTC (0xb << 1) +#define PAD_CFG2_DEBOUNCE_4K_RTC (0xc << 1) +#define PAD_CFG2_DEBOUNCE_8K_RTC (0xd << 1) +#define PAD_CFG2_DEBOUNCE_16K_RTC (0xe << 1) +#define PAD_CFG2_DEBOUNCE_32K_RTC (0xf << 1) +#define PAD_CFG2_DEBOUNCE_MASK 0x1f + +/* voltage tolerance 0=3.3V default 1=1.8V tolerant */ +#if IS_ENABLED(INTEL_PINCTRL_IOSTANDBY) +#define PAD_CFG1_TOL_MASK (0x1 << 25) +#define PAD_CFG1_TOL_1V8 (0x1 << 25) +#endif + +#define PAD_FUNC(value) PAD_CFG0_MODE_##value +#define PAD_RESET(value) PAD_CFG0_LOGICAL_RESET_##value +#define PAD_PULL(value) PAD_CFG1_PULL_##value + +#define PAD_IOSSTATE(value) PAD_CFG1_IOSSTATE_##value +#define PAD_IOSTERM(value) PAD_CFG1_IOSTERM_##value + +#define PAD_IRQ_CFG(route, trig, inv) \ + (PAD_CFG0_ROUTE_##route | \ + PAD_CFG0_TRIG_##trig | \ + PAD_CFG0_RX_POL_##inv) + +#if IS_ENABLED(INTEL_PINCTRL_DUAL_ROUTE_SUPPORT) +#define PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv) \ + (PAD_CFG0_ROUTE_##route1 | \ + PAD_CFG0_ROUTE_##route2 | \ + PAD_CFG0_TRIG_##trig | \ + PAD_CFG0_RX_POL_##inv) +#endif /* CONFIG_INTEL_PINCTRL_DUAL_ROUTE_SUPPORT */ + +#define _PAD_CFG_STRUCT(__pad, __config0, __config1) \ + __pad(__config0) (__config1) + +/* Native function configuration */ +#define PAD_CFG_NF(pad, pull, rst, func) \ + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \ + PAD_IOSSTATE(TX_LAST_RXE)) + +#if IS_ENABLED(CONFIG_INTEL_GPIO_PADCFG_PADTOL) +/* + * Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. Not + * applicable to all SOCs. Refer EDS. + */ +#define PAD_CFG_NF_1V8(pad, pull, rst, func) \ + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) |\ + PAD_IOSSTATE(TX_LAST_RXE) | PAD_CFG1_TOL_1V8) +#endif + +/* Native function configuration for standby state */ +#define PAD_CFG_NF_IOSSTATE(pad, pull, rst, func, iosstate) \ + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate)) + +/* + * Native function configuration for standby state, also configuring iostandby + * as masked + */ +#define PAD_CFG_NF_IOSTANDBY_IGNORE(pad, pull, rst, func) \ + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \ + PAD_IOSSTATE(IGNORE)) + +/* + * Native function configuration for standby state, also configuring iosstate + * and iosterm + */ +#define PAD_CFG_NF_IOSSTATE_IOSTERM(pad, pull, rst, func, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +/* General purpose output, no pullup/down */ +#define PAD_CFG_GPO(pad, val, rst) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \ + PAD_PULL(NONE) | PAD_IOSSTATE(TX_LAST_RXE)) + +/* General purpose output, with termination specified */ +#define PAD_CFG_TERM_GPO(pad, val, pull, rst) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \ + PAD_PULL(pull) | PAD_IOSSTATE(TX_LAST_RXE)) + +/* General purpose output, no pullup/down */ +#define PAD_CFG_GPO_GPIO_DRIVER(pad, val, rst, pull) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \ + PAD_PULL(pull) | PAD_IOSSTATE(TX_LAST_RXE) | \ + PAD_CFG1_GPIO_DRIVER) + +/* General purpose output */ +#define PAD_CFG_GPO_IOSSTATE_IOSTERM(pad, val, rst, pull, iosstate, ioterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \ + PAD_PULL(pull) | PAD_IOSSTATE(iosstate) | PAD_IOSTERM(ioterm)) + +/* General purpose input */ +#define PAD_CFG_GPI(pad, pull, rst) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE, \ + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE)) + +/* General purpose input. The following macro sets the + * Host Software Pad Ownership to GPIO Driver mode. + */ +#define PAD_CFG_GPI_GPIO_DRIVER(pad, pull, rst) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE, \ + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE)) + +#define PAD_CFG_GPIO_DRIVER_HI_Z(pad, pull, rst, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_CFG0_RX_DISABLE, \ + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +#define PAD_CFG_GPIO_HI_Z(pad, pull, rst, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_CFG0_RX_DISABLE, PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +/* GPIO Interrupt */ +#define PAD_CFG_GPI_INT(pad, pull, rst, trig) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_CFG0_TRIG_##trig | PAD_CFG0_RX_POL_NONE, \ + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE)) + +/* + * No Connect configuration for unused pad. + * Both TX and RX are disabled. RX disabling is done to avoid unnecessary + * setting of GPI_STS. + */ +#define PAD_NC(pad, pull) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(DEEP) | \ + PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE, \ + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE)) + +/* General purpose input, routed to APIC */ +#define PAD_CFG_GPI_APIC(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TXD_RXE)) + +/* General purpose input, routed to APIC - with IOStandby Config*/ +#define PAD_CFG_GPI_APIC_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +/* + * The following APIC macros assume the APIC will handle the filtering + * on its own end. One just needs to pass an active high message into the + * ITSS. + */ +#define PAD_CFG_GPI_APIC_LOW(pad, pull, rst) \ + PAD_CFG_GPI_APIC(pad, pull, rst, LEVEL, INVERT) + +#define PAD_CFG_GPI_APIC_HIGH(pad, pull, rst) \ + PAD_CFG_GPI_APIC(pad, pull, rst, LEVEL, NONE) + +#define PAD_CFG_GPI_APIC_EDGE_LOW(pad, pull, rst) \ + PAD_CFG_GPI_APIC(pad, pull, rst, EDGE_SINGLE, INVERT) + +/* General purpose input, routed to SMI */ +#define PAD_CFG_GPI_SMI(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SMI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TXD_RXE)) + +/* General purpose input, routed to SMI */ +#define PAD_CFG_GPI_SMI_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SMI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +#define PAD_CFG_GPI_SMI_LOW(pad, pull, rst, trig) \ + PAD_CFG_GPI_SMI(pad, pull, rst, trig, INVERT) + +#define PAD_CFG_GPI_SMI_HIGH(pad, pull, rst, trig) \ + PAD_CFG_GPI_SMI(pad, pull, rst, trig, NONE) + +/* General purpose input, routed to SCI */ +#define PAD_CFG_GPI_SCI(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TXD_RXE)) + +/* General purpose input, routed to SCI */ +#define PAD_CFG_GPI_SCI_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm)) + +#define PAD_CFG_GPI_SCI_LOW(pad, pull, rst, trig) \ + PAD_CFG_GPI_SCI(pad, pull, rst, trig, INVERT) + +#define PAD_CFG_GPI_SCI_HIGH(pad, pull, rst, trig) \ + PAD_CFG_GPI_SCI(pad, pull, rst, trig, NONE) + +#define PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, inv, dur) \ + _PAD_CFG_STRUCT_3(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TXD_RXE), PAD_CFG2_DEBEN | PAD_CFG2_##dur) + +#define PAD_CFG_GPI_SCI_LOW_DEBEN(pad, pull, rst, trig, dur) \ + PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, INVERT, dur) + +#define PAD_CFG_GPI_SCI_HIGH_DEBEN(pad, pull, rst, trig, dur) \ + PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, NONE, dur) + +/* General purpose input, routed to NMI */ +#define PAD_CFG_GPI_NMI(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(NMI, trig, inv), PAD_PULL(pull) | \ + PAD_IOSSTATE(TXD_RXE)) + +#if IS_ENABLED(INTEL_PINCTRL_DUAL_ROUTE_SUPPORT) +/* GPI, GPIO Driver, SCI interrupt */ +#define PAD_CFG_GPI_GPIO_DRIVER_SCI(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SCI, trig, inv), \ + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE)) + +#define PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, route1, route2) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv), \ + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE)) + +#define PAD_CFG_GPI_IRQ_WAKE(pad, pull, rst, trig, inv) \ + PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, IOAPIC, SCI) + +#endif /* CONFIG_INTEL_PINCTRL_DUAL_ROUTE_SUPPORT */ + +#endif /* _ASM_INTEL_PINCTRL_DEFS_H_ */ diff --git a/arch/x86/include/asm/lpss.h b/arch/x86/include/asm/lpss.h new file mode 100644 index 0000000000..7814872688 --- /dev/null +++ b/arch/x86/include/asm/lpss.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __ASM_LPSS_H +#define __ASM_LPSS_H + +struct udevice; + +/* D0 and D3 enable config */ +enum lpss_pwr_state { + STATE_D0 = 0, + STATE_D3 = 3 +}; + +/** + * lpss_reset_release() - Release device from reset + * + * This is used for devices which have LPSS support. + * + * @regs: Pointer to device registers + */ +void lpss_reset_release(void *regs); + +/** + * lpss_set_power_state() - Change power state of a device + * + * This is used for devices which have LPSS support. + * + * @dev: Device to update + * @state: New power state to set + */ +void lpss_set_power_state(struct udevice *dev, enum lpss_pwr_state state); + +#endif diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h index 40fda856ff..d6b7529073 100644 --- a/arch/x86/include/asm/mrccache.h +++ b/arch/x86/include/asm/mrccache.h @@ -7,7 +7,7 @@ #ifndef _ASM_MRCCACHE_H #define _ASM_MRCCACHE_H -#define MRC_DATA_ALIGN 0x1000 +#define MRC_DATA_ALIGN 0x100 #define MRC_DATA_SIGNATURE (('M' << 0) | ('R' << 8) | \ ('C' << 16) | ('D'<<24)) @@ -27,6 +27,14 @@ struct mrc_region { u32 length; }; +/* Types of MRC data */ +enum mrc_type_t { + MRC_TYPE_NORMAL, + MRC_TYPE_VAR, + + MRC_TYPE_COUNT, +}; + struct udevice; /** @@ -41,21 +49,6 @@ struct udevice; struct mrc_data_container *mrccache_find_current(struct mrc_region *entry); /** - * mrccache_update() - update the MRC cache with a new record - * - * This writes a new record to the end of the MRC cache region. If the new - * record is the same as the latest record then the write is skipped - * - * @sf: SPI flash to write to - * @entry: Position and size of MRC cache in SPI flash - * @cur: Record to write - * @return 0 if updated, -EEXIST if the record is the same as the latest - * record, -EINVAL if the record is not valid, other error if SPI write failed - */ -int mrccache_update(struct udevice *sf, struct mrc_region *entry, - struct mrc_data_container *cur); - -/** * mrccache_reserve() - reserve MRC data on the stack * * This copies MRC data pointed by gd->arch.mrc_output to a new place on the @@ -84,6 +77,7 @@ int mrccache_reserve(void); * triggers PCI bus enumeration during which insufficient memory issue * might be exposed and it causes subsequent SPI flash probe fails). * + * @type: Type of MRC data to use * @devp: Returns pointer to the SPI flash device * @entry: Position and size of MRC cache in SPI flash * @return 0 if success, -ENOENT if SPI flash node does not exist in the @@ -91,7 +85,8 @@ int mrccache_reserve(void); * tree, -EINVAL if MRC region properties format is incorrect, other error * if SPI flash probe failed. */ -int mrccache_get_region(struct udevice **devp, struct mrc_region *entry); +int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, + struct mrc_region *entry); /** * mrccache_save() - save MRC data to the SPI flash diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 5bc8b6c22c..246c14f815 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -70,6 +70,7 @@ #define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL3 0x0000011e #define MSR_POWER_MISC 0x00000120 +#define FLUSH_DL1_L2 (1 << 8) #define ENABLE_ULFM_AUTOCM_MASK (1 << 2) #define ENABLE_INDP_AUTOCM_MASK (1 << 3) @@ -241,10 +242,17 @@ #define PKG_POWER_LIMIT_CLAMP (1 << 16) #define PKG_POWER_LIMIT_TIME_SHIFT 17 #define PKG_POWER_LIMIT_TIME_MASK 0x7f +/* + * For Mobile, RAPL default PL1 time window value set to 28 seconds. + * RAPL time window calculation defined as follows: + * Time Window = (float)((1+X/4)*(2*^Y), X Corresponds to [23:22], + * Y to [21:17] in MSR 0x610. 28 sec is equal to 0x6e. + */ +#define MB_POWER_LIMIT1_TIME_DEFAULT 0x6e #define MSR_PKG_ENERGY_STATUS 0x00000611 #define MSR_PKG_PERF_STATUS 0x00000613 -#define MSR_PKG_POWER_INFO 0x00000614 +#define MSR_PKG_POWER_SKU 0x614 #define MSR_DRAM_POWER_LIMIT 0x00000618 #define MSR_DRAM_ENERGY_STATUS 0x00000619 diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f1d9977bcb..d7b6836786 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -25,8 +25,6 @@ /* Length of the public header on Intel microcode blobs */ #define UCODE_HEADER_LEN 0x30 -#ifndef __ASSEMBLY__ - /* * This register is documented in (for example) the Intel Atom Processor E3800 * Product Family Datasheet in "PCU - Power Management Controller (PMC)". @@ -37,11 +35,11 @@ */ #define IO_PORT_RESET 0xcf9 -enum { - SYS_RST = 1 << 1, /* 0 for soft reset, 1 for hard reset */ - RST_CPU = 1 << 2, /* initiate reset */ - FULL_RST = 1 << 3, /* full power cycle */ -}; +#define SYS_RST (1 << 1) /* 0 for soft reset, 1 for hard reset */ +#define RST_CPU (1 << 2) /* initiate reset */ +#define FULL_RST (1 << 3) /* full power cycle */ + +#ifndef __ASSEMBLY__ static inline __attribute__((always_inline)) void cpu_hlt(void) { diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h index 1bef4877eb..cc6cac08f2 100644 --- a/arch/x86/include/asm/spl.h +++ b/arch/x86/include/asm/spl.h @@ -11,6 +11,7 @@ enum { BOOT_DEVICE_SPI_MMAP = 10, + BOOT_DEVICE_FAST_SPI, BOOT_DEVICE_CROS_VBOOT, }; diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index ca0ca1066b..5cd4587480 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -4,9 +4,11 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. ifndef CONFIG_X86_64 +ifndef CONFIG_TPL_BUILD obj-y += bios.o obj-y += bios_asm.o obj-y += bios_interrupts.o +endif obj-y += string.o endif ifndef CONFIG_SPL_BUILD diff --git a/arch/x86/lib/fsp/Makefile b/arch/x86/lib/fsp/Makefile index 9e34856473..da6c0a886a 100644 --- a/arch/x86/lib/fsp/Makefile +++ b/arch/x86/lib/fsp/Makefile @@ -4,4 +4,7 @@ obj-y += fsp_common.o obj-y += fsp_dram.o +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o +endif obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index a5efe35f59..5eff0f99aa 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -58,26 +58,6 @@ void board_final_cleanup(void) debug("OK\n"); } -void *fsp_prepare_mrc_cache(void) -{ - struct mrc_data_container *cache; - struct mrc_region entry; - int ret; - - ret = mrccache_get_region(NULL, &entry); - if (ret) - return NULL; - - cache = mrccache_find_current(&entry); - if (!cache) - return NULL; - - debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__, - cache->data, cache->data_size, cache->checksum); - - return cache->data; -} - #ifdef CONFIG_HAVE_ACPI_RESUME int fsp_save_s3_stack(void) { diff --git a/arch/x86/lib/fsp/fsp_dram.c b/arch/x86/lib/fsp/fsp_dram.c index bc456bb4a9..9ce0ddf0d3 100644 --- a/arch/x86/lib/fsp/fsp_dram.c +++ b/arch/x86/lib/fsp/fsp_dram.c @@ -9,6 +9,7 @@ #include <asm/fsp/fsp_support.h> #include <asm/e820.h> #include <asm/mrccache.h> +#include <asm/mtrr.h> #include <asm/post.h> DECLARE_GLOBAL_DATA_PTR; @@ -38,8 +39,40 @@ int fsp_scan_for_ram_size(void) int dram_init_banksize(void) { + const struct hob_header *hdr; + struct hob_res_desc *res_desc; + phys_addr_t low_end; + uint bank; + + low_end = 0; + for (bank = 1, hdr = gd->arch.hob_list; + bank < CONFIG_NR_DRAM_BANKS && !end_of_hob(hdr); + hdr = get_next_hob(hdr)) { + if (hdr->type != HOB_TYPE_RES_DESC) + continue; + res_desc = (struct hob_res_desc *)hdr; + if (res_desc->type != RES_SYS_MEM && + res_desc->type != RES_MEM_RESERVED) + continue; + if (res_desc->phys_start < (1ULL << 32)) { + low_end = max(low_end, + res_desc->phys_start + res_desc->len); + continue; + } + + gd->bd->bi_dram[bank].start = res_desc->phys_start; + gd->bd->bi_dram[bank].size = res_desc->len; + mtrr_add_request(MTRR_TYPE_WRBACK, res_desc->phys_start, + res_desc->len); + log_debug("ram %llx %llx\n", gd->bd->bi_dram[bank].start, + gd->bd->bi_dram[bank].size); + } + + /* Add the memory below 4GB */ gd->bd->bi_dram[0].start = 0; - gd->bd->bi_dram[0].size = gd->ram_size; + gd->bd->bi_dram[0].size = low_end; + + mtrr_add_request(MTRR_TYPE_WRBACK, 0, low_end); return 0; } diff --git a/arch/x86/lib/fsp1/fsp_graphics.c b/arch/x86/lib/fsp/fsp_graphics.c index 52e71334f9..226c7e66b3 100644 --- a/arch/x86/lib/fsp1/fsp_graphics.c +++ b/arch/x86/lib/fsp/fsp_graphics.c @@ -7,7 +7,8 @@ #include <dm.h> #include <vbe.h> #include <video.h> -#include <asm/fsp1/fsp_support.h> +#include <asm/fsp/fsp_support.h> +#include <asm/mtrr.h> DECLARE_GLOBAL_DATA_PTR; @@ -97,6 +98,9 @@ static int fsp_video_probe(struct udevice *dev) if (ret) goto err; + mtrr_add_request(MTRR_TYPE_WRCOMB, vesa->phys_base_ptr, 256 << 20); + mtrr_commit(true); + printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize, vesa->bits_per_pixel); diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 983888fd74..ee228117d1 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -5,7 +5,7 @@ */ #include <common.h> -#include <asm/fsp1/fsp_support.h> +#include <asm/fsp/fsp_support.h> #include <asm/post.h> u32 fsp_get_usable_lowmem_top(const void *hob_list) diff --git a/arch/x86/lib/fsp1/Makefile b/arch/x86/lib/fsp1/Makefile index 870de71bd7..1cf5e54191 100644 --- a/arch/x86/lib/fsp1/Makefile +++ b/arch/x86/lib/fsp1/Makefile @@ -5,5 +5,4 @@ obj-y += fsp_car.o obj-y += fsp_common.o obj-y += fsp_dram.o -obj-$(CONFIG_VIDEO_FSP) += fsp_graphics.o obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp1/fsp_common.c b/arch/x86/lib/fsp1/fsp_common.c index e8066d8de3..ec9c218778 100644 --- a/arch/x86/lib/fsp1/fsp_common.c +++ b/arch/x86/lib/fsp1/fsp_common.c @@ -18,6 +18,26 @@ DECLARE_GLOBAL_DATA_PTR; +static void *fsp_prepare_mrc_cache(void) +{ + struct mrc_data_container *cache; + struct mrc_region entry; + int ret; + + ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry); + if (ret) + return NULL; + + cache = mrccache_find_current(&entry); + if (!cache) + return NULL; + + debug("%s: mrc cache at %p, size %x checksum %04x\n", __func__, + cache->data, cache->data_size, cache->checksum); + + return cache->data; +} + int arch_fsp_init(void) { void *nvs; diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c index 6a3349b42a..5ef89744b9 100644 --- a/arch/x86/lib/fsp1/fsp_dram.c +++ b/arch/x86/lib/fsp1/fsp_dram.c @@ -15,9 +15,11 @@ int dram_init(void) if (ret) return ret; - if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) - gd->arch.mrc_output = fsp_get_nvs_data(gd->arch.hob_list, - &gd->arch.mrc_output_len); + if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) { + struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL]; + + mrc->buf = fsp_get_nvs_data(gd->arch.hob_list, &mrc->len); + } return 0; } diff --git a/arch/x86/lib/fsp2/Makefile b/arch/x86/lib/fsp2/Makefile new file mode 100644 index 0000000000..ddbe2d0db2 --- /dev/null +++ b/arch/x86/lib/fsp2/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC + +obj-y += fsp_common.o +obj-y += fsp_dram.o +obj-y += fsp_init.o +obj-y += fsp_meminit.o +obj-y += fsp_silicon_init.o +obj-y += fsp_support.o diff --git a/arch/x86/lib/fsp2/fsp_common.c b/arch/x86/lib/fsp2/fsp_common.c new file mode 100644 index 0000000000..f69456e43a --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_common.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <init.h> + +int arch_fsp_init(void) +{ + return 0; +} diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c new file mode 100644 index 0000000000..90a238a224 --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <acpi_s3.h> +#include <handoff.h> +#include <spl.h> +#include <asm/arch/cpu.h> +#include <asm/fsp/fsp_support.h> +#include <asm/fsp2/fsp_api.h> +#include <asm/fsp2/fsp_internal.h> + +int dram_init(void) +{ + int ret; + + if (spl_phase() == PHASE_SPL) { +#ifdef CONFIG_HAVE_ACPI_RESUME + bool s3wake = gd->arch.prev_sleep_state == ACPI_S3; +#else + bool s3wake = false; +#endif + + ret = fsp_memory_init(s3wake, + IS_ENABLED(CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH)); + if (ret) { + debug("Memory init failed (err=%x)\n", ret); + return ret; + } + + /* The FSP has already set up DRAM, so grab the info we need */ + ret = fsp_scan_for_ram_size(); + if (ret) + return ret; + +#ifdef CONFIG_ENABLE_MRC_CACHE + gd->arch.mrc[MRC_TYPE_NORMAL].buf = + fsp_get_nvs_data(gd->arch.hob_list, + &gd->arch.mrc[MRC_TYPE_NORMAL].len); + gd->arch.mrc[MRC_TYPE_VAR].buf = + fsp_get_var_nvs_data(gd->arch.hob_list, + &gd->arch.mrc[MRC_TYPE_VAR].len); + log_debug("normal %x, var %x\n", + gd->arch.mrc[MRC_TYPE_NORMAL].len, + gd->arch.mrc[MRC_TYPE_VAR].len); +#endif + } else { +#if CONFIG_IS_ENABLED(HANDOFF) + struct spl_handoff *ho = gd->spl_handoff; + + if (!ho) { + debug("No SPL handoff found\n"); + return -ESTRPIPE; + } + gd->ram_size = ho->ram_size; + handoff_load_dram_banks(ho); +#endif + ret = arch_fsps_preinit(); + if (ret) + return log_msg_ret("fsp_s_preinit", ret); + } + + return 0; +} + +ulong board_get_usable_ram_top(ulong total_size) +{ +#if CONFIG_IS_ENABLED(HANDOFF) + struct spl_handoff *ho = gd->spl_handoff; + + return ho->arch.usable_ram_top; +#endif + + return gd->ram_top; +} diff --git a/arch/x86/lib/fsp2/fsp_init.c b/arch/x86/lib/fsp2/fsp_init.c new file mode 100644 index 0000000000..da9bd6b45c --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_init.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <binman.h> +#include <binman_sym.h> +#include <cbfs.h> +#include <dm.h> +#include <init.h> +#include <spi.h> +#include <spl.h> +#include <spi_flash.h> +#include <asm/intel_pinctrl.h> +#include <dm/uclass-internal.h> +#include <asm/fsp2/fsp_internal.h> + +int arch_cpu_init_dm(void) +{ + struct udevice *dev; + ofnode node; + int ret; + + /* Make sure pads are set up early in U-Boot */ + if (spl_phase() != PHASE_BOARD_F) + return 0; + + /* Probe all pinctrl devices to set up the pads */ + ret = uclass_first_device_err(UCLASS_PINCTRL, &dev); + if (ret) + return log_msg_ret("no fsp pinctrl", ret); + node = ofnode_path("fsp"); + if (!ofnode_valid(node)) + return log_msg_ret("no fsp params", -EINVAL); + ret = pinctrl_config_pads_for_node(dev, node); + if (ret) + return log_msg_ret("pad config", ret); + + return ret; +} + +#if !defined(CONFIG_TPL_BUILD) +binman_sym_declare(ulong, intel_fsp_m, image_pos); +binman_sym_declare(ulong, intel_fsp_m, size); + +/** + * get_cbfs_fsp() - Obtain the FSP by looking up in CBFS + * + * This looks up an FSP in a CBFS. It is used mostly for testing, when booting + * U-Boot from a hybrid image containing coreboot as the first-stage bootloader. + * + * The typical use for this feature is when building a Chrome OS image which + * includes coreboot in it. By adding U-Boot into the 'COREBOOT' CBFS as well, + * it is possible to make coreboot chain-load U-Boot. Thus the initial stages of + * the SoC init can be done by coreboot and the later stages by U-Boot. This is + * a convenient way to start the porting work. The jump to U-Boot can then be + * moved progressively earlier and earlier, until U-Boot takes over all the init + * and you have a native port. + * + * This function looks up a CBFS at a known location and reads the FSP-M from it + * so that U-Boot can init the memory. + * + * This function is not used in the normal boot but is kept here for future + * development. + * + * @type; Type to look up (only FSP_M supported at present) + * @map_base: Base memory address for mapped SPI + * @entry: Returns an entry containing the position of the FSP image + */ +static int get_cbfs_fsp(enum fsp_type_t type, ulong map_base, + struct binman_entry *entry) +{ + /* + * Use a hard-coded position of CBFS in the ROM for now. It would be + * possible to read the position using the FMAP in the ROM, but since + * this code is only used for development, it doesn't seem worth it. + * Use the 'cbfstool <image> layout' command to get these values, e.g.: + * 'COREBOOT' (CBFS, size 1814528, offset 2117632). + */ + ulong cbfs_base = 0x205000; + ulong cbfs_size = 0x1bb000; + struct cbfs_priv *cbfs; + int ret; + + ret = cbfs_init_mem(map_base + cbfs_base, cbfs_size, &cbfs); + if (ret) + return ret; + if (!ret) { + const struct cbfs_cachenode *node; + + node = cbfs_find_file(cbfs, "fspm.bin"); + if (!node) + return log_msg_ret("fspm node", -ENOENT); + + entry->image_pos = (ulong)node->data; + entry->size = node->data_length; + } + + return 0; +} + +int fsp_locate_fsp(enum fsp_type_t type, struct binman_entry *entry, + bool use_spi_flash, struct udevice **devp, + struct fsp_header **hdrp, ulong *rom_offsetp) +{ + ulong mask = CONFIG_ROM_SIZE - 1; + struct udevice *dev; + ulong rom_offset = 0; + uint map_size; + ulong map_base; + uint offset; + int ret; + + /* + * Find the devices but don't probe them, since we don't want to + * auto-config PCI before silicon init runs + */ + ret = uclass_find_first_device(UCLASS_NORTHBRIDGE, &dev); + if (ret) + return log_msg_ret("Cannot get northbridge", ret); + if (!use_spi_flash) { + struct udevice *sf; + + /* Just use the SPI driver to get the memory map */ + ret = uclass_find_first_device(UCLASS_SPI_FLASH, &sf); + if (ret) + return log_msg_ret("Cannot get SPI flash", ret); + ret = dm_spi_get_mmap(sf, &map_base, &map_size, &offset); + if (ret) + return log_msg_ret("Could not get flash mmap", ret); + } + + if (spl_phase() >= PHASE_BOARD_F) { + if (type != FSP_S) + return -EPROTONOSUPPORT; + ret = binman_entry_find("intel-fsp-s", entry); + if (ret) + return log_msg_ret("binman entry", ret); + if (!use_spi_flash) + rom_offset = (map_base & mask) - CONFIG_ROM_SIZE; + } else { + ret = -ENOENT; + if (false) + /* + * Support using a hybrid image build by coreboot. See + * the function comments for details + */ + ret = get_cbfs_fsp(type, map_base, entry); + if (ret) { + ulong mask = CONFIG_ROM_SIZE - 1; + + if (type != FSP_M) + return -EPROTONOSUPPORT; + entry->image_pos = binman_sym(ulong, intel_fsp_m, + image_pos); + entry->size = binman_sym(ulong, intel_fsp_m, size); + if (entry->image_pos != BINMAN_SYM_MISSING) { + ret = 0; + if (use_spi_flash) + entry->image_pos &= mask; + else + entry->image_pos += (map_base & mask); + } else { + ret = -ENOENT; + } + } + } + if (ret) + return log_msg_ret("Cannot find FSP", ret); + entry->image_pos += rom_offset; + + /* + * Account for the time taken to read memory-mapped SPI flash since in + * this case we don't use the SPI driver and BOOTSTAGE_ID_ACCUM_SPI. + */ + if (!use_spi_flash) + bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi"); + ret = fsp_get_header(entry->image_pos, entry->size, use_spi_flash, + hdrp); + if (!use_spi_flash) + bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI); + if (ret) + return log_msg_ret("fsp_get_header", ret); + *devp = dev; + if (rom_offsetp) + *rom_offsetp = rom_offset; + + return 0; +} +#endif diff --git a/arch/x86/lib/fsp2/fsp_meminit.c b/arch/x86/lib/fsp2/fsp_meminit.c new file mode 100644 index 0000000000..bf30c47989 --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_meminit.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: Intel +/* + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.) + * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) + * Mostly taken from coreboot fsp2_0/memory_init.c + */ + +#include <common.h> +#include <binman.h> +#include <asm/mrccache.h> +#include <asm/fsp/fsp_infoheader.h> +#include <asm/fsp2/fsp_api.h> +#include <asm/fsp2/fsp_internal.h> +#include <asm/arch/fsp/fsp_configs.h> +#include <asm/arch/fsp/fsp_m_upd.h> + +static int prepare_mrc_cache_type(enum mrc_type_t type, + struct mrc_data_container **cachep) +{ + struct mrc_data_container *cache; + struct mrc_region entry; + int ret; + + ret = mrccache_get_region(type, NULL, &entry); + if (ret) + return ret; + cache = mrccache_find_current(&entry); + if (!cache) + return -ENOENT; + + log_debug("MRC at %x, size %x\n", (uint)cache->data, cache->data_size); + *cachep = cache; + + return 0; +} + +int prepare_mrc_cache(struct fspm_upd *upd) +{ + struct mrc_data_container *cache; + int ret; + + ret = prepare_mrc_cache_type(MRC_TYPE_NORMAL, &cache); + if (ret) + return log_msg_ret("Cannot get normal cache", ret); + upd->arch.nvs_buffer_ptr = cache->data; + + ret = prepare_mrc_cache_type(MRC_TYPE_VAR, &cache); + if (ret) + return log_msg_ret("Cannot get var cache", ret); + upd->config.variable_nvs_buffer_ptr = cache->data; + + return 0; +} + +int fsp_memory_init(bool s3wake, bool use_spi_flash) +{ + struct fspm_upd upd, *fsp_upd; + fsp_memory_init_func func; + struct binman_entry entry; + struct fsp_header *hdr; + struct hob_header *hob; + struct udevice *dev; + int ret; + + ret = fsp_locate_fsp(FSP_M, &entry, use_spi_flash, &dev, &hdr, NULL); + if (ret) + return log_msg_ret("locate FSP", ret); + debug("Found FSP_M at %x, size %x\n", hdr->img_base, hdr->img_size); + + /* Copy over the default config */ + fsp_upd = (struct fspm_upd *)(hdr->img_base + hdr->cfg_region_off); + if (fsp_upd->header.signature != FSPM_UPD_SIGNATURE) + return log_msg_ret("Bad UPD signature", -EPERM); + memcpy(&upd, fsp_upd, sizeof(upd)); + + ret = fspm_update_config(dev, &upd); + if (ret) + return log_msg_ret("Could not setup config", ret); + + debug("SDRAM init..."); + bootstage_start(BOOTSTATE_ID_ACCUM_FSP_M, "fsp-m"); + func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init); + ret = func(&upd, &hob); + bootstage_accum(BOOTSTATE_ID_ACCUM_FSP_M); + if (ret) + return log_msg_ret("SDRAM init fail\n", ret); + + gd->arch.hob_list = hob; + debug("done\n"); + + ret = fspm_done(dev); + if (ret) + return log_msg_ret("fsm_done\n", ret); + + return 0; +} diff --git a/arch/x86/lib/fsp2/fsp_silicon_init.c b/arch/x86/lib/fsp2/fsp_silicon_init.c new file mode 100644 index 0000000000..d7ce43e1eb --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_silicon_init.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Intel +/* + * Copyright (C) 2015-2016 Intel Corp. + * (Written by Andrey Petrov <andrey.petrov@intel.com> for Intel Corp.) + * + * Mostly taken from coreboot fsp2_0/silicon_init.c + */ + +#define LOG_CATEGORY UCLASS_NORTHBRIDGE + +#include <common.h> +#include <binman.h> +#include <dm.h> +#include <asm/arch/fsp/fsp_configs.h> +#include <asm/arch/fsp/fsp_s_upd.h> +#include <asm/fsp/fsp_infoheader.h> +#include <asm/fsp2/fsp_internal.h> + +int fsp_silicon_init(bool s3wake, bool use_spi_flash) +{ + struct fsps_upd upd, *fsp_upd; + fsp_silicon_init_func func; + struct fsp_header *hdr; + struct binman_entry entry; + struct udevice *dev; + ulong rom_offset = 0; + int ret; + + ret = fsp_locate_fsp(FSP_S, &entry, use_spi_flash, &dev, &hdr, + &rom_offset); + if (ret) + return log_msg_ret("locate FSP", ret); + gd->arch.fsp_s_hdr = hdr; + + /* Copy over the default config */ + fsp_upd = (struct fsps_upd *)(hdr->img_base + hdr->cfg_region_off); + if (fsp_upd->header.signature != FSPS_UPD_SIGNATURE) + return log_msg_ret("Bad UPD signature", -EPERM); + memcpy(&upd, fsp_upd, sizeof(upd)); + + ret = fsps_update_config(dev, rom_offset, &upd); + if (ret) + return log_msg_ret("Could not setup config", ret); + log_debug("Silicon init..."); + bootstage_start(BOOTSTATE_ID_ACCUM_FSP_S, "fsp-s"); + func = (fsp_silicon_init_func)(hdr->img_base + hdr->fsp_silicon_init); + ret = func(&upd); + bootstage_accum(BOOTSTATE_ID_ACCUM_FSP_S); + if (ret) + return log_msg_ret("Silicon init fail\n", ret); + log_debug("done\n"); + + return 0; +} diff --git a/arch/x86/lib/fsp2/fsp_support.c b/arch/x86/lib/fsp2/fsp_support.c new file mode 100644 index 0000000000..0a04b443f7 --- /dev/null +++ b/arch/x86/lib/fsp2/fsp_support.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Intel +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <spi_flash.h> +#include <asm/fsp/fsp_support.h> +#include <asm/fsp2/fsp_internal.h> + +/* The amount of the FSP header to probe to obtain what we need */ +#define PROBE_BUF_SIZE 0x180 + +int fsp_get_header(ulong offset, ulong size, bool use_spi_flash, + struct fsp_header **fspp) +{ + static efi_guid_t guid = FSP_HEADER_GUID; + struct fv_ext_header *exhdr; + struct fsp_header *fsp; + struct ffs_file_header *file_hdr; + struct fv_header *fv; + struct raw_section *raw; + void *ptr, *base; + u8 buf[PROBE_BUF_SIZE]; + struct udevice *dev; + int ret; + + /* + * There are quite a very steps to work through all the headers in this + * file and the structs have similar names. Turn on debugging if needed + * to understand what is going wrong. + * + * You are in a maze of twisty little headers all alike. + */ + debug("offset=%x buf=%x\n", (uint)offset, (uint)buf); + if (use_spi_flash) { + ret = uclass_first_device_err(UCLASS_SPI_FLASH, &dev); + if (ret) + return log_msg_ret("Cannot find flash device", ret); + ret = spi_flash_read_dm(dev, offset, PROBE_BUF_SIZE, buf); + if (ret) + return log_msg_ret("Cannot read flash", ret); + } else { + memcpy(buf, (void *)offset, PROBE_BUF_SIZE); + } + + /* Initalise the FSP base */ + ptr = buf; + fv = ptr; + + /* Check the FV signature, _FVH */ + debug("offset=%x sign=%x\n", (uint)offset, (uint)fv->sign); + if (fv->sign != EFI_FVH_SIGNATURE) + return log_msg_ret("Base FV signature", -EINVAL); + + /* Go to the end of the FV header and align the address */ + debug("fv->ext_hdr_off = %x\n", fv->ext_hdr_off); + ptr += fv->ext_hdr_off; + exhdr = ptr; + ptr += ALIGN(exhdr->ext_hdr_size, 8); + debug("ptr=%x\n", ptr - (void *)buf); + + /* Check the FFS GUID */ + file_hdr = ptr; + if (memcmp(&file_hdr->name, &guid, sizeof(guid))) + return log_msg_ret("Base FFS GUID", -ENXIO); + /* Add the FFS header size to find the raw section header */ + ptr = file_hdr + 1; + + raw = ptr; + debug("raw->type = %x\n", raw->type); + if (raw->type != EFI_SECTION_RAW) + return log_msg_ret("Section type not RAW", -ENOEXEC); + + /* Add the raw section header size to find the FSP header */ + ptr = raw + 1; + fsp = ptr; + + /* Check the FSPH header */ + debug("fsp %x\n", (uint)fsp); + if (fsp->sign != EFI_FSPH_SIGNATURE) + return log_msg_ret("Base FSPH signature", -EACCES); + + base = (void *)fsp->img_base; + debug("Image base %x\n", (uint)base); + debug("Image addr %x\n", (uint)fsp->fsp_mem_init); + if (use_spi_flash) { + ret = spi_flash_read_dm(dev, offset, size, base); + if (ret) + return log_msg_ret("Could not read FPS-M", ret); + } else { + memcpy(base, (void *)offset, size); + } + ptr = base + (ptr - (void *)buf); + *fspp = ptr; + + return 0; +} + +u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase) +{ + fsp_notify_f notify; + struct fsp_notify_params params; + struct fsp_notify_params *params_ptr; + u32 status; + + if (!fsp_hdr) + fsp_hdr = gd->arch.fsp_s_hdr; + + if (!fsp_hdr) + return log_msg_ret("no FSP", -ENOENT); + + notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify); + params.phase = phase; + params_ptr = ¶ms; + + /* + * Use ASM code to ensure correct parameter is on the stack for + * FspNotify as U-Boot is using different ABI from FSP + */ + asm volatile ( + "pushl %1;" /* push notify phase */ + "call *%%eax;" /* call FspNotify */ + "addl $4, %%esp;" /* clean up the stack */ + : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr) + ); + + return status; +} diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 33bb52039b..b9420a4cab 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -14,6 +14,8 @@ #include <spi.h> #include <spi_flash.h> #include <asm/mrccache.h> +#include <dm/device-internal.h> +#include <dm/uclass-internal.h> DECLARE_GLOBAL_DATA_PTR; @@ -80,21 +82,31 @@ struct mrc_data_container *mrccache_find_current(struct mrc_region *entry) /** * find_next_mrc_cache() - get next cache entry * + * This moves to the next cache entry in the region, making sure it has enough + * space to hold data of size @data_size. + * * @entry: MRC cache flash area * @cache: Entry to start from + * @data_size: Required data size of the new entry. Note that we assume that + * all cache entries are the same size * * @return next cache entry if found, NULL if we got to the end */ static struct mrc_data_container *find_next_mrc_cache(struct mrc_region *entry, - struct mrc_data_container *cache) + struct mrc_data_container *prev, int data_size) { + struct mrc_data_container *cache; ulong base_addr, end_addr; base_addr = entry->base + entry->offset; end_addr = base_addr + entry->length; - cache = next_mrc_block(cache); - if ((ulong)cache >= end_addr) { + /* + * We assume that all cache entries are the same size, but let's use + * data_size here for clarity. + */ + cache = next_mrc_block(prev); + if ((ulong)cache + mrc_block_size(data_size) > end_addr) { /* Crossed the boundary */ cache = NULL; debug("%s: no available entries found\n", __func__); @@ -106,8 +118,20 @@ static struct mrc_data_container *find_next_mrc_cache(struct mrc_region *entry, return cache; } -int mrccache_update(struct udevice *sf, struct mrc_region *entry, - struct mrc_data_container *cur) +/** + * mrccache_update() - update the MRC cache with a new record + * + * This writes a new record to the end of the MRC cache region. If the new + * record is the same as the latest record then the write is skipped + * + * @sf: SPI flash to write to + * @entry: Position and size of MRC cache in SPI flash + * @cur: Record to write + * @return 0 if updated, -EEXIST if the record is the same as the latest + * record, -EINVAL if the record is not valid, other error if SPI write failed + */ +static int mrccache_update(struct udevice *sf, struct mrc_region *entry, + struct mrc_data_container *cur) { struct mrc_data_container *cache; ulong offset; @@ -131,7 +155,7 @@ int mrccache_update(struct udevice *sf, struct mrc_region *entry, /* Move to the next block, which will be the first unused block */ if (cache) - cache = find_next_mrc_cache(entry, cache); + cache = find_next_mrc_cache(entry, cache, cur->data_size); /* * If we have got to the end, erase the entire mrc-cache area and start @@ -156,130 +180,158 @@ int mrccache_update(struct udevice *sf, struct mrc_region *entry, cur); if (ret) { debug("Failed to write to SPI flash\n"); - return ret; + return log_msg_ret("Cannot update mrccache", ret); } return 0; } -static void mrccache_setup(void *data) +static void mrccache_setup(struct mrc_output *mrc, void *data) { struct mrc_data_container *cache = data; u16 checksum; cache->signature = MRC_DATA_SIGNATURE; - cache->data_size = gd->arch.mrc_output_len; - checksum = compute_ip_checksum(gd->arch.mrc_output, cache->data_size); + cache->data_size = mrc->len; + checksum = compute_ip_checksum(mrc->buf, cache->data_size); debug("Saving %d bytes for MRC output data, checksum %04x\n", cache->data_size, checksum); cache->checksum = checksum; cache->reserved = 0; - memcpy(cache->data, gd->arch.mrc_output, cache->data_size); + memcpy(cache->data, mrc->buf, cache->data_size); - /* gd->arch.mrc_output now points to the container */ - gd->arch.mrc_output = (char *)cache; + mrc->cache = cache; } int mrccache_reserve(void) { - if (!gd->arch.mrc_output_len) - return 0; + int i; - /* adjust stack pointer to store pure cache data plus the header */ - gd->start_addr_sp -= (gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE); - mrccache_setup((void *)gd->start_addr_sp); + for (i = 0; i < MRC_TYPE_COUNT; i++) { + struct mrc_output *mrc = &gd->arch.mrc[i]; - gd->start_addr_sp &= ~0xf; + if (!mrc->len) + continue; + + /* adjust stack pointer to store pure cache data plus header */ + gd->start_addr_sp -= (mrc->len + MRC_DATA_HEADER_SIZE); + mrccache_setup(mrc, (void *)gd->start_addr_sp); + + gd->start_addr_sp &= ~0xf; + } return 0; } -int mrccache_get_region(struct udevice **devp, struct mrc_region *entry) +int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, + struct mrc_region *entry) { - const void *blob = gd->fdt_blob; - int node, mrc_node; + struct udevice *dev; + ofnode mrc_node; + ulong map_base; + uint map_size; + uint offset; u32 reg[2]; int ret; - /* Find the flash chip within the SPI controller node */ - node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); - if (node < 0) { - debug("%s: Cannot find SPI flash\n", __func__); - return -ENOENT; - } - - if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2)) { - debug("%s: Cannot find memory map\n", __func__); - return -EINVAL; + /* + * Find the flash chip within the SPI controller node. Avoid probing + * the device here since it may put it into a strange state where the + * memory map cannot be read. + */ + ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev); + if (ret) + return log_msg_ret("Cannot find SPI flash\n", ret); + ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); + if (!ret) { + entry->base = map_base; + } else { + ret = dev_read_u32_array(dev, "memory-map", reg, 2); + if (ret) + return log_msg_ret("Cannot find memory map\n", ret); + entry->base = reg[0]; } - entry->base = reg[0]; /* Find the place where we put the MRC cache */ - mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache"); - if (mrc_node < 0) { - debug("%s: Cannot find node\n", __func__); - return -EPERM; - } + mrc_node = dev_read_subnode(dev, type == MRC_TYPE_NORMAL ? + "rw-mrc-cache" : "rw-var-mrc-cache"); + if (!ofnode_valid(mrc_node)) + return log_msg_ret("Cannot find node", -EPERM); - if (fdtdec_get_int_array(blob, mrc_node, "reg", reg, 2)) { - debug("%s: Cannot find address\n", __func__); - return -EINVAL; - } + ret = ofnode_read_u32_array(mrc_node, "reg", reg, 2); + if (ret) + return log_msg_ret("Cannot find address", ret); entry->offset = reg[0]; entry->length = reg[1]; - if (devp) { - ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, - devp); - debug("ret = %d\n", ret); - if (ret) - return ret; - } + if (devp) + *devp = dev; + debug("MRC cache type %d in '%s', offset %x, len %x, base %x\n", + type, dev->name, entry->offset, entry->length, entry->base); return 0; } -int mrccache_save(void) +static int mrccache_save_type(enum mrc_type_t type) { - struct mrc_data_container *data; + struct mrc_data_container *cache; + struct mrc_output *mrc; struct mrc_region entry; struct udevice *sf; int ret; - if (!gd->arch.mrc_output_len) + mrc = &gd->arch.mrc[type]; + if (!mrc->len) return 0; - debug("Saving %d bytes of MRC output data to SPI flash\n", - gd->arch.mrc_output_len); - - ret = mrccache_get_region(&sf, &entry); + log_debug("Saving %#x bytes of MRC output data type %d to SPI flash\n", + mrc->len, type); + ret = mrccache_get_region(type, &sf, &entry); if (ret) - goto err_entry; - data = (struct mrc_data_container *)gd->arch.mrc_output; - ret = mrccache_update(sf, &entry, data); - if (!ret) { - debug("Saved MRC data with checksum %04x\n", data->checksum); - } else if (ret == -EEXIST) { + return log_msg_ret("Cannot get region", ret); + ret = device_probe(sf); + if (ret) + return log_msg_ret("Cannot probe device", ret); + cache = mrc->cache; + + ret = mrccache_update(sf, &entry, cache); + if (!ret) + debug("Saved MRC data with checksum %04x\n", cache->checksum); + else if (ret == -EEXIST) debug("MRC data is the same as last time, skipping save\n"); - ret = 0; + + return 0; +} + +int mrccache_save(void) +{ + int i; + + for (i = 0; i < MRC_TYPE_COUNT; i++) { + int ret; + + ret = mrccache_save_type(i); + if (ret) + return ret; } -err_entry: - if (ret) - debug("%s: Failed: %d\n", __func__, ret); - return ret; + return 0; } int mrccache_spl_save(void) { - void *data; - int size; - - size = gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE; - data = malloc(size); - if (!data) - return log_msg_ret("Allocate MRC cache block", -ENOMEM); - mrccache_setup(data); - gd->arch.mrc_output = data; + int i; + + for (i = 0; i < MRC_TYPE_COUNT; i++) { + struct mrc_output *mrc = &gd->arch.mrc[i]; + void *data; + int size; + + size = mrc->len + MRC_DATA_HEADER_SIZE; + data = malloc(size); + if (!data) + return log_msg_ret("Allocate MRC cache block", -ENOMEM); + mrccache_setup(mrc, data); + } return mrccache_save(); } diff --git a/arch/x86/lib/pirq_routing.c b/arch/x86/lib/pirq_routing.c index e5f0e61424..17bd2fcb9b 100644 --- a/arch/x86/lib/pirq_routing.c +++ b/arch/x86/lib/pirq_routing.c @@ -10,6 +10,8 @@ #include <asm/pci.h> #include <asm/pirq_routing.h> +DECLARE_GLOBAL_DATA_PTR; + static u8 pirq_get_next_free_irq(struct udevice *dev, u8 *pirq, u16 bitmap, bool irq_already_routed[]) { @@ -131,3 +133,11 @@ u32 copy_pirq_routing_table(u32 addr, struct irq_routing_table *rt) return addr + rt->size; } + +ulong write_pirq_routing_table(ulong addr) +{ + if (!gd->arch.pirq_routing_table) + return addr; + + return copy_pirq_routing_table(addr, gd->arch.pirq_routing_table); +} diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c index 68be0fe0cf..667a2743a6 100644 --- a/board/freescale/imx8qm_mek/imx8qm_mek.c +++ b/board/freescale/imx8qm_mek/imx8qm_mek.c @@ -50,7 +50,7 @@ int board_early_init_f(void) return 0; } -#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { /* TODO */ diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c index 671064fae2..194eb60cd3 100644 --- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c +++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c @@ -54,7 +54,7 @@ int board_early_init_f(void) return 0; } -#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { struct gpio_desc desc; diff --git a/board/freescale/ls1028a/ls1028a.c b/board/freescale/ls1028a/ls1028a.c index a9606b8865..1151e77531 100644 --- a/board/freescale/ls1028a/ls1028a.c +++ b/board/freescale/ls1028a/ls1028a.c @@ -86,7 +86,19 @@ int board_init(void) if (!i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev)) dm_i2c_write(dev, 0x0b, &val, 1); #endif +#endif +#if defined(CONFIG_TARGET_LS1028ARDB) + u8 reg; + + reg = QIXIS_READ(brdcfg[4]); + /* + * Field | Function + * 3 | DisplayPort Power Enable (net DP_PWR_EN): + * DPPWR | 0= DP_PWR is enabled. + */ + reg &= ~(DP_PWD_EN_DEFAULT_MASK); + QIXIS_WRITE(brdcfg[4], reg); #endif return 0; } diff --git a/board/freescale/ls1046afrwy/ls1046afrwy.c b/board/freescale/ls1046afrwy/ls1046afrwy.c index ac2f8ee436..db8b3a5b92 100644 --- a/board/freescale/ls1046afrwy/ls1046afrwy.c +++ b/board/freescale/ls1046afrwy/ls1046afrwy.c @@ -24,7 +24,8 @@ #define LS1046A_PORSR1_REG 0x1EE0000 #define BOOT_SRC_SD 0x20000000 #define BOOT_SRC_MASK 0xFF800000 -#define BOARD_REV_GPIO 13 +#define BOARD_REV_GPIO_SHIFT 17 +#define BOARD_REV_MASK 0x03 #define USB2_SEL_MASK 0x00000100 #define BYTE_SWAP_32(word) ((((word) & 0xff000000) >> 24) | \ @@ -87,10 +88,14 @@ int board_early_init_f(void) static inline uint8_t get_board_version(void) { - u8 val; struct ccsr_gpio *pgpio = (void *)(GPIO2_BASE_ADDR); - val = (in_le32(&pgpio->gpdat) >> BOARD_REV_GPIO) & 0x03; + /* GPIO 13 and GPIO 14 are used for Board Rev */ + u32 gpio_val = ((in_be32(&pgpio->gpdat) >> BOARD_REV_GPIO_SHIFT)) + & BOARD_REV_MASK; + + /* GPIOs' are 0..31 in Big Endiness, swap GPIO 13 and GPIO 14 */ + u8 val = ((gpio_val >> 1) | (gpio_val << 1)) & BOARD_REV_MASK; return val; } diff --git a/board/gateworks/gw_ventana/Kconfig b/board/gateworks/gw_ventana/Kconfig index 5d1bae41ac..fee910ca83 100644 --- a/board/gateworks/gw_ventana/Kconfig +++ b/board/gateworks/gw_ventana/Kconfig @@ -1,5 +1,8 @@ if TARGET_GW_VENTANA +config DM_GPIO + default y + config SYS_BOARD default "gw_ventana" diff --git a/board/google/Kconfig b/board/google/Kconfig index 679a0f1023..22c4be392f 100644 --- a/board/google/Kconfig +++ b/board/google/Kconfig @@ -8,6 +8,20 @@ choice prompt "Mainboard model" optional +config TARGET_CHROMEBOOK_CORAL + bool "Chromebook coral" + help + This is a range of Intel-based laptops released in 2018. They use an + Intel Apollo Lake SoC. The design supports WiFi, 4GB to 16GB of + LPDDR4 1600MHz SDRAM, PCIe WiFi and Bluetooth, eMMC (typically 32GB), + up two cameras (front-facing 720p and another 5MP option), USB SD + reader, microphone and speakers. It also includes two USB 3 Type A and + two Type C ports. The latter are used as power input and can also + charge external devices as well as a 4K external display. There is a + Chrome OS EC connected on LPC, a Cr50 secure chip from Google and + various display options. OEMs products include Acer Chromebook 11 + (e.g. C732, CB11, CP311) and Lenovo Chromebook (100e, 300e, 500e). + config TARGET_CHROMEBOOK_LINK bool "Chromebook link" help @@ -62,6 +76,7 @@ config TARGET_CHROMEBOOK_SAMUS_TPL endchoice +source "board/google/chromebook_coral/Kconfig" source "board/google/chromebook_link/Kconfig" source "board/google/chromebox_panther/Kconfig" source "board/google/chromebook_samus/Kconfig" diff --git a/board/google/chromebook_coral/Kconfig b/board/google/chromebook_coral/Kconfig new file mode 100644 index 0000000000..940bee89b0 --- /dev/null +++ b/board/google/chromebook_coral/Kconfig @@ -0,0 +1,43 @@ +if TARGET_CHROMEBOOK_CORAL + +config SYS_BOARD + default "chromebook_coral" + +config SYS_VENDOR + default "google" + +config SYS_SOC + default "apollolake" + +config SYS_CONFIG_NAME + default "chromebook_coral" + +config SYS_TEXT_BASE + default 0xffe00000 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select INTEL_APOLLOLAKE + select BOARD_ROMSIZE_KB_16384 + +config PCIE_ECAM_BASE + default 0xf0000000 + +config EARLY_POST_CROS_EC + bool "Enable early post to Chrome OS EC" + help + Allow post codes to be sent to the Chroem OS EC early during boot, + to enable monitoring of the boot and debugging when things go wrong. + With this option enabled, the EC console can be used to watch post + codes the first part of boot. + +config SYS_CAR_ADDR + hex + default 0xfef00000 + +config SYS_CAR_SIZE + hex + default 0xc0000 + +endif diff --git a/board/google/chromebook_coral/MAINTAINERS b/board/google/chromebook_coral/MAINTAINERS new file mode 100644 index 0000000000..904227e2e2 --- /dev/null +++ b/board/google/chromebook_coral/MAINTAINERS @@ -0,0 +1,6 @@ +CHROMEBOOK_CORAL_BOARD +M: Simon Glass <sjg@chromium.org> +S: Maintained +F: board/google/chromebook_coral/ +F: include/configs/chromebook_coral.h +F: configs/chromebook_coral_defconfig diff --git a/board/google/chromebook_coral/Makefile b/board/google/chromebook_coral/Makefile new file mode 100644 index 0000000000..6a27ce3da1 --- /dev/null +++ b/board/google/chromebook_coral/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC + +obj-y += coral.o diff --git a/board/google/chromebook_coral/coral.c b/board/google/chromebook_coral/coral.c new file mode 100644 index 0000000000..4e34710b97 --- /dev/null +++ b/board/google/chromebook_coral/coral.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> + +int arch_misc_init(void) +{ + return 0; +} + +/* This function is needed if CONFIG_CMDLINE is not enabled */ +int board_run_command(const char *cmdline) +{ + printf("No command line\n"); + + return 0; +} diff --git a/board/keymile/Kconfig b/board/keymile/Kconfig index acaa9289f7..5f512d56da 100644 --- a/board/keymile/Kconfig +++ b/board/keymile/Kconfig @@ -62,6 +62,12 @@ config KM_CONSOLE_TTY help TTY console to use on board. +config KM_DEF_NETDEV + string "Default Netdevice" + default "eth0" + help + Default netdevice for debug interface + config KM_COMMON_ETH_INIT bool "Common Ethernet Initialization" default y if KIRKWOOD || MPC83xx diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index abbf985eb2..5969d51395 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -277,7 +277,7 @@ int dram_init(void) int checkboard(void) { - puts("Board: Keymile " CONFIG_KM_BOARD_NAME); + puts("Board: ABB " CONFIG_SYS_CONFIG_NAME); if (piggy_present()) puts(" with PIGGY."); diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index ae9653db78..88914c80e8 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -29,7 +29,7 @@ static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; int checkboard(void) { - printf("Board: Keymile %s\n", CONFIG_KM_BOARD_NAME); + printf("Board: Keymile %s\n", CONFIG_SYS_CONFIG_NAME); return 0; } diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c index 3e5174ef8a..0483041187 100644 --- a/board/toradex/apalis-imx8/apalis-imx8.c +++ b/board/toradex/apalis-imx8/apalis-imx8.c @@ -51,7 +51,7 @@ int board_early_init_f(void) return 0; } -#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { /* TODO */ diff --git a/cmd/Kconfig b/cmd/Kconfig index 1e4cf146c5..4e29e7b3c5 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -228,6 +228,14 @@ config CMD_LICENSE help Print GPL license text +config CMD_PMC + bool "pmc" + help + Provides access to the Intel Power-Management Controller (PMC) so + that its state can be examined. This does not currently support + changing the state but it is still useful for debugging and seeing + what is going on. + config CMD_REGINFO bool "reginfo" depends on PPC diff --git a/cmd/Makefile b/cmd/Makefile index 3ac7104546..12e898d962 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -109,6 +109,7 @@ ifdef CONFIG_PCI obj-$(CONFIG_CMD_PCI) += pci.o endif obj-$(CONFIG_CMD_PINMUX) += pinmux.o +obj-$(CONFIG_CMD_PMC) += pmc.o obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_CMD_QFW) += qfw.o diff --git a/cmd/pmc.c b/cmd/pmc.c new file mode 100644 index 0000000000..cafeba9fcc --- /dev/null +++ b/cmd/pmc.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel PMC command + * + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <power/acpi_pmc.h> + +static int get_pmc_dev(struct udevice **devp) +{ + struct udevice *dev; + int ret; + + ret = uclass_first_device_err(UCLASS_ACPI_PMC, &dev); + if (ret) { + printf("Could not find device (err=%d)\n", ret); + return ret; + } + ret = pmc_init(dev); + if (ret) { + printf("Could not init device (err=%d)\n", ret); + return ret; + } + *devp = dev; + + return 0; +} + +static int do_pmc_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + struct udevice *dev; + int ret; + + ret = get_pmc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + + return 0; +} + +static int do_pmc_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + struct udevice *dev; + int ret; + + ret = get_pmc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + pmc_dump_info(dev); + + return 0; +} + +static cmd_tbl_t cmd_pmc_sub[] = { + U_BOOT_CMD_MKENT(init, 0, 1, do_pmc_init, "", ""), + U_BOOT_CMD_MKENT(info, 0, 1, do_pmc_info, "", ""), +}; + +static int do_pmc(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + const cmd_tbl_t *cp; + + if (argc < 2) /* no subcommand */ + return cmd_usage(cmdtp); + + cp = find_cmd_tbl(argv[1], &cmd_pmc_sub[0], ARRAY_SIZE(cmd_pmc_sub)); + if (!cp) + return CMD_RET_USAGE; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + pmc, 2, 1, do_pmc, "Power-management controller info", + "info - read state and show info about the PMC\n" + "pmc init - read state from the PMC\n" + ); diff --git a/cmd/x86/fsp.c b/cmd/x86/fsp.c index b3b663021b..6e485fb144 100644 --- a/cmd/x86/fsp.c +++ b/cmd/x86/fsp.c @@ -5,23 +5,38 @@ #include <common.h> #include <command.h> -#include <asm/fsp1/fsp_support.h> +#include <asm/fsp/fsp_support.h> DECLARE_GLOBAL_DATA_PTR; static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - struct fsp_header *hdr = fsp_find_header(); - u32 img_addr = hdr->img_base; - char *sign = (char *)&hdr->sign; + struct fsp_header *hdr; + u32 img_addr; + char *sign; + uint addr; int i; - printf("FSP : binary 0x%08x, header 0x%08x\n", - CONFIG_FSP_ADDR, (int)hdr); +#ifdef CONFIG_FSP_VERSION2 + /* + * Only FSP-S is displayed. FSP-M was used in SPL but may not still be + * around, and we didn't keep a pointer to it. + */ + hdr = gd->arch.fsp_s_hdr; + img_addr = hdr->img_base; + addr = img_addr; +#else + addr = CONFIG_FSP_ADDR; + hdr = fsp_find_header(); + img_addr = hdr->img_base; +#endif + sign = (char *)&hdr->sign; + + printf("FSP : binary %08x, header %08x\n", addr, (int)hdr); printf("Header : sign "); for (i = 0; i < sizeof(hdr->sign); i++) printf("%c", *sign++); - printf(", size %d, rev %d\n", hdr->hdr_len, hdr->hdr_rev); + printf(", size %x, rev %d\n", hdr->hdr_len, hdr->hdr_rev); printf("Image : rev "); if (hdr->hdr_rev == FSP_HEADER_REVISION_1) { printf("%d.%d", @@ -34,24 +49,32 @@ static int do_hdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf(", id "); for (i = 0; i < ARRAY_SIZE(hdr->img_id); i++) printf("%c", hdr->img_id[i]); - printf(", addr 0x%08x, size %d\n", img_addr, hdr->img_size); - if (hdr->hdr_rev == FSP_HEADER_REVISION_2) { + printf(", addr %08x, size %x\n", img_addr, hdr->img_size); + if (hdr->hdr_rev >= FSP_HEADER_REVISION_1) { printf("GFX :%ssupported\n", hdr->img_attr & FSP_ATTR_GRAPHICS_SUPPORT ? " " : " un"); } - printf("VPD : addr 0x%08x, size %d\n", + printf("VPD : addr %08x, size %x\n", hdr->cfg_region_off + img_addr, hdr->cfg_region_size); - printf("\nNumber of APIs Supported : %d\n", hdr->api_num); - printf("\tTempRamInit : 0x%08x\n", hdr->fsp_tempram_init + img_addr); - printf("\tFspInit : 0x%08x\n", hdr->fsp_init + img_addr); - printf("\tFspNotify : 0x%08x\n", hdr->fsp_notify + img_addr); - if (hdr->hdr_rev == FSP_HEADER_REVISION_2) { - printf("\tMemoryInit : 0x%08x\n", - hdr->fsp_mem_init + img_addr); - printf("\tTempRamExit : 0x%08x\n", - hdr->fsp_tempram_exit + img_addr); - printf("\tSiliconInit : 0x%08x\n", - hdr->fsp_silicon_init + img_addr); + if (hdr->hdr_rev <= FSP_HEADER_REVISION_2) + printf("\nNumber of APIs Supported : %d\n", hdr->api_num); + if (hdr->fsp_tempram_init) + printf("\tTempRamInit : %08x\n", + hdr->fsp_tempram_init + img_addr); + if (hdr->fsp_init) + printf("\tFspInit : %08x\n", hdr->fsp_init + img_addr); + if (hdr->fsp_notify) + printf("\tFspNotify : %08x\n", hdr->fsp_notify + img_addr); + if (hdr->hdr_rev >= FSP_HEADER_REVISION_1) { + if (hdr->fsp_mem_init) + printf("\tMemoryInit : %08x\n", + hdr->fsp_mem_init + img_addr); + if (hdr->fsp_tempram_exit) + printf("\tTempRamExit : %08x\n", + hdr->fsp_tempram_exit + img_addr); + if (hdr->fsp_silicon_init) + printf("\tSiliconInit : %08x\n", + hdr->fsp_silicon_init + img_addr); } return 0; diff --git a/common/board_r.c b/common/board_r.c index 5464172259..e711de64b5 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -18,6 +18,7 @@ #if defined(CONFIG_CMD_BEDBUG) #include <bedbug/type.h> #endif +#include <binman.h> #include <command.h> #include <console.h> #include <dm.h> @@ -310,16 +311,24 @@ static int initr_dm(void) bootstage_accum(BOOTSTATE_ID_ACCUM_DM_R); if (ret) return ret; -#ifdef CONFIG_TIMER_EARLY - ret = dm_timer_init(); - if (ret) - return ret; -#endif return 0; } #endif +static int initr_dm_devices(void) +{ + int ret; + + if (IS_ENABLED(CONFIG_TIMER_EARLY)) { + ret = dm_timer_init(); + if (ret) + return ret; + } + + return 0; +} + static int initr_bootstage(void) { bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); @@ -347,6 +356,14 @@ static int initr_manual_reloc_cmdtable(void) } #endif +static int initr_binman(void) +{ + if (!CONFIG_IS_ENABLED(BINMAN_FDT)) + return 0; + + return binman_init(); +} + #if defined(CONFIG_MTD_NOR_FLASH) static int initr_flash(void) { @@ -697,6 +714,11 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_EFI_LOADER efi_memory_init, #endif + initr_binman, +#ifdef CONFIG_FSP_VERSION2 + arch_fsp_init_r, +#endif + initr_dm_devices, stdio_init_tables, initr_serial, initr_announce, diff --git a/common/spl/Kconfig b/common/spl/Kconfig index a72412718b..c527617e43 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -91,20 +91,24 @@ config SPL_SYS_REPORT_STACK_F_USAGE occurrence of non 0xaa bytes. This default implementation works for stacks growing down only. -menu "PowerPC SPL Boot options" - depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) +menu "PowerPC and LayerScape SPL Boot options" config SPL_NAND_BOOT bool "Load SPL from NAND flash" + depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) config SPL_MMC_BOOT bool "Load SPL from SD Card / eMMC" + depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) config SPL_SPI_BOOT bool "Load SPL from SPI flash" + depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK) config SPL_FSL_PBL bool "Create SPL in Freescale PBI format" + depends on (PPC || ARCH_LS1021A || ARCH_LS1043A || ARCH_LS1046A) && \ + SUPPORT_SPL help Create boot binary having SPL binary in PBI format concatenated with u-boot binary. diff --git a/common/spl/spl.c b/common/spl/spl.c index d51dbe9942..c1fce62b91 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -42,6 +42,12 @@ u32 *boot_params_ptr = NULL; /* See spl.h for information about this */ binman_sym_declare(ulong, u_boot_any, image_pos); +binman_sym_declare(ulong, u_boot_any, size); + +#ifdef CONFIG_TPL +binman_sym_declare(ulong, spl, image_pos); +binman_sym_declare(ulong, spl, size); +#endif /* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); @@ -120,6 +126,20 @@ void spl_fixup_fdt(void) #endif } +ulong spl_get_image_pos(void) +{ + return spl_phase() == PHASE_TPL ? + binman_sym(ulong, spl, image_pos) : + binman_sym(ulong, u_boot_any, image_pos); +} + +ulong spl_get_image_size(void) +{ + return spl_phase() == PHASE_TPL ? + binman_sym(ulong, spl, size) : + binman_sym(ulong, u_boot_any, size); +} + /* * Weak default function for board specific cleanup/preparation before * Linux boot. Some boards/platforms might not need it, so just provide diff --git a/configs/P1020MBG-PC_36BIT_SDCARD_defconfig b/configs/P1020MBG-PC_36BIT_SDCARD_defconfig index cb7293a973..47f879f43e 100644 --- a/configs/P1020MBG-PC_36BIT_SDCARD_defconfig +++ b/configs/P1020MBG-PC_36BIT_SDCARD_defconfig @@ -55,5 +55,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020MBG-PC_36BIT_defconfig b/configs/P1020MBG-PC_36BIT_defconfig index 9d0e4c58ad..e60561c6ae 100644 --- a/configs/P1020MBG-PC_36BIT_defconfig +++ b/configs/P1020MBG-PC_36BIT_defconfig @@ -43,5 +43,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020MBG-PC_SDCARD_defconfig b/configs/P1020MBG-PC_SDCARD_defconfig index e539efffbc..d36a2b03da 100644 --- a/configs/P1020MBG-PC_SDCARD_defconfig +++ b/configs/P1020MBG-PC_SDCARD_defconfig @@ -54,5 +54,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020MBG-PC_defconfig b/configs/P1020MBG-PC_defconfig index 06d50d0057..301a4d3024 100644 --- a/configs/P1020MBG-PC_defconfig +++ b/configs/P1020MBG-PC_defconfig @@ -42,5 +42,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020RDB-PC_36BIT_NAND_defconfig b/configs/P1020RDB-PC_36BIT_NAND_defconfig index 7ac2136f2d..01bdc611a2 100644 --- a/configs/P1020RDB-PC_36BIT_NAND_defconfig +++ b/configs/P1020RDB-PC_36BIT_NAND_defconfig @@ -73,3 +73,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_36BIT_SDCARD_defconfig b/configs/P1020RDB-PC_36BIT_SDCARD_defconfig index 347075f6fe..4cb1fb9773 100644 --- a/configs/P1020RDB-PC_36BIT_SDCARD_defconfig +++ b/configs/P1020RDB-PC_36BIT_SDCARD_defconfig @@ -68,3 +68,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig b/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig index e9cfd7f560..c6f0a1f99e 100644 --- a/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig +++ b/configs/P1020RDB-PC_36BIT_SPIFLASH_defconfig @@ -70,3 +70,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_36BIT_defconfig b/configs/P1020RDB-PC_36BIT_defconfig index d22ea96376..6cab654759 100644 --- a/configs/P1020RDB-PC_36BIT_defconfig +++ b/configs/P1020RDB-PC_36BIT_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_NAND_defconfig b/configs/P1020RDB-PC_NAND_defconfig index 5d697f186f..d8cd9a1c33 100644 --- a/configs/P1020RDB-PC_NAND_defconfig +++ b/configs/P1020RDB-PC_NAND_defconfig @@ -72,3 +72,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_SDCARD_defconfig b/configs/P1020RDB-PC_SDCARD_defconfig index 31415b2571..859a0f3cd6 100644 --- a/configs/P1020RDB-PC_SDCARD_defconfig +++ b/configs/P1020RDB-PC_SDCARD_defconfig @@ -67,3 +67,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_SPIFLASH_defconfig b/configs/P1020RDB-PC_SPIFLASH_defconfig index 328ca5e503..793bcaf65b 100644 --- a/configs/P1020RDB-PC_SPIFLASH_defconfig +++ b/configs/P1020RDB-PC_SPIFLASH_defconfig @@ -69,3 +69,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PC_defconfig b/configs/P1020RDB-PC_defconfig index c2ba41e14b..e337cebea4 100644 --- a/configs/P1020RDB-PC_defconfig +++ b/configs/P1020RDB-PC_defconfig @@ -56,3 +56,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PD_NAND_defconfig b/configs/P1020RDB-PD_NAND_defconfig index 23f449be3c..ac86d66cd2 100644 --- a/configs/P1020RDB-PD_NAND_defconfig +++ b/configs/P1020RDB-PD_NAND_defconfig @@ -76,3 +76,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PD_SDCARD_defconfig b/configs/P1020RDB-PD_SDCARD_defconfig index b155a97c3f..7654de295f 100644 --- a/configs/P1020RDB-PD_SDCARD_defconfig +++ b/configs/P1020RDB-PD_SDCARD_defconfig @@ -71,3 +71,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PD_SPIFLASH_defconfig b/configs/P1020RDB-PD_SPIFLASH_defconfig index e936128d23..2a29691ec2 100644 --- a/configs/P1020RDB-PD_SPIFLASH_defconfig +++ b/configs/P1020RDB-PD_SPIFLASH_defconfig @@ -73,3 +73,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020RDB-PD_defconfig b/configs/P1020RDB-PD_defconfig index e0a2e7ae92..fffdcc852a 100644 --- a/configs/P1020RDB-PD_defconfig +++ b/configs/P1020RDB-PD_defconfig @@ -60,3 +60,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P1020UTM-PC_36BIT_SDCARD_defconfig b/configs/P1020UTM-PC_36BIT_SDCARD_defconfig index 2cd245edf0..1bbca3be0d 100644 --- a/configs/P1020UTM-PC_36BIT_SDCARD_defconfig +++ b/configs/P1020UTM-PC_36BIT_SDCARD_defconfig @@ -55,5 +55,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020UTM-PC_36BIT_defconfig b/configs/P1020UTM-PC_36BIT_defconfig index 793ab1535f..593f958df5 100644 --- a/configs/P1020UTM-PC_36BIT_defconfig +++ b/configs/P1020UTM-PC_36BIT_defconfig @@ -43,5 +43,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020UTM-PC_SDCARD_defconfig b/configs/P1020UTM-PC_SDCARD_defconfig index 1bdc2aaa00..9d96ff80cc 100644 --- a/configs/P1020UTM-PC_SDCARD_defconfig +++ b/configs/P1020UTM-PC_SDCARD_defconfig @@ -54,5 +54,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P1020UTM-PC_defconfig b/configs/P1020UTM-PC_defconfig index bd366e953b..967c41d72f 100644 --- a/configs/P1020UTM-PC_defconfig +++ b/configs/P1020UTM-PC_defconfig @@ -42,5 +42,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P2020RDB-PC_36BIT_NAND_defconfig b/configs/P2020RDB-PC_36BIT_NAND_defconfig index 7209321ed5..42a1a3ef31 100644 --- a/configs/P2020RDB-PC_36BIT_NAND_defconfig +++ b/configs/P2020RDB-PC_36BIT_NAND_defconfig @@ -78,3 +78,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_36BIT_SDCARD_defconfig b/configs/P2020RDB-PC_36BIT_SDCARD_defconfig index 0bd9417dfa..6cd99e10af 100644 --- a/configs/P2020RDB-PC_36BIT_SDCARD_defconfig +++ b/configs/P2020RDB-PC_36BIT_SDCARD_defconfig @@ -73,3 +73,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig b/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig index 379ae8402e..fa18cf7a42 100644 --- a/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig +++ b/configs/P2020RDB-PC_36BIT_SPIFLASH_defconfig @@ -75,3 +75,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_36BIT_defconfig b/configs/P2020RDB-PC_36BIT_defconfig index 831fb97930..8655b15b91 100644 --- a/configs/P2020RDB-PC_36BIT_defconfig +++ b/configs/P2020RDB-PC_36BIT_defconfig @@ -62,3 +62,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_NAND_defconfig b/configs/P2020RDB-PC_NAND_defconfig index 098d627d07..0b56ae05d1 100644 --- a/configs/P2020RDB-PC_NAND_defconfig +++ b/configs/P2020RDB-PC_NAND_defconfig @@ -77,3 +77,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_SDCARD_defconfig b/configs/P2020RDB-PC_SDCARD_defconfig index 87f804fe88..6b94aa4b40 100644 --- a/configs/P2020RDB-PC_SDCARD_defconfig +++ b/configs/P2020RDB-PC_SDCARD_defconfig @@ -72,3 +72,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_SPIFLASH_defconfig b/configs/P2020RDB-PC_SPIFLASH_defconfig index bc3125f8e4..d107607acd 100644 --- a/configs/P2020RDB-PC_SPIFLASH_defconfig +++ b/configs/P2020RDB-PC_SPIFLASH_defconfig @@ -74,3 +74,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2020RDB-PC_defconfig b/configs/P2020RDB-PC_defconfig index 0cf84462b5..d681e59732 100644 --- a/configs/P2020RDB-PC_defconfig +++ b/configs/P2020RDB-PC_defconfig @@ -61,3 +61,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2041RDB_NAND_defconfig b/configs/P2041RDB_NAND_defconfig index 398835353f..110e50bfd9 100644 --- a/configs/P2041RDB_NAND_defconfig +++ b/configs/P2041RDB_NAND_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2041RDB_SDCARD_defconfig b/configs/P2041RDB_SDCARD_defconfig index 7807d954d6..c47c60158d 100644 --- a/configs/P2041RDB_SDCARD_defconfig +++ b/configs/P2041RDB_SDCARD_defconfig @@ -56,3 +56,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2041RDB_SPIFLASH_defconfig b/configs/P2041RDB_SPIFLASH_defconfig index ab6c7a76fa..a8187c6a84 100644 --- a/configs/P2041RDB_SPIFLASH_defconfig +++ b/configs/P2041RDB_SPIFLASH_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig b/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig index ce354ae609..f7d403e4f5 100644 --- a/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig +++ b/configs/P2041RDB_SRIO_PCIE_BOOT_defconfig @@ -43,5 +43,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P2041RDB_defconfig b/configs/P2041RDB_defconfig index d6c56dbfbd..3a79fc62b6 100644 --- a/configs/P2041RDB_defconfig +++ b/configs/P2041RDB_defconfig @@ -55,3 +55,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P3041DS_NAND_defconfig b/configs/P3041DS_NAND_defconfig index a76be9e985..473ad5b055 100644 --- a/configs/P3041DS_NAND_defconfig +++ b/configs/P3041DS_NAND_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P3041DS_SDCARD_defconfig b/configs/P3041DS_SDCARD_defconfig index abfed4f5f0..806653e748 100644 --- a/configs/P3041DS_SDCARD_defconfig +++ b/configs/P3041DS_SDCARD_defconfig @@ -56,3 +56,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P3041DS_SPIFLASH_defconfig b/configs/P3041DS_SPIFLASH_defconfig index ddbb813d06..b354f36fb1 100644 --- a/configs/P3041DS_SPIFLASH_defconfig +++ b/configs/P3041DS_SPIFLASH_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P3041DS_SRIO_PCIE_BOOT_defconfig b/configs/P3041DS_SRIO_PCIE_BOOT_defconfig index a8e4512bf4..5f2d3dbae3 100644 --- a/configs/P3041DS_SRIO_PCIE_BOOT_defconfig +++ b/configs/P3041DS_SRIO_PCIE_BOOT_defconfig @@ -43,5 +43,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P3041DS_defconfig b/configs/P3041DS_defconfig index 5587001b3c..e00958566a 100644 --- a/configs/P3041DS_defconfig +++ b/configs/P3041DS_defconfig @@ -55,3 +55,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P4080DS_SDCARD_defconfig b/configs/P4080DS_SDCARD_defconfig index 53d9fb4e56..da929598f6 100644 --- a/configs/P4080DS_SDCARD_defconfig +++ b/configs/P4080DS_SDCARD_defconfig @@ -55,3 +55,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P4080DS_SPIFLASH_defconfig b/configs/P4080DS_SPIFLASH_defconfig index dc58d62472..a8f778f057 100644 --- a/configs/P4080DS_SPIFLASH_defconfig +++ b/configs/P4080DS_SPIFLASH_defconfig @@ -56,3 +56,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P4080DS_SRIO_PCIE_BOOT_defconfig b/configs/P4080DS_SRIO_PCIE_BOOT_defconfig index a090bed0bc..bc1c9caf6d 100644 --- a/configs/P4080DS_SRIO_PCIE_BOOT_defconfig +++ b/configs/P4080DS_SRIO_PCIE_BOOT_defconfig @@ -41,5 +41,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/P4080DS_defconfig b/configs/P4080DS_defconfig index 9deeb3f3d1..fcefd8d1e7 100644 --- a/configs/P4080DS_defconfig +++ b/configs/P4080DS_defconfig @@ -54,3 +54,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P5040DS_NAND_defconfig b/configs/P5040DS_NAND_defconfig index ea2197d750..4c3f705238 100644 --- a/configs/P5040DS_NAND_defconfig +++ b/configs/P5040DS_NAND_defconfig @@ -58,3 +58,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P5040DS_SDCARD_defconfig b/configs/P5040DS_SDCARD_defconfig index 511b194849..3874e06f31 100644 --- a/configs/P5040DS_SDCARD_defconfig +++ b/configs/P5040DS_SDCARD_defconfig @@ -56,3 +56,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P5040DS_SPIFLASH_defconfig b/configs/P5040DS_SPIFLASH_defconfig index 49efaae6f4..7dd082747b 100644 --- a/configs/P5040DS_SPIFLASH_defconfig +++ b/configs/P5040DS_SPIFLASH_defconfig @@ -57,3 +57,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/P5040DS_defconfig b/configs/P5040DS_defconfig index 47613460ee..d531401796 100644 --- a/configs/P5040DS_defconfig +++ b/configs/P5040DS_defconfig @@ -55,3 +55,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T1023RDB_NAND_defconfig b/configs/T1023RDB_NAND_defconfig index f38f46804a..b060d1e083 100644 --- a/configs/T1023RDB_NAND_defconfig +++ b/configs/T1023RDB_NAND_defconfig @@ -70,5 +70,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1023RDB_SDCARD_defconfig b/configs/T1023RDB_SDCARD_defconfig index 2f699fa9c0..6d2021617e 100644 --- a/configs/T1023RDB_SDCARD_defconfig +++ b/configs/T1023RDB_SDCARD_defconfig @@ -67,5 +67,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1023RDB_SPIFLASH_defconfig b/configs/T1023RDB_SPIFLASH_defconfig index 230eae72ac..ab24a4820d 100644 --- a/configs/T1023RDB_SPIFLASH_defconfig +++ b/configs/T1023RDB_SPIFLASH_defconfig @@ -70,5 +70,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1023RDB_defconfig b/configs/T1023RDB_defconfig index ede4ccac6a..b8d3c98838 100644 --- a/configs/T1023RDB_defconfig +++ b/configs/T1023RDB_defconfig @@ -54,5 +54,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024QDS_DDR4_defconfig b/configs/T1024QDS_DDR4_defconfig index d21bfb48d4..582dcf9da1 100644 --- a/configs/T1024QDS_DDR4_defconfig +++ b/configs/T1024QDS_DDR4_defconfig @@ -55,6 +55,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024QDS_NAND_defconfig b/configs/T1024QDS_NAND_defconfig index f7649e0769..3087368e9d 100644 --- a/configs/T1024QDS_NAND_defconfig +++ b/configs/T1024QDS_NAND_defconfig @@ -74,6 +74,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024QDS_SDCARD_defconfig b/configs/T1024QDS_SDCARD_defconfig index 0303fa4a0e..6617b4dfd7 100644 --- a/configs/T1024QDS_SDCARD_defconfig +++ b/configs/T1024QDS_SDCARD_defconfig @@ -71,6 +71,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024QDS_SPIFLASH_defconfig b/configs/T1024QDS_SPIFLASH_defconfig index 1ac3ff43a2..e698c9d5db 100644 --- a/configs/T1024QDS_SPIFLASH_defconfig +++ b/configs/T1024QDS_SPIFLASH_defconfig @@ -74,6 +74,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024QDS_defconfig b/configs/T1024QDS_defconfig index 3517cfd562..8c9bd73af6 100644 --- a/configs/T1024QDS_defconfig +++ b/configs/T1024QDS_defconfig @@ -58,6 +58,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1024RDB_NAND_defconfig b/configs/T1024RDB_NAND_defconfig index f324ec2e98..19fe0c992d 100644 --- a/configs/T1024RDB_NAND_defconfig +++ b/configs/T1024RDB_NAND_defconfig @@ -79,3 +79,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T1024RDB_SDCARD_defconfig b/configs/T1024RDB_SDCARD_defconfig index f8a97e9f0e..0062387a7f 100644 --- a/configs/T1024RDB_SDCARD_defconfig +++ b/configs/T1024RDB_SDCARD_defconfig @@ -76,3 +76,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T1024RDB_SPIFLASH_defconfig b/configs/T1024RDB_SPIFLASH_defconfig index 3e07a5cb16..1f48ed4ab4 100644 --- a/configs/T1024RDB_SPIFLASH_defconfig +++ b/configs/T1024RDB_SPIFLASH_defconfig @@ -79,3 +79,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T1024RDB_defconfig b/configs/T1024RDB_defconfig index 543703db3e..ad4ba96a2e 100644 --- a/configs/T1024RDB_defconfig +++ b/configs/T1024RDB_defconfig @@ -64,3 +64,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T1040D4RDB_NAND_defconfig b/configs/T1040D4RDB_NAND_defconfig index f0ae1b035b..a0d39410fd 100644 --- a/configs/T1040D4RDB_NAND_defconfig +++ b/configs/T1040D4RDB_NAND_defconfig @@ -69,5 +69,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040D4RDB_SDCARD_defconfig b/configs/T1040D4RDB_SDCARD_defconfig index fd7a3246d8..9849cebfa9 100644 --- a/configs/T1040D4RDB_SDCARD_defconfig +++ b/configs/T1040D4RDB_SDCARD_defconfig @@ -66,5 +66,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040D4RDB_SPIFLASH_defconfig b/configs/T1040D4RDB_SPIFLASH_defconfig index e3df245730..accc0c7b0c 100644 --- a/configs/T1040D4RDB_SPIFLASH_defconfig +++ b/configs/T1040D4RDB_SPIFLASH_defconfig @@ -69,5 +69,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040D4RDB_defconfig b/configs/T1040D4RDB_defconfig index 8177b1653c..5283e2f49b 100644 --- a/configs/T1040D4RDB_defconfig +++ b/configs/T1040D4RDB_defconfig @@ -53,5 +53,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040QDS_DDR4_defconfig b/configs/T1040QDS_DDR4_defconfig index 9cb012cf6f..4cc50d49e3 100644 --- a/configs/T1040QDS_DDR4_defconfig +++ b/configs/T1040QDS_DDR4_defconfig @@ -58,6 +58,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040QDS_defconfig b/configs/T1040QDS_defconfig index 94c02a9810..cbbd50e243 100644 --- a/configs/T1040QDS_defconfig +++ b/configs/T1040QDS_defconfig @@ -59,6 +59,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040RDB_NAND_defconfig b/configs/T1040RDB_NAND_defconfig index bee51c5610..94ec95a886 100644 --- a/configs/T1040RDB_NAND_defconfig +++ b/configs/T1040RDB_NAND_defconfig @@ -70,5 +70,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040RDB_SDCARD_defconfig b/configs/T1040RDB_SDCARD_defconfig index e272c13d7d..e882f9a9d0 100644 --- a/configs/T1040RDB_SDCARD_defconfig +++ b/configs/T1040RDB_SDCARD_defconfig @@ -67,5 +67,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040RDB_SPIFLASH_defconfig b/configs/T1040RDB_SPIFLASH_defconfig index 5bae4a5c78..ab0aacac39 100644 --- a/configs/T1040RDB_SPIFLASH_defconfig +++ b/configs/T1040RDB_SPIFLASH_defconfig @@ -70,5 +70,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1040RDB_defconfig b/configs/T1040RDB_defconfig index f5c2c1795e..50eab6983d 100644 --- a/configs/T1040RDB_defconfig +++ b/configs/T1040RDB_defconfig @@ -54,5 +54,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T1042D4RDB_NAND_defconfig b/configs/T1042D4RDB_NAND_defconfig index 80a631f06a..2b117a47e7 100644 --- a/configs/T1042D4RDB_NAND_defconfig +++ b/configs/T1042D4RDB_NAND_defconfig @@ -77,5 +77,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042D4RDB_SDCARD_defconfig b/configs/T1042D4RDB_SDCARD_defconfig index 0838e3c821..bf77f38ab1 100644 --- a/configs/T1042D4RDB_SDCARD_defconfig +++ b/configs/T1042D4RDB_SDCARD_defconfig @@ -74,5 +74,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042D4RDB_SPIFLASH_defconfig b/configs/T1042D4RDB_SPIFLASH_defconfig index fa93f5b9f8..8fe38eb5a1 100644 --- a/configs/T1042D4RDB_SPIFLASH_defconfig +++ b/configs/T1042D4RDB_SPIFLASH_defconfig @@ -77,5 +77,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042D4RDB_defconfig b/configs/T1042D4RDB_defconfig index af989d4105..4e66073ef4 100644 --- a/configs/T1042D4RDB_defconfig +++ b/configs/T1042D4RDB_defconfig @@ -62,5 +62,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042RDB_PI_NAND_defconfig b/configs/T1042RDB_PI_NAND_defconfig index 204cd8a612..b1bb253d61 100644 --- a/configs/T1042RDB_PI_NAND_defconfig +++ b/configs/T1042RDB_PI_NAND_defconfig @@ -72,6 +72,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042RDB_PI_SDCARD_defconfig b/configs/T1042RDB_PI_SDCARD_defconfig index c291ddc004..3e31774647 100644 --- a/configs/T1042RDB_PI_SDCARD_defconfig +++ b/configs/T1042RDB_PI_SDCARD_defconfig @@ -69,6 +69,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042RDB_PI_SPIFLASH_defconfig b/configs/T1042RDB_PI_SPIFLASH_defconfig index cd3f5e3301..8003d7dc9e 100644 --- a/configs/T1042RDB_PI_SPIFLASH_defconfig +++ b/configs/T1042RDB_PI_SPIFLASH_defconfig @@ -72,6 +72,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042RDB_PI_defconfig b/configs/T1042RDB_PI_defconfig index 727d1f251f..35035ea5d6 100644 --- a/configs/T1042RDB_PI_defconfig +++ b/configs/T1042RDB_PI_defconfig @@ -56,6 +56,7 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_VIDEO=y CONFIG_CFB_CONSOLE_ANSI=y diff --git a/configs/T1042RDB_defconfig b/configs/T1042RDB_defconfig index cf8ae99a71..6dc0c1bd5c 100644 --- a/configs/T1042RDB_defconfig +++ b/configs/T1042RDB_defconfig @@ -53,5 +53,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2080RDB_NAND_defconfig b/configs/T2080RDB_NAND_defconfig index 0e72898dde..d6eadd5c66 100644 --- a/configs/T2080RDB_NAND_defconfig +++ b/configs/T2080RDB_NAND_defconfig @@ -77,3 +77,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T2080RDB_SDCARD_defconfig b/configs/T2080RDB_SDCARD_defconfig index f5929f5cbc..041c1bae77 100644 --- a/configs/T2080RDB_SDCARD_defconfig +++ b/configs/T2080RDB_SDCARD_defconfig @@ -74,3 +74,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T2080RDB_SPIFLASH_defconfig b/configs/T2080RDB_SPIFLASH_defconfig index fe20c17902..7ee9a8ffc5 100644 --- a/configs/T2080RDB_SPIFLASH_defconfig +++ b/configs/T2080RDB_SPIFLASH_defconfig @@ -77,3 +77,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig b/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig index e6de728c6f..f599e07a12 100644 --- a/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig +++ b/configs/T2080RDB_SRIO_PCIE_BOOT_defconfig @@ -46,5 +46,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2080RDB_defconfig b/configs/T2080RDB_defconfig index 5d5f246334..ea43eb5d17 100644 --- a/configs/T2080RDB_defconfig +++ b/configs/T2080RDB_defconfig @@ -61,3 +61,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T2081QDS_NAND_defconfig b/configs/T2081QDS_NAND_defconfig index 0ce4168e6f..ced1f3914e 100644 --- a/configs/T2081QDS_NAND_defconfig +++ b/configs/T2081QDS_NAND_defconfig @@ -68,5 +68,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2081QDS_SDCARD_defconfig b/configs/T2081QDS_SDCARD_defconfig index 13f22c178b..133577d609 100644 --- a/configs/T2081QDS_SDCARD_defconfig +++ b/configs/T2081QDS_SDCARD_defconfig @@ -65,5 +65,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2081QDS_SPIFLASH_defconfig b/configs/T2081QDS_SPIFLASH_defconfig index 2d9d491cfc..2726d6f38f 100644 --- a/configs/T2081QDS_SPIFLASH_defconfig +++ b/configs/T2081QDS_SPIFLASH_defconfig @@ -68,5 +68,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig b/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig index 8d00ad65eb..33b375ae56 100644 --- a/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig +++ b/configs/T2081QDS_SRIO_PCIE_BOOT_defconfig @@ -44,5 +44,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T2081QDS_defconfig b/configs/T2081QDS_defconfig index bfa40b5ef9..c1354e2c27 100644 --- a/configs/T2081QDS_defconfig +++ b/configs/T2081QDS_defconfig @@ -52,5 +52,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T4240QDS_NAND_defconfig b/configs/T4240QDS_NAND_defconfig index b5a867c77b..46c23b352a 100644 --- a/configs/T4240QDS_NAND_defconfig +++ b/configs/T4240QDS_NAND_defconfig @@ -62,5 +62,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T4240QDS_SDCARD_defconfig b/configs/T4240QDS_SDCARD_defconfig index c735b3d147..7d632ac5f7 100644 --- a/configs/T4240QDS_SDCARD_defconfig +++ b/configs/T4240QDS_SDCARD_defconfig @@ -59,5 +59,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T4240QDS_SRIO_PCIE_BOOT_defconfig b/configs/T4240QDS_SRIO_PCIE_BOOT_defconfig index 29cadfa3a8..55ba67d2a9 100644 --- a/configs/T4240QDS_SRIO_PCIE_BOOT_defconfig +++ b/configs/T4240QDS_SRIO_PCIE_BOOT_defconfig @@ -42,5 +42,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T4240QDS_defconfig b/configs/T4240QDS_defconfig index 3d7aa9f987..38ba19777d 100644 --- a/configs/T4240QDS_defconfig +++ b/configs/T4240QDS_defconfig @@ -46,5 +46,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_STORAGE=y CONFIG_OF_LIBFDT=y diff --git a/configs/T4240RDB_SDCARD_defconfig b/configs/T4240RDB_SDCARD_defconfig index 5b7034acc3..d01163b578 100644 --- a/configs/T4240RDB_SDCARD_defconfig +++ b/configs/T4240RDB_SDCARD_defconfig @@ -67,3 +67,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/T4240RDB_defconfig b/configs/T4240RDB_defconfig index 6287956f4c..426ddef391 100644 --- a/configs/T4240RDB_defconfig +++ b/configs/T4240RDB_defconfig @@ -55,3 +55,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_FSL_ESPI=y CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig new file mode 100644 index 0000000000..566d47d22f --- /dev/null +++ b/configs/chromebook_coral_defconfig @@ -0,0 +1,102 @@ +CONFIG_X86=y +CONFIG_SYS_TEXT_BASE=0x1110000 +CONFIG_SYS_MALLOC_F_LEN=0x3d00 +CONFIG_SPL_SYS_MALLOC_F_LEN=0xf000 +CONFIG_NR_DRAM_BANKS=8 +CONFIG_BOOTSTAGE_STASH_ADDR=0xfef00000 +CONFIG_DEBUG_UART_BOARD_INIT=y +CONFIG_DEBUG_UART_BASE=0xde000000 +CONFIG_DEBUG_UART_CLOCK=1843200 +CONFIG_VENDOR_GOOGLE=y +CONFIG_TARGET_CHROMEBOOK_CORAL=y +CONFIG_DEBUG_UART=y +CONFIG_FSP_VERSION2=y +CONFIG_HAVE_ACPI_RESUME=y +CONFIG_INTEL_CAR_CQOS=y +CONFIG_X86_OFFSET_U_BOOT=0xffe00000 +CONFIG_X86_OFFSET_SPL=0xffe80000 +CONFIG_SPL_TEXT_BASE=0xfef10000 +CONFIG_BOOTSTAGE=y +CONFIG_SPL_BOOTSTAGE=y +CONFIG_TPL_BOOTSTAGE=y +CONFIG_BOOTSTAGE_REPORT=y +CONFIG_SPL_BOOTSTAGE_RECORD_COUNT=10 +CONFIG_BOOTSTAGE_STASH=y +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro earlyprintk console=tty0 console=ttyS0,115200" +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_SPL_LOG=y +CONFIG_LOG_DEFAULT_LEVEL=7 +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_LAST_STAGE_INIT=y +CONFIG_BLOBLIST=y +# CONFIG_TPL_BLOBLIST is not set +CONFIG_BLOBLIST_ADDR=0x100000 +CONFIG_HANDOFF=y +CONFIG_TPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_CPU_SUPPORT=y +CONFIG_SPL_PCI=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_HUSH_PARSER=y +CONFIG_CMD_CPU=y +CONFIG_CMD_PMC=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_SATA=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_SOUND=y +CONFIG_CMD_BOOTSTAGE=y +CONFIG_CMD_TPM=y +CONFIG_CMD_TPM_TEST=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_MAC_PARTITION=y +# CONFIG_SPL_MAC_PARTITION is not set +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_ISO_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="chromebook_coral" +# CONFIG_NET is not set +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CPU=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_DW=y +CONFIG_TPL_MISC=y +CONFIG_CROS_EC=y +CONFIG_CROS_EC_LPC=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_X86_PCH7 is not set +# CONFIG_X86_PCH9 is not set +CONFIG_PINCTRL=y +# CONFIG_SPL_PINCTRL_FULL is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550=y +CONFIG_SOUND=y +CONFIG_SOUND_I8254=y +CONFIG_SOUND_RT5677=y +CONFIG_SPI=y +CONFIG_ICH_SPI=y +CONFIG_TPL_SYSRESET=y +CONFIG_TPM_TIS_LPC=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_KEYBOARD=y +CONFIG_SPL_FS_CBFS=y +# CONFIG_SPL_USE_TINY_PRINTF is not set +CONFIG_TPL_USE_TINY_PRINTF=y +CONFIG_CMD_DHRYSTONE=y +CONFIG_TPM=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/chromebook_samus_tpl_defconfig b/configs/chromebook_samus_tpl_defconfig index 5ef2ecb1c4..403b754ce9 100644 --- a/configs/chromebook_samus_tpl_defconfig +++ b/configs/chromebook_samus_tpl_defconfig @@ -16,6 +16,7 @@ CONFIG_HAVE_REFCODE=y CONFIG_SMP=y CONFIG_HAVE_VGA_BIOS=y CONFIG_SPL_TEXT_BASE=0xffe70000 +CONFIG_X86_OFFSET_U_BOOT=0xfff00000 CONFIG_BOOTSTAGE=y CONFIG_BOOTSTAGE_REPORT=y CONFIG_SHOW_BOOT_PROGRESS=y @@ -71,6 +72,8 @@ CONFIG_SYS_I2C_DW=y CONFIG_TPL_MISC=y CONFIG_CROS_EC=y CONFIG_CROS_EC_LPC=y +# CONFIG_SPL_PINCTRL is not set +# CONFIG_TPL_PINCTRL is not set CONFIG_SYS_NS16550=y CONFIG_SOUND=y CONFIG_SOUND_I8254=y diff --git a/configs/kmcoge4_defconfig b/configs/kmcoge4_defconfig index fcab61e991..80e0c92863 100644 --- a/configs/kmcoge4_defconfig +++ b/configs/kmcoge4_defconfig @@ -6,6 +6,7 @@ CONFIG_SYS_BOOTCOUNT_ADDR=0xFB000020 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_MPC85xx=y CONFIG_TARGET_KMP204X=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y @@ -42,6 +43,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_OFFSET_REDUND=0x110000 CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmcoge5ne_defconfig b/configs/kmcoge5ne_defconfig index c5e709e28c..7e65f3c26a 100644 --- a/configs/kmcoge5ne_defconfig +++ b/configs/kmcoge5ne_defconfig @@ -1,5 +1,6 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xF0000000 +CONFIG_KM_DEF_NETDEV="eth1" CONFIG_ENV_SIZE=0x4000 CONFIG_SYS_BOOTCOUNT_ADDR=0xE011BFF8 CONFIG_ENV_SECT_SIZE=0x20000 @@ -154,6 +155,7 @@ CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_DBYP_PLL_BYPASSED=y CONFIG_LCRR_EADC_2=y CONFIG_LCRR_CLKDIV_4=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -182,6 +184,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmeter1_defconfig b/configs/kmeter1_defconfig index 18f9625784..5f3aa2e9b9 100644 --- a/configs/kmeter1_defconfig +++ b/configs/kmeter1_defconfig @@ -1,5 +1,6 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xF0000000 +CONFIG_KM_DEF_NETDEV="eth2" CONFIG_ENV_SIZE=0x4000 CONFIG_SYS_BOOTCOUNT_ADDR=0xE011BFF8 CONFIG_ENV_SECT_SIZE=0x20000 @@ -118,6 +119,7 @@ CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_DBYP_PLL_BYPASSED=y CONFIG_LCRR_EADC_2=y CONFIG_LCRR_CLKDIV_4=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -145,6 +147,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmopti2_defconfig b/configs/kmopti2_defconfig index 7d0597161c..7ba06b253a 100644 --- a/configs/kmopti2_defconfig +++ b/configs/kmopti2_defconfig @@ -138,6 +138,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -165,6 +166,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmsupx5_defconfig b/configs/kmsupx5_defconfig index fe17be0a0f..e4548add35 100644 --- a/configs/kmsupx5_defconfig +++ b/configs/kmsupx5_defconfig @@ -118,6 +118,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -145,6 +146,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmtegr1_defconfig b/configs/kmtegr1_defconfig index 91b7aa8b77..d62f49f027 100644 --- a/configs/kmtegr1_defconfig +++ b/configs/kmtegr1_defconfig @@ -1,5 +1,6 @@ CONFIG_PPC=y CONFIG_SYS_TEXT_BASE=0xF0000000 +CONFIG_KM_DEF_NETDEV="eth1" CONFIG_ENV_SIZE=0x4000 CONFIG_SYS_BOOTCOUNT_ADDR=0xE0113FF8 CONFIG_ENV_SECT_SIZE=0x20000 @@ -116,6 +117,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_EXTRA_OPTIONS="KMTEGR1" @@ -146,6 +148,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF0100000 CONFIG_ENV_ADDR_REDUND=0xF0120000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/kmtepr2_defconfig b/configs/kmtepr2_defconfig index 3605a55b2a..e710c9f137 100644 --- a/configs/kmtepr2_defconfig +++ b/configs/kmtepr2_defconfig @@ -138,6 +138,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -165,6 +166,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/ls1021aiot_sdcard_defconfig b/configs/ls1021aiot_sdcard_defconfig index 8de8b7f351..f083bb28ef 100644 --- a/configs/ls1021aiot_sdcard_defconfig +++ b/configs/ls1021aiot_sdcard_defconfig @@ -7,6 +7,7 @@ CONFIG_ENV_OFFSET=0x100000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SD_BOOT,SD_BOOT_QSPI" CONFIG_MISC_INIT_R=y diff --git a/configs/ls1021aqds_nand_defconfig b/configs/ls1021aqds_nand_defconfig index b6c0f39de3..8cac448e35 100644 --- a/configs/ls1021aqds_nand_defconfig +++ b/configs/ls1021aqds_nand_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x140000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1021aqds_sdcard_ifc_defconfig b/configs/ls1021aqds_sdcard_ifc_defconfig index c57e5ff1ba..efe0031be2 100644 --- a/configs/ls1021aqds_sdcard_ifc_defconfig +++ b/configs/ls1021aqds_sdcard_ifc_defconfig @@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1021aqds_sdcard_qspi_defconfig b/configs/ls1021aqds_sdcard_qspi_defconfig index 8ed3dbd6c3..72616555c4 100644 --- a/configs/ls1021aqds_sdcard_qspi_defconfig +++ b/configs/ls1021aqds_sdcard_qspi_defconfig @@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig index 1859a8f867..af002b7893 100644 --- a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_ENV_SIZE=0x20000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y diff --git a/configs/ls1021atwr_sdcard_ifc_defconfig b/configs/ls1021atwr_sdcard_ifc_defconfig index b330ca7c32..ce6253c26d 100644 --- a/configs/ls1021atwr_sdcard_ifc_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y diff --git a/configs/ls1021atwr_sdcard_qspi_defconfig b/configs/ls1021atwr_sdcard_qspi_defconfig index 7fbf82e6d3..a231672ebc 100644 --- a/configs/ls1021atwr_sdcard_qspi_defconfig +++ b/configs/ls1021atwr_sdcard_qspi_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y diff --git a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig index a69e892cee..31e3b5a9b6 100644 --- a/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028aqds_tfa_SECURE_BOOT_defconfig @@ -3,6 +3,7 @@ CONFIG_TARGET_LS1028AQDS=y CONFIG_TFABOOT=y CONFIG_SYS_MALLOC_F_LEN=0x6000 CONFIG_NXP_ESBC=y +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_SYS_FSL_SDHC_CLK_DIV=1 CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=2 diff --git a/configs/ls1028aqds_tfa_defconfig b/configs/ls1028aqds_tfa_defconfig index 538830d9d9..72922120e9 100644 --- a/configs/ls1028aqds_tfa_defconfig +++ b/configs/ls1028aqds_tfa_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_TARGET_LS1028AQDS=y CONFIG_TFABOOT=y CONFIG_SYS_MALLOC_F_LEN=0x6000 +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_SYS_FSL_SDHC_CLK_DIV=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x500000 diff --git a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig index 55769c7738..db92204d98 100644 --- a/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/ls1028ardb_tfa_SECURE_BOOT_defconfig @@ -3,6 +3,7 @@ CONFIG_TARGET_LS1028ARDB=y CONFIG_TFABOOT=y CONFIG_SYS_MALLOC_F_LEN=0x6000 CONFIG_NXP_ESBC=y +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_SYS_FSL_SDHC_CLK_DIV=1 CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=2 diff --git a/configs/ls1028ardb_tfa_defconfig b/configs/ls1028ardb_tfa_defconfig index 870d6b7345..41fe40a853 100644 --- a/configs/ls1028ardb_tfa_defconfig +++ b/configs/ls1028ardb_tfa_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_TARGET_LS1028ARDB=y CONFIG_TFABOOT=y CONFIG_SYS_MALLOC_F_LEN=0x6000 +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_SYS_FSL_SDHC_CLK_DIV=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x500000 @@ -80,4 +81,8 @@ CONFIG_USB_XHCI_DWC3=y CONFIG_WDT=y CONFIG_WDT_SP805=y CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_ASIX88179=y CONFIG_EFI_LOADER_BOUNCE_BUFFER=y diff --git a/configs/ls1043aqds_nand_defconfig b/configs/ls1043aqds_nand_defconfig index 8eb80dc53a..d890172d71 100644 --- a/configs/ls1043aqds_nand_defconfig +++ b/configs/ls1043aqds_nand_defconfig @@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043aqds_sdcard_ifc_defconfig b/configs/ls1043aqds_sdcard_ifc_defconfig index 7d70c4613a..61336b218a 100644 --- a/configs/ls1043aqds_sdcard_ifc_defconfig +++ b/configs/ls1043aqds_sdcard_ifc_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043aqds_sdcard_qspi_defconfig b/configs/ls1043aqds_sdcard_qspi_defconfig index 3ee00a87eb..41d9f874b0 100644 --- a/configs/ls1043aqds_sdcard_qspi_defconfig +++ b/configs/ls1043aqds_sdcard_qspi_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043ardb_nand_SECURE_BOOT_defconfig b/configs/ls1043ardb_nand_SECURE_BOOT_defconfig index 3f5af36725..5ebd59c4c3 100644 --- a/configs/ls1043ardb_nand_SECURE_BOOT_defconfig +++ b/configs/ls1043ardb_nand_SECURE_BOOT_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043ardb_nand_defconfig b/configs/ls1043ardb_nand_defconfig index 973bda9b6e..bf5243d840 100644 --- a/configs/ls1043ardb_nand_defconfig +++ b/configs/ls1043ardb_nand_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043ardb_sdcard_SECURE_BOOT_defconfig b/configs/ls1043ardb_sdcard_SECURE_BOOT_defconfig index efcf1698a3..2b5606a404 100644 --- a/configs/ls1043ardb_sdcard_SECURE_BOOT_defconfig +++ b/configs/ls1043ardb_sdcard_SECURE_BOOT_defconfig @@ -11,6 +11,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1043ardb_sdcard_defconfig b/configs/ls1043ardb_sdcard_defconfig index 81b01318b2..bf786edb32 100644 --- a/configs/ls1043ardb_sdcard_defconfig +++ b/configs/ls1043ardb_sdcard_defconfig @@ -11,6 +11,7 @@ CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046aqds_nand_defconfig b/configs/ls1046aqds_nand_defconfig index 5fbb573ccc..9057622ff9 100644 --- a/configs/ls1046aqds_nand_defconfig +++ b/configs/ls1046aqds_nand_defconfig @@ -8,6 +8,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046aqds_sdcard_ifc_defconfig b/configs/ls1046aqds_sdcard_ifc_defconfig index caa7a4db82..f789f78747 100644 --- a/configs/ls1046aqds_sdcard_ifc_defconfig +++ b/configs/ls1046aqds_sdcard_ifc_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046aqds_sdcard_qspi_defconfig b/configs/ls1046aqds_sdcard_qspi_defconfig index 88ed9b2aff..10e693316c 100644 --- a/configs/ls1046aqds_sdcard_qspi_defconfig +++ b/configs/ls1046aqds_sdcard_qspi_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046ardb_emmc_defconfig b/configs/ls1046ardb_emmc_defconfig index 4979cb3159..ed4e060c64 100644 --- a/configs/ls1046ardb_emmc_defconfig +++ b/configs/ls1046ardb_emmc_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig index 7551b9d7d6..63a2cb680a 100644 --- a/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig +++ b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig @@ -11,6 +11,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1046ardb_sdcard_defconfig b/configs/ls1046ardb_sdcard_defconfig index 8bade9df11..c961924d8f 100644 --- a/configs/ls1046ardb_sdcard_defconfig +++ b/configs/ls1046ardb_sdcard_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_AHCI=y +CONFIG_SPL_FSL_PBL=y CONFIG_SPL_TEXT_BASE=0x10000000 CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT_VERBOSE=y diff --git a/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig b/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig index 0381ae6af8..4858f666da 100644 --- a/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig +++ b/configs/lx2160aqds_tfa_SECURE_BOOT_defconfig @@ -4,6 +4,7 @@ CONFIG_TFABOOT=y CONFIG_SYS_TEXT_BASE=0x82000000 CONFIG_SYS_MALLOC_F_LEN=0x6000 CONFIG_NXP_ESBC=y +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=3 CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y diff --git a/configs/lx2160aqds_tfa_defconfig b/configs/lx2160aqds_tfa_defconfig index c2ef337965..167c517050 100644 --- a/configs/lx2160aqds_tfa_defconfig +++ b/configs/lx2160aqds_tfa_defconfig @@ -3,6 +3,7 @@ CONFIG_TARGET_LX2160AQDS=y CONFIG_TFABOOT=y CONFIG_SYS_TEXT_BASE=0x82000000 CONFIG_SYS_MALLOC_F_LEN=0x6000 +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x500000 CONFIG_NR_DRAM_BANKS=3 diff --git a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig index 20f8c3bba4..87459dd383 100644 --- a/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig +++ b/configs/lx2160ardb_tfa_SECURE_BOOT_defconfig @@ -5,6 +5,7 @@ CONFIG_SYS_TEXT_BASE=0x82000000 CONFIG_SYS_MALLOC_F_LEN=0x6000 CONFIG_NXP_ESBC=y CONFIG_EMC2305=y +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_ENV_SIZE=0x2000 CONFIG_NR_DRAM_BANKS=3 CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y diff --git a/configs/lx2160ardb_tfa_defconfig b/configs/lx2160ardb_tfa_defconfig index a0a4296519..f6cf1aca8e 100644 --- a/configs/lx2160ardb_tfa_defconfig +++ b/configs/lx2160ardb_tfa_defconfig @@ -4,6 +4,7 @@ CONFIG_TFABOOT=y CONFIG_SYS_TEXT_BASE=0x82000000 CONFIG_SYS_MALLOC_F_LEN=0x6000 CONFIG_EMC2305=y +CONFIG_FSPI_AHB_EN_4BYTE=y CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x500000 CONFIG_NR_DRAM_BANKS=3 diff --git a/configs/omap35_logic_defconfig b/configs/omap35_logic_defconfig index 511c8ef25b..c7b67f0ffe 100644 --- a/configs/omap35_logic_defconfig +++ b/configs/omap35_logic_defconfig @@ -45,6 +45,7 @@ CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-35xx-devkit" CONFIG_ENV_IS_IN_NAND=y CONFIG_SPL_DM=y CONFIG_SPL_OF_TRANSLATE=y +# CONFIG_SPL_DM_GPIO is not set CONFIG_DM_I2C=y CONFIG_DM_MMC=y CONFIG_MMC_OMAP_HS=y diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig index b88a4c57fe..a37ec4d0d6 100644 --- a/configs/qemu-x86_64_defconfig +++ b/configs/qemu-x86_64_defconfig @@ -13,6 +13,7 @@ CONFIG_SMP=y CONFIG_GENERATE_PIRQ_TABLE=y CONFIG_GENERATE_MP_TABLE=y CONFIG_GENERATE_ACPI_TABLE=y +CONFIG_X86_OFFSET_U_BOOT=0xfff00000 CONFIG_SPL_TEXT_BASE=0xfffd0000 CONFIG_DISTRO_DEFAULTS=y CONFIG_BUILD_ROM=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index cc536ff0ba..b06ffcec3a 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -83,6 +83,8 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y +CONFIG_AXI=y +CONFIG_AXI_SANDBOX=y CONFIG_CLK=y CONFIG_CPU=y CONFIG_DM_DEMO=y @@ -112,6 +114,7 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y +CONFIG_IRQ=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_I2C_EEPROM=y @@ -203,3 +206,4 @@ CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_P2SB=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 64245f7cdc..858ad04b10 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -132,6 +132,8 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y +CONFIG_IRQ=y +CONFIG_P2SB=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_I2C_EEPROM=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index bb31b00904..2a9161c53b 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -67,6 +67,8 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y +CONFIG_AXI=y +CONFIG_AXI_SANDBOX=y CONFIG_CLK=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_SANDBOX_CLK_CCF=y @@ -98,6 +100,7 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y +CONFIG_IRQ=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_I2C_EEPROM=y @@ -117,6 +120,7 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_SANDBOX=y +CONFIG_P2SB=y CONFIG_PHY=y CONFIG_PHY_SANDBOX=y CONFIG_PINCTRL=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 61a8ffdef8..138bb9896f 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -88,6 +88,8 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y +CONFIG_AXI=y +CONFIG_AXI_SANDBOX=y CONFIG_CLK=y CONFIG_CPU=y CONFIG_DM_DEMO=y @@ -118,6 +120,7 @@ CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_LPC=y CONFIG_CROS_EC_SANDBOX=y CONFIG_CROS_EC_SPI=y +CONFIG_IRQ=y CONFIG_PWRSEQ=y CONFIG_SPL_PWRSEQ=y CONFIG_MMC_SANDBOX=y @@ -202,3 +205,4 @@ CONFIG_ERRNO_STR=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_P2SB=y diff --git a/configs/suvd3_defconfig b/configs/suvd3_defconfig index a3cdc8ba1b..f3d1f2fa27 100644 --- a/configs/suvd3_defconfig +++ b/configs/suvd3_defconfig @@ -138,6 +138,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_EXTRA_OPTIONS="SUVD3" @@ -166,6 +167,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index e36c9debf6..c698be67ea 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -13,6 +13,8 @@ CONFIG_DEFAULT_DEVICE_TREE="sandbox" CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_IP_DEFRAG=y # CONFIG_UDP_FUNCTION_FASTBOOT is not set +CONFIG_AXI=y +CONFIG_AXI_SANDBOX=y CONFIG_SANDBOX_GPIO=y CONFIG_PCI=y CONFIG_DM_PCI=y diff --git a/configs/tuge1_defconfig b/configs/tuge1_defconfig index df28752615..e6268f7337 100644 --- a/configs/tuge1_defconfig +++ b/configs/tuge1_defconfig @@ -118,6 +118,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -145,6 +146,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/configs/tuxx1_defconfig b/configs/tuxx1_defconfig index 75cd1416eb..ca7c0dec33 100644 --- a/configs/tuxx1_defconfig +++ b/configs/tuxx1_defconfig @@ -140,6 +140,7 @@ CONFIG_ACR_APARK_MASTER=y CONFIG_ACR_PARKM_USB_I2C1_BOOT=y CONFIG_LCRR_EADC_1=y CONFIG_LCRR_CLKDIV_2=y +# CONFIG_SYS_MALLOC_F is not set CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_MISC_INIT_R=y @@ -167,6 +168,7 @@ CONFIG_CMD_UBI=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_ENV_ADDR=0xF00C0000 CONFIG_ENV_ADDR_REDUND=0xF00E0000 +CONFIG_DM=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 # CONFIG_MMC is not set diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst new file mode 100644 index 0000000000..515fd06d76 --- /dev/null +++ b/doc/board/google/chromebook_coral.rst @@ -0,0 +1,241 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. sectionauthor:: Simon Glass <sjg@chromium.org> + +Chromebook Coral +================ + +Coral is a Chromebook (or really about 20 different Chromebooks) which use the +Intel Apollo Lake platform (APL). The 'reef' Chromebooks use the same APL SoC so +should also work. Some later ones based on Glacier Lake (GLK) need various +changes in GPIOs, etc. but are very similar. + +It is hoped that this port can enable ports to embedded APL boards which are +starting to appear. + +Note that booting U-Boot on APL is already supported by coreboot and +Slim Bootloader. This documentation refers to a 'bare metal' port. + + +Boot flow - TPL +--------------- + +Apollo Lake boots via an IFWI (Integrated Firmware Image). TPL is placed in +this, in the IBBL entry. + +On boot, an on-chip microcontroller called the CSE (Converged Security Engine) +sets up some SDRAM at ffff8000 and loads the TPL image to that address. The +SRAM extends up to the top of 32-bit address space, but the last 2KB is the +start16 region, so the TPL image must be 30KB at most, and CONFIG_TPL_TEXT_BASE +must be ffff8000. Actually the start16 region is small and it could probably +move from f800 to fe00, providing another 1.5KB, but TPL is only about 19KB so +there is no need to change it at present. The size limit is enforced by +CONFIG_TPL_SIZE_LIMIT to avoid producing images that won't boot. + +TPL (running from start.S) first sets up CAR (Cache-as-RAM) which provides +larger area of RAM for use while booting. CAR is mapped at CONFIG_SYS_CAR_ADDR +(fef00000) and is 768KB in size. It then sets up the stack in the botttom 64KB +of this space (i.e. below fef10000). This means that the stack and early +malloc() region in TPL can be 64KB at most. + +TPL operates without CONFIG_TPL_PCI enabled so PCI config access must use the +x86-specific functions pci_x86_write_config(), etc. SPL creates a simple-bus +device so that PCI devices are bound by driver model. Then arch_cpu_init_tpl() +is called to early init on various devices. This includes placing PCI devices +at hard-coded addresses in the memory map. PCI auto-config is not used. + +Most of the 16KB ROM is mapped into the very top of memory, except for the +Intel descriptor (first 4KB) and the space for SRAM as above. + +TPL does not set up a bloblist since at present it does not have anything to +pass to SPL. + +Once TPL is done it loads SPL from ROM using either the memory-mapped SPI or by +using the Intel fast SPI driver. SPL is loaded into CAR, at the address given +by CONFIG_SPL_TEXT_BASE, which is normally fef10000. + +Note that booting using the SPI driver results in an TPL image that is about +26KB in size instead of 19KB. Also boot speed is worse by about 340ms. If you +really want to use the driver, enable CONFIG_APL_SPI_FLASH_BOOT and set +BOOT_FROM_FAST_SPI_FLASH to true[2]. + + +Boot flow - SPL +--------------- + +SPL (running from start_from_tpl.S) continues to use the same stack as TPL. +It calls arch_cpu_init_spl() to set up a few devices, then init_dram() loads +the FSP-M binary into CAR and runs to, to set up SDRAM. The address of the +output 'HOB' list (Hand-off-block) is stored into gd->arch.hob_list for parsing. +There is a 2GB chunk of SDRAM starting at 0 and the rest is at 4GB. + +PCI auto-config is not used in SPL either, but CONFIG_SPL_PCI is defined, so +proper PCI access is available and normal dm_pci_read_config() calls can be +used. However PCI auto-config is not used so the same static memory mapping set +up by TPL is still active. + +SPL on x86 always runs with CONFIG_SPL_SEPARATE_BSS=y and BSS is at 120000 +(see u-boot-spl.lds). This works because SPL doesn't access BSS until after +board_init_r(), as per the rules, and DRAM is available then. + +SPL sets up a bloblist and passes the SPL hand-off information to U-Boot proper. +This includes a pointer to the HOB list as well as DRAM information. See +struct arch_spl_handoff. The bloblist address is set by CONFIG_BLOBLIST_ADDR, +normally 100000. + +SPL uses SPI flash to update the MRC caches in ROM. This speeds up subsequent +boots. Be warned that SPL can take 30 seconds without this cache! This is a +known issue with Intel SoCs with modern DRAM and apparently cannot be improved. +The MRC caches are used to work around this. + +Once SPL is finished it loads U-Boot into SDRAM at CONFIG_SYS_TEXT_BASE, which +is normally 1110000. Note that CAR is still active. + + +Boot flow - U-Boot pre-relocation +--------------------------------- + +U-Boot (running from start_from_spl.S) starts running in RAM and uses the same +stack as SPL. It does various init activities before relocation. Notably +arch_cpu_init_dm() sets up the pin muxing for the chip using a very large table +in the device tree. + +PCI auto-config is not used before relocation, but CONFIG_PCI of course is +defined, so proper PCI access is available. The same static memory mapping set +up by TPL is still active until relocation. + +As per usual, U-Boot allocates memory at the top of available RAM (a bit below +2GB in this case) and copies things there ready to relocate itself. Notably +reserve_arch() does not reserve space for the HOB list returned by FSP-M since +this is already located in RAM. + +U-Boot then shuts down CAR and jumps to its relocated version. + + +Boot flow - U-Boot post-relocation +--------------------------------- + +U-Boot starts up normally, running near the top of RAM. After driver model is +running, arch_fsp_init_r() is called which loads and runs the FSP-S binary. +This updates the HOB list to include graphics information, used by the fsp_video +driver. + +PCI autoconfig is done and a few devices are probed to complete init. Most +others are started only when they are used. + +Note that FSP-S is supposed to run after CAR has been shut down, which happens +immediately before U-Boot starts up in its relocated position. Therefore we +cannot run FSP-S before relocation. On the other hand we must run it before +PCI auto-config is done, since FSP-S may show or hide devices. The first device +that probes PCI after relocation is the serial port, in initr_serial(), so FSP-S +must run before that. A corollary is that loading FSP-S must be done without +using the SPI driver, to avoid probing PCI and causing an autoconfig, so +memory-mapped reading is always used for FSP-S. + +It would be possible to tear down CAR in SPL instead of U-Boot. The SPL handoff +information could make sure it does not include any pointers into CAR (in fact +it doesn't). But tearing down CAR in U-Boot allows the initial state used by TPL +and SPL to be read by U-Boot, which seems useful. It also matches how older +platforms start up (those that don't use SPL). + + +Performance +----------- + +Bootstage is used through all phases of U-Boot to keep accurate timimgs for +boot. Use 'bootstage report' in U-Boot to see the report, e.g.: + +Timer summary in microseconds (16 records): + Mark Elapsed Stage + 0 0 reset + 155,325 155,325 TPL + 204,014 48,689 end TPL + 204,385 371 SPL + 738,633 534,248 end SPL + 739,161 528 board_init_f + 842,764 103,603 board_init_r + 1,166,233 323,469 main_loop + 1,166,283 50 id=175 + +Accumulated time: + 62 fast_spi + 202 dm_r + 7,779 dm_spl + 15,555 dm_f + 208,357 fsp-m + 239,847 fsp-s + 292,143 mmap_spi + +CPU performance is about 3500 DMIPS: + +=> dhry +1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS + + +Partial memory map +------------------ + +ffffffff Top of ROM (and last byte of 32-bit address space) +ffff8000 TPL loaded here (from IFWI) +ff000000 Bottom of ROM +fefc000 Top of CAR region +fef96000 Stack for FSP-M +fef40000 59000 FSP-M +fef11000 SPL loaded here +fef10000 CONFIG_BLOBLIST_ADDR +fef10000 Stack top in TPL, SPL and U-Boot before relocation +fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR +fef00000 Base of CAR region + + f0000 CONFIG_ROM_TABLE_ADDR + 120000 BSS (defined in u-boot-spl.lds) + 200000 FSP-S (which is run after U-Boot is relocated) + 1110000 CONFIG_SYS_TEXT_BASE + + +Supported peripherals +--------------------- + +- UART +- SPI flash +- Video +- MMC (dev 0) and micro-SD (dev 1) +- Chrome OS EC +- Keyboard +- USB + + +To do +----- + +- Finish peripherals + - left-side USB + - USB-C + - Cr50 (security chip: a basic driver is running but not included here) + - I2C (driver exists but not enabled in device tree) + - Sound (Intel I2S support exists, but need da7219 driver) + - RTC (driver exists but not enabled in device tree) + - Various minor features supported by LPC, etc. +- Booting Chrome OS, e.g. with verified boot +- Integrate with Chrome OS vboot +- Improvements to booting from coreboot (i.e. as a coreboot target) +- Use FSP-T binary instead of our own CAR implementation +- Use the official FSP package instead of the coreboot one +- Enable all CPU cores +- Suspend / resume +- ACPI + + +Credits +------- + +This is a spare-time project conducted slowly over a long period of time. + +Much of the code for this port came from Coreboot, an open-source firmware +project similar to U-Boot's SPL in terms of features. + +Also see [2] for information about the boot flow used by coreboot. It is +similar, but has an extra postcar stage. U-Boot doesn't need this since it +supports relocating itself in memory. + + +[2] Intel PDF https://www.coreboot.org/images/2/23/Apollolake_SoC.pdf diff --git a/doc/board/google/index.rst b/doc/board/google/index.rst index 7f557feb44..061c797718 100644 --- a/doc/board/google/index.rst +++ b/doc/board/google/index.rst @@ -6,5 +6,6 @@ Google .. toctree:: :maxdepth: 2 + chromebook_coral chromebook_link chromebook_samus diff --git a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt new file mode 100644 index 0000000000..e27a40b437 --- /dev/null +++ b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt @@ -0,0 +1,55 @@ +Intel Apollo Lake GPIO controller + +The Apollo Lake (APL) GPIO controller is used to control GPIO functions of +the pins. + +Required properties: +- compatible: "intel,apl-gpio" +- #gpio-cells: Should be 2. The syntax of the gpio specifier used by client + nodes should be the following with values derived from the SoC user manual. + <[phandle of the gpio controller node] + [pin number within the gpio controller] + [flags]> + + Values for gpio specifier: + - Pin number: is a GPIO pin number between 0 and 244 + - Flags: GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW + +- gpio-controller: Specifies that the node is a gpio controller. + +Example: + +... +{ + p2sb: p2sb@d,0 { + reg = <0x02006810 0 0 0 0>; + compatible = "intel,apl-p2sb"; + early-regs = <IOMAP_P2SB_BAR 0x100000>; + + north { + compatible = "intel,apl-pinctrl"; + intel,p2sb-port-id = <PID_GPIO_N>; + gpio_n: gpio-n { + compatible = "intel,gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + }; + + i2c_2: i2c2@16,2 { + compatible = "intel,apl-i2c", "snps,designware-i2c-pci"; + reg = <0x0200b210 0 0 0 0>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <400000>; + tpm@50 { + reg = <0x50>; + compatible = "google,cr50"; + u-boot,i2c-offset-len = <0>; + ready-gpio = <&gpio_n GPIO_28 GPIO_ACTIVE_LOW>; + }; + }; + +}; +... diff --git a/doc/device-tree-bindings/pci/x86-pci.txt b/doc/device-tree-bindings/pci/x86-pci.txt new file mode 100644 index 0000000000..3aa5bd9a46 --- /dev/null +++ b/doc/device-tree-bindings/pci/x86-pci.txt @@ -0,0 +1,24 @@ +x86 PCI DT details: +=================== + +Some options are available to affect how PCI operates on x86. + +Optional properties: +- u-boot,skip-auto-config-until-reloc : Don't set up PCI configuration until + after U-Boot has relocated. Normally if PCI is used before relocation, + this happens before relocation also. Some platforms set up static + configuration in TPL/SPL to reduce code size and boot time, since these + phases only know about a small subset of PCI devices. + +Example: + +pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000 + 0x42000000 0x0 0xb0000000 0xb0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xefff>; + u-boot,skip-auto-config-until-reloc; +}; diff --git a/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt b/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt new file mode 100644 index 0000000000..cd7f8a0ca3 --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt @@ -0,0 +1,39 @@ +* Intel Apollo Lake pin controller + +The Apollo Lake (APL) pin controller is used to select the function of a pin +and to configure it. + +Required properties: +- compatible: "intel,apl-pinctrl" +- intel,p2sb-port-id: Port ID number within the parent P2SB +- reg: PCI address of the controller + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices. + +Optional subnodes: + +GPIO nodes may be added as children of the pinctrl nodes. See intel,apl-gpio +for the binding. + + +Example: + +... +{ + p2sb: p2sb@d,0 { + reg = <0x02006810 0 0 0 0>; + compatible = "intel,apl-p2sb"; + early-regs = <IOMAP_P2SB_BAR 0x100000>; + + n { + compatible = "intel,apl-pinctrl"; + intel,p2sb-port-id = <PID_GPIO_N>; + gpio_n: gpio-n { + compatible = "intel,apl-gpio"; + #gpio-cells = <2>; + }; + }; + }; +}; +... diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst index 557957d2a1..034a68bb4e 100644 --- a/doc/driver-model/of-plat.rst +++ b/doc/driver-model/of-plat.rst @@ -279,6 +279,12 @@ For example: }; +Note that struct mmc_platdata is defined in the C file, not in a header. This +is to avoid needing to include dt-structs.h in a header file. The idea is to +keep the use of each of-platdata struct to the smallest possible code area. +There is just one driver C file for each struct, that can convert from the +of-platdata struct to the standard one used by the driver. + In the case where SPL_OF_PLATDATA is enabled, platdata_auto_alloc_size is still used to allocate space for the platform data. This is different from the normal behaviour and is triggered by the use of of-platdata (strictly diff --git a/drivers/Makefile b/drivers/Makefile index e977f19af6..cb8c215e76 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_$(SPL_TPL_)VIRTIO) += virtio/ obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/ obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/ obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/ +obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += power/acpi_pmc/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD diff --git a/drivers/core/util.c b/drivers/core/util.c index 7dc1a2af02..69f83755f0 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -4,7 +4,9 @@ */ #include <common.h> +#include <dm/device.h> #include <dm/ofnode.h> +#include <dm/read.h> #include <dm/util.h> #include <linux/libfdt.h> #include <vsprintf.h> @@ -58,3 +60,21 @@ bool dm_ofnode_pre_reloc(ofnode node) #endif } #endif + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) +int pci_get_devfn(struct udevice *dev) +{ + struct fdt_pci_addr addr; + int ret; + + /* Extract the devfn from fdt_pci_addr */ + ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, + "reg", &addr); + if (ret) { + if (ret != -ENOENT) + return -EINVAL; + } + + return addr.phys_hi & 0xff00; +} +#endif diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index a9b085db8c..952b296dd8 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -370,6 +370,8 @@ step2: debug("Setting DEBUG_3[21] to 0x%08x\n", in_be32(&ddr->debug[2])); #endif /* part 1 of the workaound */ + /* Always start in self-refresh, clear after MEM_EN */ + setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); /* * 500 painful micro-seconds must elapse between @@ -382,8 +384,6 @@ step2: #ifdef CONFIG_DEEP_SLEEP if (is_warm_boot()) { - /* enter self-refresh */ - setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); /* do board specific memory setup */ board_mem_sleep_setup(); temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI); @@ -395,6 +395,10 @@ step2: out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); asm volatile("sync;isync"); + /* Exit self-refresh after DDR conf as some ddr memories can fail. */ + clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); + asm volatile("sync;isync"); + total_gb_size_per_controller = 0; for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (!(regs->cs[i].config & 0x80000000)) @@ -544,9 +548,4 @@ step2: clrbits_be32(&ddr->sdram_cfg, 0x2); } #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ -#ifdef CONFIG_DEEP_SLEEP - if (is_warm_boot()) - /* exit self-refresh */ - clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); -#endif } diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c1ad5d64a3..1de6f5225e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -14,6 +14,28 @@ config DM_GPIO particular GPIOs that they provide. The uclass interface is defined in include/asm-generic/gpio.h. +config SPL_DM_GPIO + bool "Enable Driver Model for GPIO drivers in SPL" + depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT + default y + help + Enable driver model for GPIO access in SPL. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. + +config TPL_DM_GPIO + bool "Enable Driver Model for GPIO drivers in TPL" + depends on DM_GPIO && TPL_DM && TPL_GPIO_SUPPORT + default y + help + Enable driver model for GPIO access in TPL. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. + config GPIO_HOG bool "Enable GPIO hog support" depends on DM_GPIO @@ -82,6 +104,15 @@ config INTEL_BROADWELL_GPIO driver from the common Intel ICH6 driver. It supports a total of 95 GPIOs which can be configured from the device tree. +config INTEL_GPIO + bool "Intel generic GPIO driver" + depends on DM_GPIO + help + Say yes here to select Intel generic GPIO driver. This controller + supports recent chips (e.g. Apollo Lake). It permits basic GPIO + control including setting pins to input/output. It makes use of its + parent pinctrl driver to actually effect changes. + config INTEL_ICH6_GPIO bool "Intel ICH6 compatible legacy GPIO driver" depends on DM_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ccc49e2eb0..449046b64c 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -7,14 +7,17 @@ ifndef CONFIG_SPL_BUILD obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o obj-$(CONFIG_AXP_GPIO) += axp_gpio.o endif -obj-$(CONFIG_DM_GPIO) += gpio-uclass.o +obj-$(CONFIG_$(SPL_TPL_)DM_GPIO) += gpio-uclass.o obj-$(CONFIG_$(SPL_)DM_PCA953X) += pca953x_gpio.o +ifdef CONFIG_$(SPL_TPL_)GPIO obj-$(CONFIG_DM_74X164) += 74x164_gpio.o +endif obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o +obj-$(CONFIG_INTEL_GPIO) += intel_gpio.o obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o obj-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index dbfed72c61..5ea3e77b2d 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -210,7 +210,7 @@ int at91_pio3_set_d_periph(unsigned port, unsigned pin, int use_pullup) return 0; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) static bool at91_get_port_output(struct at91_port *at91_port, int offset) { u32 mask, val; @@ -457,7 +457,7 @@ int at91_get_pio_value(unsigned port, unsigned pin) return 0; } -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) /* Common GPIO API */ int gpio_request(unsigned gpio, const char *label) @@ -499,7 +499,7 @@ int gpio_set_value(unsigned gpio, int value) } #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct at91_port_priv { struct at91_port *regs; diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 95a189a50f..8e6f32de1f 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -168,7 +168,7 @@ int atmel_pio4_get_pio_input(u32 port, u32 pin) return (readl(&port_base->pdsr) & mask) ? 1 : 0; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct atmel_pioctrl_data { u32 nbanks; diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c index 0a50c68d72..bd5a366aef 100644 --- a/drivers/gpio/da8xx_gpio.c +++ b/drivers/gpio/da8xx_gpio.c @@ -15,7 +15,7 @@ #include "da8xx_gpio.h" -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #include <asm/arch/hardware.h> #include <asm/arch/davinci_misc.h> @@ -377,7 +377,8 @@ static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, _gpio_set_value(bank, gpio, value); return 0; } -#ifndef CONFIG_DM_GPIO + +#if !CONFIG_IS_ENABLED(DM_GPIO) void gpio_info(void) { @@ -428,7 +429,7 @@ int gpio_set_value(unsigned int gpio, int value) return _gpio_set_value(bank, gpio, value); } -#else /* CONFIG_DM_GPIO */ +#else /* DM_GPIO */ static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset) { diff --git a/drivers/gpio/da8xx_gpio.h b/drivers/gpio/da8xx_gpio.h index 1de9ec7f6f..849e8d2dcf 100644 --- a/drivers/gpio/da8xx_gpio.h +++ b/drivers/gpio/da8xx_gpio.h @@ -28,7 +28,7 @@ struct davinci_gpio_bank { #define MAX_NUM_GPIOS 144 #define GPIO_BIT(gp) ((gp) & 0x1F) -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* Information about a GPIO bank */ struct davinci_gpio_platdata { diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c new file mode 100644 index 0000000000..4bf1c9ddc4 --- /dev/null +++ b/drivers/gpio/intel_gpio.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <p2sb.h> +#include <pch.h> +#include <pci.h> +#include <syscon.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/intel_pinctrl.h> +#include <asm/intel_pinctrl_defs.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/arch/gpio.h> +#include <dt-bindings/gpio/x86-gpio.h> + +static int intel_gpio_direction_input(struct udevice *dev, uint offset) +{ + struct udevice *pinctrl = dev_get_parent(dev); + uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset); + + pcr_clrsetbits32(pinctrl, config_offset, + PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE | + PAD_CFG0_RX_DISABLE, + PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE); + + return 0; +} + +static int intel_gpio_direction_output(struct udevice *dev, uint offset, + int value) +{ + struct udevice *pinctrl = dev_get_parent(dev); + uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset); + + pcr_clrsetbits32(dev, config_offset, + PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE | + PAD_CFG0_TX_DISABLE, + PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE | + (value ? PAD_CFG0_TX_STATE : 0)); + + return 0; +} + +static int intel_gpio_get_value(struct udevice *dev, uint offset) +{ + struct udevice *pinctrl = dev_get_parent(dev); + uint mode, rx_tx; + u32 reg; + + reg = intel_pinctrl_get_config_reg(pinctrl, offset); + mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT; + if (!mode) { + rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE); + if (rx_tx == PAD_CFG0_TX_DISABLE) + return mode & PAD_CFG0_RX_STATE_BIT ? 1 : 0; + else if (rx_tx == PAD_CFG0_RX_DISABLE) + return mode & PAD_CFG0_TX_STATE_BIT ? 1 : 0; + } + + return 0; +} + +static int intel_gpio_set_value(struct udevice *dev, unsigned offset, int value) +{ + struct udevice *pinctrl = dev_get_parent(dev); + uint config_offset = intel_pinctrl_get_config_reg_addr(pinctrl, offset); + + pcr_clrsetbits32(dev, config_offset, PAD_CFG0_TX_STATE, + value ? PAD_CFG0_TX_STATE : 0); + + return 0; +} + +static int intel_gpio_get_function(struct udevice *dev, uint offset) +{ + struct udevice *pinctrl = dev_get_parent(dev); + uint mode, rx_tx; + u32 reg; + + reg = intel_pinctrl_get_config_reg(pinctrl, offset); + mode = (reg & PAD_CFG0_MODE_MASK) >> PAD_CFG0_MODE_SHIFT; + if (!mode) { + rx_tx = reg & (PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE); + if (rx_tx == PAD_CFG0_TX_DISABLE) + return GPIOF_INPUT; + else if (rx_tx == PAD_CFG0_RX_DISABLE) + return GPIOF_OUTPUT; + } + + return GPIOF_FUNC; +} + +static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args) +{ + struct udevice *pinctrl, *dev; + int gpio, ret; + + /* + * GPIO numbers are global in the device tree so it doesn't matter + * which one is used + */ + gpio = args->args[0]; + ret = intel_pinctrl_get_pad(gpio, &pinctrl, &desc->offset); + if (ret) + return log_msg_ret("bad", ret); + device_find_first_child(pinctrl, &dev); + if (!dev) + return log_msg_ret("no child", -ENOENT); + desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; + desc->dev = dev; + + return 0; +} + +static int intel_gpio_probe(struct udevice *dev) +{ + return 0; +} + +static int intel_gpio_ofdata_to_platdata(struct udevice *dev) +{ + struct gpio_dev_priv *upriv = dev_get_uclass_priv(dev); + struct intel_pinctrl_priv *pinctrl_priv = dev_get_priv(dev->parent); + const struct pad_community *comm = pinctrl_priv->comm; + + upriv->gpio_count = comm->last_pad - comm->first_pad + 1; + upriv->bank_name = dev->name; + + return 0; +} + +static const struct dm_gpio_ops gpio_intel_ops = { + .direction_input = intel_gpio_direction_input, + .direction_output = intel_gpio_direction_output, + .get_value = intel_gpio_get_value, + .set_value = intel_gpio_set_value, + .get_function = intel_gpio_get_function, + .xlate = intel_gpio_xlate, +}; + +static const struct udevice_id intel_intel_gpio_ids[] = { + { .compatible = "intel,gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_intel) = { + .name = "gpio_intel", + .id = UCLASS_GPIO, + .of_match = intel_intel_gpio_ids, + .ops = &gpio_intel_ops, + .ofdata_to_platdata = intel_gpio_ofdata_to_platdata, + .probe = intel_gpio_probe, +}; diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 64ab7a303f..6592d141d3 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -30,7 +30,7 @@ struct mxc_bank_info { struct gpio_regs *regs; }; -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define GPIO_TO_PORT(n) ((n) / 32) /* GPIO port description */ @@ -161,7 +161,7 @@ int gpio_direction_output(unsigned gpio, int value) } #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <fdtdec.h> static int mxc_gpio_is_output(struct gpio_regs *regs, int offset) { diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c index 5795155e3e..77778e9ce5 100644 --- a/drivers/gpio/mxs_gpio.c +++ b/drivers/gpio/mxs_gpio.c @@ -128,7 +128,7 @@ int name_to_gpio(const char *name) return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT); } -#else /* CONFIG_DM_GPIO */ +#else /* DM_GPIO */ #include <dm.h> #include <asm/gpio.h> #include <dt-structs.h> @@ -312,4 +312,4 @@ U_BOOT_DRIVER(gpio_mxs) = { .ofdata_to_platdata = mxs_ofdata_to_platdata, #endif }; -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */ diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index 0031415d03..4249850f4b 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; #define OMAP_GPIO_DIR_OUT 0 #define OMAP_GPIO_DIR_IN 1 -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #define GPIO_PER_BANK 32 @@ -121,7 +121,7 @@ static int _get_gpio_value(const struct gpio_bank *bank, int gpio) return (__raw_readl(reg) & (1 << gpio)) != 0; } -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static inline const struct gpio_bank *get_gpio_bank(int gpio) { @@ -377,4 +377,4 @@ U_BOOT_DRIVER(gpio_omap) = { #endif }; -#endif /* CONFIG_DM_GPIO */ +#endif /* !DM_GPIO */ diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 719efc2cef..9c3a4428e1 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -28,7 +28,7 @@ struct sunxi_gpio_platdata { int gpio_count; }; -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static int sunxi_gpio_output(u32 pin, u32 val) { u32 dat; @@ -116,7 +116,7 @@ int sunxi_name_to_gpio(const char *name) return -1; return group * 32 + pin; } -#endif +#endif /* DM_GPIO */ int sunxi_name_to_gpio_bank(const char *name) { @@ -132,7 +132,7 @@ int sunxi_name_to_gpio_bank(const char *name) return -1; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* TODO(sjg@chromium.org): Remove this function and use device tree */ int sunxi_name_to_gpio(const char *name) { @@ -373,4 +373,4 @@ U_BOOT_DRIVER(gpio_sunxi) = { .bind = gpio_sunxi_bind, .probe = gpio_sunxi_probe, }; -#endif +#endif /* DM_GPIO */ diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index c2f75d8755..f5a471f887 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o +ifdef CONFIG_DM_PCI +obj-$(CONFIG_SYS_I2C_DW) += designware_i2c_pci.o +endif obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 6daa90e744..b8cdd1c661 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -13,34 +13,6 @@ #include <asm/io.h> #include "designware_i2c.h" -struct dw_scl_sda_cfg { - u32 ss_hcnt; - u32 fs_hcnt; - u32 ss_lcnt; - u32 fs_lcnt; - u32 sda_hold; -}; - -#ifdef CONFIG_X86 -/* BayTrail HCNT/LCNT/SDA hold time */ -static struct dw_scl_sda_cfg byt_config = { - .ss_hcnt = 0x200, - .fs_hcnt = 0x55, - .ss_lcnt = 0x200, - .fs_lcnt = 0x99, - .sda_hold = 0x6, -}; -#endif - -struct dw_i2c { - struct i2c_regs *regs; - struct dw_scl_sda_cfg *scl_sda_cfg; - struct reset_ctl_bulk resets; -#if CONFIG_IS_ENABLED(CLK) - struct clk clk; -#endif -}; - #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable) { @@ -90,7 +62,9 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, unsigned int ena; int i2c_spd; - if (speed >= I2C_MAX_SPEED) + /* Allow max speed if there is no config, or the config allows it */ + if (speed >= I2C_MAX_SPEED && + (!scl_sda_cfg || scl_sda_cfg->has_max_speed)) i2c_spd = IC_SPEED_MODE_MAX; else if (speed >= I2C_FAST_SPEED) i2c_spd = IC_SPEED_MODE_FAST; @@ -106,7 +80,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK)); switch (i2c_spd) { -#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */ case IC_SPEED_MODE_MAX: cntl |= IC_CON_SPD_SS; if (scl_sda_cfg) { @@ -119,7 +92,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, writel(hcnt, &i2c_base->ic_hs_scl_hcnt); writel(lcnt, &i2c_base->ic_hs_scl_lcnt); break; -#endif case IC_SPEED_MODE_STANDARD: cntl |= IC_CON_SPD_SS; @@ -565,24 +537,19 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, return ret; } -static int designware_i2c_probe(struct udevice *bus) +static int designware_i2c_ofdata_to_platdata(struct udevice *bus) { struct dw_i2c *priv = dev_get_priv(bus); - int ret; - if (device_is_on_pci_bus(bus)) { -#ifdef CONFIG_DM_PCI - /* Save base address from PCI BAR */ - priv->regs = (struct i2c_regs *) - dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); -#ifdef CONFIG_X86 - /* Use BayTrail specific timing values */ - priv->scl_sda_cfg = &byt_config; -#endif -#endif - } else { - priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus); - } + priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus); + + return 0; +} + +int designware_i2c_probe(struct udevice *bus) +{ + struct dw_i2c *priv = dev_get_priv(bus); + int ret; ret = reset_get_bulk(bus, &priv->resets); if (ret) @@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus) return __dw_i2c_init(priv->regs, 0, 0); } -static int designware_i2c_remove(struct udevice *dev) +int designware_i2c_remove(struct udevice *dev) { struct dw_i2c *priv = dev_get_priv(dev); @@ -618,30 +585,7 @@ static int designware_i2c_remove(struct udevice *dev) return reset_release_bulk(&priv->resets); } -static int designware_i2c_bind(struct udevice *dev) -{ - static int num_cards; - char name[20]; - - /* Create a unique device name for PCI type devices */ - if (device_is_on_pci_bus(dev)) { - /* - * ToDo: - * Setting req_seq in the driver is probably not recommended. - * But without a DT alias the number is not configured. And - * using this driver is impossible for PCIe I2C devices. - * This can be removed, once a better (correct) way for this - * is found and implemented. - */ - dev->req_seq = num_cards; - sprintf(name, "i2c_designware#%u", num_cards++); - device_set_name(dev, name); - } - - return 0; -} - -static const struct dm_i2c_ops designware_i2c_ops = { +const struct dm_i2c_ops designware_i2c_ops = { .xfer = designware_i2c_xfer, .probe_chip = designware_i2c_probe_chip, .set_bus_speed = designware_i2c_set_bus_speed, @@ -656,28 +600,12 @@ U_BOOT_DRIVER(i2c_designware) = { .name = "i2c_designware", .id = UCLASS_I2C, .of_match = designware_i2c_ids, - .bind = designware_i2c_bind, + .ofdata_to_platdata = designware_i2c_ofdata_to_platdata, .probe = designware_i2c_probe, .priv_auto_alloc_size = sizeof(struct dw_i2c), .remove = designware_i2c_remove, - .flags = DM_FLAG_OS_PREPARE, + .flags = DM_FLAG_OS_PREPARE, .ops = &designware_i2c_ops, }; -#ifdef CONFIG_X86 -static struct pci_device_id designware_pci_supported[] = { - /* Intel BayTrail has 7 I2C controller located on the PCI bus */ - { PCI_VDEVICE(INTEL, 0x0f41) }, - { PCI_VDEVICE(INTEL, 0x0f42) }, - { PCI_VDEVICE(INTEL, 0x0f43) }, - { PCI_VDEVICE(INTEL, 0x0f44) }, - { PCI_VDEVICE(INTEL, 0x0f45) }, - { PCI_VDEVICE(INTEL, 0x0f46) }, - { PCI_VDEVICE(INTEL, 0x0f47) }, - {}, -}; - -U_BOOT_PCI_DEVICE(i2c_designware, designware_pci_supported); -#endif - #endif /* CONFIG_DM_I2C */ diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 20ff20d9b8..48766d0806 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -7,6 +7,8 @@ #ifndef __DW_I2C_H_ #define __DW_I2C_H_ +#include <reset.h> + struct i2c_regs { u32 ic_con; /* 0x00 */ u32 ic_tar; /* 0x04 */ @@ -131,4 +133,37 @@ struct i2c_regs { #define I2C_FAST_SPEED 400000 #define I2C_STANDARD_SPEED 100000 +/** + * struct dw_scl_sda_cfg - I2C timing configuration + * + * @has_max_speed: Support maximum speed (1Mbps) + * @ss_hcnt: Standard speed high time in ns + * @fs_hcnt: Fast speed high time in ns + * @ss_lcnt: Standard speed low time in ns + * @fs_lcnt: Fast speed low time in ns + * @sda_hold: SDA hold time + */ +struct dw_scl_sda_cfg { + bool has_max_speed; + u32 ss_hcnt; + u32 fs_hcnt; + u32 ss_lcnt; + u32 fs_lcnt; + u32 sda_hold; +}; + +struct dw_i2c { + struct i2c_regs *regs; + struct dw_scl_sda_cfg *scl_sda_cfg; + struct reset_ctl_bulk resets; +#if CONFIG_IS_ENABLED(CLK) + struct clk clk; +#endif +}; + +extern const struct dm_i2c_ops designware_i2c_ops; + +int designware_i2c_probe(struct udevice *bus); +int designware_i2c_remove(struct udevice *dev); + #endif /* __DW_I2C_H_ */ diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c new file mode 100644 index 0000000000..7f0625df66 --- /dev/null +++ b/drivers/i2c/designware_i2c_pci.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * Copyright 2019 Google Inc + */ + +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <asm/lpss.h> +#include "designware_i2c.h" + +enum { + VANILLA = 0, /* standard I2C with no tweaks */ + INTEL_APL, /* Apollo Lake I2C */ +}; + +/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = { + .ss_hcnt = 0x200, + .fs_hcnt = 0x55, + .ss_lcnt = 0x200, + .fs_lcnt = 0x99, + .sda_hold = 0x6, +}; + +/* Have a weak function for now - possibly should be a new uclass */ +__weak void lpss_reset_release(void *regs); + +static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev) +{ + struct dw_i2c *priv = dev_get_priv(dev); + + if (spl_phase() < PHASE_SPL) { + u32 base; + int ret; + + ret = dev_read_u32(dev, "early-regs", &base); + if (ret) + return log_msg_ret("early-regs", ret); + + /* Set i2c base address */ + dm_pci_write_config32(dev, PCI_BASE_ADDRESS_0, base); + + /* Enable memory access and bus master */ + dm_pci_write_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + } + + if (spl_phase() < PHASE_BOARD_F) { + /* Handle early, fixed mapping into a different address space */ + priv->regs = (struct i2c_regs *)dm_pci_read_bar32(dev, 0); + } else { + priv->regs = (struct i2c_regs *) + dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + } + if (!priv->regs) + return -EINVAL; + + /* Save base address from PCI BAR */ + if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL)) + /* Use BayTrail specific timing values */ + priv->scl_sda_cfg = &byt_config; + + return 0; +} + +static int designware_i2c_pci_probe(struct udevice *dev) +{ + struct dw_i2c *priv = dev_get_priv(dev); + + if (dev_get_driver_data(dev) == INTEL_APL) { + /* Ensure controller is in D0 state */ + lpss_set_power_state(dev, STATE_D0); + + lpss_reset_release(priv->regs); + } + + return designware_i2c_probe(dev); +} + +static int designware_i2c_pci_bind(struct udevice *dev) +{ + char name[20]; + + /* + * Create a unique device name for PCI type devices + * ToDo: + * Setting req_seq in the driver is probably not recommended. + * But without a DT alias the number is not configured. And + * using this driver is impossible for PCIe I2C devices. + * This can be removed, once a better (correct) way for this + * is found and implemented. + * + * TODO(sjg@chromium.org): Perhaps if uclasses had platdata this would + * be possible. We cannot use static data in drivers since they may be + * used in SPL or before relocation. + */ + dev->req_seq = gd->arch.dw_i2c_num_cards++; + sprintf(name, "i2c_designware#%u", dev->req_seq); + device_set_name(dev, name); + + return 0; +} + +static const struct udevice_id designware_i2c_pci_ids[] = { + { .compatible = "snps,designware-i2c-pci" }, + { .compatible = "intel,apl-i2c", .data = INTEL_APL }, + { } +}; + +U_BOOT_DRIVER(i2c_designware_pci) = { + .name = "i2c_designware_pci", + .id = UCLASS_I2C, + .of_match = designware_i2c_pci_ids, + .bind = designware_i2c_pci_bind, + .ofdata_to_platdata = designware_i2c_pci_ofdata_to_platdata, + .probe = designware_i2c_pci_probe, + .priv_auto_alloc_size = sizeof(struct dw_i2c), + .remove = designware_i2c_remove, + .flags = DM_FLAG_OS_PREPARE, + .ops = &designware_i2c_ops, +}; + +static struct pci_device_id designware_pci_supported[] = { + /* Intel BayTrail has 7 I2C controller located on the PCI bus */ + { PCI_VDEVICE(INTEL, 0x0f41) }, + { PCI_VDEVICE(INTEL, 0x0f42) }, + { PCI_VDEVICE(INTEL, 0x0f43) }, + { PCI_VDEVICE(INTEL, 0x0f44) }, + { PCI_VDEVICE(INTEL, 0x0f45) }, + { PCI_VDEVICE(INTEL, 0x0f46) }, + { PCI_VDEVICE(INTEL, 0x0f47) }, + { PCI_VDEVICE(INTEL, 0x5aac), .driver_data = INTEL_APL }, + { PCI_VDEVICE(INTEL, 0x5aae), .driver_data = INTEL_APL }, + { PCI_VDEVICE(INTEL, 0x5ab0), .driver_data = INTEL_APL }, + { PCI_VDEVICE(INTEL, 0x5ab2), .driver_data = INTEL_APL }, + { PCI_VDEVICE(INTEL, 0x5ab4), .driver_data = INTEL_APL }, + { PCI_VDEVICE(INTEL, 0x5ab6), .driver_data = INTEL_APL }, + {}, +}; + +U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported); diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index e47abf1833..fe77e64619 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -11,7 +11,7 @@ #include <dm/device-internal.h> #include <dm/lists.h> #include <dm/pinctrl.h> -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif @@ -52,16 +52,19 @@ void i2c_dump_msgs(struct i2c_msg *msg, int nmsgs) static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset, uint8_t offset_buf[], struct i2c_msg *msg) { - int offset_len; + int offset_len = chip->offset_len; msg->addr = chip->chip_addr; + if (chip->chip_addr_offset_mask) + msg->addr |= (offset >> (8 * offset_len)) & + chip->chip_addr_offset_mask; msg->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0; msg->len = chip->offset_len; msg->buf = offset_buf; - if (!chip->offset_len) + if (!offset_len) return -EADDRNOTAVAIL; - assert(chip->offset_len <= I2C_MAX_OFFSET_LEN); - offset_len = chip->offset_len; + assert(offset_len <= I2C_MAX_OFFSET_LEN); + while (offset_len--) *offset_buf++ = offset >> (8 * offset_len); @@ -83,7 +86,7 @@ static int i2c_read_bytewise(struct udevice *dev, uint offset, if (i2c_setup_offset(chip, offset + i, offset_buf, msg)) return -EINVAL; ptr = msg + 1; - ptr->addr = chip->chip_addr; + ptr->addr = msg->addr; ptr->flags = msg->flags | I2C_M_RD; ptr->len = 1; ptr->buf = &buffer[i]; @@ -139,7 +142,7 @@ int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len) ptr++; if (len) { - ptr->addr = chip->chip_addr; + ptr->addr = msg->addr; ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0; ptr->flags |= I2C_M_RD; ptr->len = len; @@ -323,7 +326,8 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len, struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); int ret; - if (chip->chip_addr == chip_addr) { + if (chip->chip_addr == (chip_addr & + ~chip->chip_addr_offset_mask)) { ret = device_probe(dev); debug("found, ret=%d\n", ret); if (ret) @@ -465,7 +469,23 @@ int i2c_get_chip_offset_len(struct udevice *dev) return chip->offset_len; } -#ifdef CONFIG_DM_GPIO +int i2c_set_chip_addr_offset_mask(struct udevice *dev, uint mask) +{ + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); + + chip->chip_addr_offset_mask = mask; + + return 0; +} + +uint i2c_get_chip_addr_offset_mask(struct udevice *dev) +{ + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); + + return chip->chip_addr_offset_mask; +} + +#if CONFIG_IS_ENABLED(DM_GPIO) static void i2c_gpio_set_pin(struct gpio_desc *pin, int bit) { if (bit) @@ -561,7 +581,7 @@ static int i2c_deblock_gpio(struct udevice *bus) { return -ENOSYS; } -#endif // CONFIG_DM_GPIO +#endif /* DM_GPIO */ int i2c_deblock(struct udevice *bus) { diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c index a630ce991d..bb2935f8ec 100644 --- a/drivers/i2c/muxes/pca954x.c +++ b/drivers/i2c/muxes/pca954x.c @@ -125,7 +125,7 @@ static int pca954x_ofdata_to_platdata(struct udevice *dev) static int pca954x_probe(struct udevice *dev) { - if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct pca954x_priv *priv = dev_get_priv(dev); int err; @@ -146,7 +146,7 @@ static int pca954x_probe(struct udevice *dev) static int pca954x_remove(struct udevice *dev) { - if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct pca954x_priv *priv = dev_get_priv(dev); if (dm_gpio_is_valid(&priv->gpio_mux_reset)) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 82bb093c56..f18aa8f7ba 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -203,6 +203,15 @@ config FSL_SEC_MON Security Monitor can be transitioned on any security failures, like software violations or hardware security violations. +config IRQ + bool "Intel Interrupt controller" + depends on X86 || SANDBOX + help + This enables support for Intel interrupt controllers, including ITSS. + Some devices have extra features, such as Apollo Lake. The + device has its own uclass since there are several operations + involved. + config JZ4780_EFUSE bool "Ingenic JZ4780 eFUSE support" depends on ARCH_JZ47XX @@ -226,6 +235,39 @@ config NUVOTON_NCT6102D disable the legacy UART, the watchdog or other devices in the Nuvoton Super IO chips on X86 platforms. +config P2SB + bool "Intel Primary-to-Sideband Bus" + depends on X86 || SANDBOX + help + This enables support for the Intel Primary-to-Sideband bus, + abbreviated to P2SB. The P2SB is used to access various peripherals + such as eSPI, GPIO, through memory-mapped I/O in a large chunk of PCI + space. The space is segmented into different channels and peripherals + are accessed by device-specific means within those channels. Devices + should be added in the device tree as subnodes of the P2SB. A + Peripheral Channel Register? (PCR) API is provided to access those + devices - see pcr_readl(), etc. + +config SPL_P2SB + bool "Intel Primary-to-Sideband Bus in SPL" + depends on SPL && (X86 || SANDBOX) + help + The Primary-to-Sideband bus is used to access various peripherals + through memory-mapped I/O in a large chunk of PCI space. The space is + segmented into different channels and peripherals are accessed by + device-specific means within those channels. Devices should be added + in the device tree as subnodes of the p2sb. + +config TPL_P2SB + bool "Intel Primary-to-Sideband Bus in TPL" + depends on TPL && (X86 || SANDBOX) + help + The Primary-to-Sideband bus is used to access various peripherals + through memory-mapped I/O in a large chunk of PCI space. The space is + segmented into different channels and peripherals are accessed by + device-specific means within those channels. Devices should be added + in the device tree as subnodes of the p2sb. + config PWRSEQ bool "Enable power-sequencing drivers" depends on DM diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 55976d6be5..d4e8638dea 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -10,8 +10,10 @@ obj-$(CONFIG_$(SPL_TPL_)CROS_EC_SANDBOX) += cros_ec_sandbox.o obj-$(CONFIG_$(SPL_TPL_)CROS_EC_LPC) += cros_ec_lpc.o ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_SANDBOX) += sandbox_adder.o obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o +obj-$(CONFIG_SANDBOX) += p2sb_sandbox.o p2sb_emul.o obj-$(CONFIG_SANDBOX) += swap_case.o endif @@ -39,6 +41,8 @@ obj-$(CONFIG_FS_LOADER) += fs_loader.o obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o +obj-$(CONFIG_IRQ) += irq-uclass.o +obj-$(CONFIG_SANDBOX) += irq_sandbox.o obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o obj-$(CONFIG_IMX8) += imx8/ @@ -49,6 +53,7 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NS87308) += ns87308.o obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o +obj-$(CONFIG_P2SB) += p2sb-uclass.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o obj-$(CONFIG_QFW) += qfw.o diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 382f826286..fa9984f6bd 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -313,7 +313,7 @@ static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version, * @param din_len Maximum size of response in bytes * @return number of bytes in response, or -ve on error */ -static int ec_command_inptr(struct udevice *dev, uint8_t cmd, +static int ec_command_inptr(struct udevice *dev, uint cmd, int cmd_version, const void *dout, int dout_len, uint8_t **dinp, int din_len) { diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c index 3755dbf74b..934f82074d 100644 --- a/drivers/misc/i2c_eeprom.c +++ b/drivers/misc/i2c_eeprom.c @@ -8,9 +8,15 @@ #include <linux/err.h> #include <linux/kernel.h> #include <dm.h> +#include <dm/device-internal.h> #include <i2c.h> #include <i2c_eeprom.h> +struct i2c_eeprom_drv_data { + u32 size; /* size in bytes */ + u32 pagewidth; /* pagesize = 2^pagewidth */ +}; + int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size) { const struct i2c_eeprom_ops *ops = device_get_ops(dev); @@ -31,6 +37,16 @@ int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size) return ops->write(dev, offset, buf, size); } +int i2c_eeprom_size(struct udevice *dev) +{ + const struct i2c_eeprom_ops *ops = device_get_ops(dev); + + if (!ops->size) + return -ENOSYS; + + return ops->size(dev); +} + static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf, int size) { @@ -60,25 +76,62 @@ static int i2c_eeprom_std_write(struct udevice *dev, int offset, return 0; } +static int i2c_eeprom_std_size(struct udevice *dev) +{ + struct i2c_eeprom *priv = dev_get_priv(dev); + + return priv->size; +} + static const struct i2c_eeprom_ops i2c_eeprom_std_ops = { .read = i2c_eeprom_std_read, .write = i2c_eeprom_std_write, + .size = i2c_eeprom_std_size, }; static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) { struct i2c_eeprom *priv = dev_get_priv(dev); - u64 data = dev_get_driver_data(dev); + struct i2c_eeprom_drv_data *data = + (struct i2c_eeprom_drv_data *)dev_get_driver_data(dev); u32 pagesize; + u32 size; if (dev_read_u32(dev, "pagesize", &pagesize) == 0) { priv->pagesize = pagesize; - return 0; + } else { + /* 6 bit -> page size of up to 2^63 (should be sufficient) */ + priv->pagewidth = data->pagewidth; + priv->pagesize = (1 << priv->pagewidth); } - /* 6 bit -> page size of up to 2^63 (should be sufficient) */ - priv->pagewidth = data & 0x3F; - priv->pagesize = (1 << priv->pagewidth); + if (dev_read_u32(dev, "size", &size) == 0) + priv->size = size; + else + priv->size = data->size; + + return 0; +} + +static int i2c_eeprom_std_bind(struct udevice *dev) +{ + ofnode partitions = ofnode_find_subnode(dev_ofnode(dev), "partitions"); + ofnode partition; + const char *name; + + if (!ofnode_valid(partitions)) + return 0; + if (!ofnode_device_is_compatible(partitions, "fixed-partitions")) + return -ENOTSUPP; + + ofnode_for_each_subnode(partition, partitions) { + name = ofnode_get_name(partition); + if (!name) + continue; + + device_bind_ofnode(dev, DM_GET_DRIVER(i2c_eeprom_partition), + name, NULL, partition, NULL); + } return 0; } @@ -96,21 +149,91 @@ static int i2c_eeprom_std_probe(struct udevice *dev) return 0; } +static const struct i2c_eeprom_drv_data eeprom_data = { + .size = 0, + .pagewidth = 0, +}; + +static const struct i2c_eeprom_drv_data mc24aa02e48_data = { + .size = 256, + .pagewidth = 3, +}; + +static const struct i2c_eeprom_drv_data atmel24c01a_data = { + .size = 128, + .pagewidth = 3, +}; + +static const struct i2c_eeprom_drv_data atmel24c02_data = { + .size = 256, + .pagewidth = 3, +}; + +static const struct i2c_eeprom_drv_data atmel24c04_data = { + .size = 512, + .pagewidth = 4, +}; + +static const struct i2c_eeprom_drv_data atmel24c08_data = { + .size = 1024, + .pagewidth = 4, +}; + +static const struct i2c_eeprom_drv_data atmel24c08a_data = { + .size = 1024, + .pagewidth = 4, +}; + +static const struct i2c_eeprom_drv_data atmel24c16a_data = { + .size = 2048, + .pagewidth = 4, +}; + +static const struct i2c_eeprom_drv_data atmel24mac402_data = { + .size = 256, + .pagewidth = 4, +}; + +static const struct i2c_eeprom_drv_data atmel24c32_data = { + .size = 4096, + .pagewidth = 5, +}; + +static const struct i2c_eeprom_drv_data atmel24c64_data = { + .size = 8192, + .pagewidth = 5, +}; + +static const struct i2c_eeprom_drv_data atmel24c128_data = { + .size = 16384, + .pagewidth = 6, +}; + +static const struct i2c_eeprom_drv_data atmel24c256_data = { + .size = 32768, + .pagewidth = 6, +}; + +static const struct i2c_eeprom_drv_data atmel24c512_data = { + .size = 65536, + .pagewidth = 6, +}; + static const struct udevice_id i2c_eeprom_std_ids[] = { - { .compatible = "i2c-eeprom", .data = 0 }, - { .compatible = "microchip,24aa02e48", .data = 3 }, - { .compatible = "atmel,24c01a", .data = 3 }, - { .compatible = "atmel,24c02", .data = 3 }, - { .compatible = "atmel,24c04", .data = 4 }, - { .compatible = "atmel,24c08", .data = 4 }, - { .compatible = "atmel,24c08a", .data = 4 }, - { .compatible = "atmel,24c16a", .data = 4 }, - { .compatible = "atmel,24mac402", .data = 4 }, - { .compatible = "atmel,24c32", .data = 5 }, - { .compatible = "atmel,24c64", .data = 5 }, - { .compatible = "atmel,24c128", .data = 6 }, - { .compatible = "atmel,24c256", .data = 6 }, - { .compatible = "atmel,24c512", .data = 6 }, + { .compatible = "i2c-eeprom", (ulong)&eeprom_data }, + { .compatible = "microchip,24aa02e48", (ulong)&mc24aa02e48_data }, + { .compatible = "atmel,24c01a", (ulong)&atmel24c01a_data }, + { .compatible = "atmel,24c02", (ulong)&atmel24c02_data }, + { .compatible = "atmel,24c04", (ulong)&atmel24c04_data }, + { .compatible = "atmel,24c08", (ulong)&atmel24c08_data }, + { .compatible = "atmel,24c08a", (ulong)&atmel24c08a_data }, + { .compatible = "atmel,24c16a", (ulong)&atmel24c16a_data }, + { .compatible = "atmel,24mac402", (ulong)&atmel24mac402_data }, + { .compatible = "atmel,24c32", (ulong)&atmel24c32_data }, + { .compatible = "atmel,24c64", (ulong)&atmel24c64_data }, + { .compatible = "atmel,24c128", (ulong)&atmel24c128_data }, + { .compatible = "atmel,24c256", (ulong)&atmel24c256_data }, + { .compatible = "atmel,24c512", (ulong)&atmel24c512_data }, { } }; @@ -118,12 +241,94 @@ U_BOOT_DRIVER(i2c_eeprom_std) = { .name = "i2c_eeprom", .id = UCLASS_I2C_EEPROM, .of_match = i2c_eeprom_std_ids, + .bind = i2c_eeprom_std_bind, .probe = i2c_eeprom_std_probe, .ofdata_to_platdata = i2c_eeprom_std_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct i2c_eeprom), .ops = &i2c_eeprom_std_ops, }; +struct i2c_eeprom_partition { + u32 offset; + u32 size; +}; + +static int i2c_eeprom_partition_probe(struct udevice *dev) +{ + return 0; +} + +static int i2c_eeprom_partition_ofdata_to_platdata(struct udevice *dev) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + u32 offset, size; + int ret; + + ret = dev_read_u32(dev, "offset", &offset); + if (ret) + return ret; + + ret = dev_read_u32(dev, "size", &size); + if (ret) + return ret; + + priv->offset = offset; + priv->size = size; + + return 0; +} + +static int i2c_eeprom_partition_read(struct udevice *dev, int offset, + u8 *buf, int size) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + struct udevice *parent = dev_get_parent(dev); + + if (!parent) + return -ENODEV; + if (offset + size > priv->size) + return -EINVAL; + + return i2c_eeprom_read(parent, offset + priv->offset, buf, size); +} + +static int i2c_eeprom_partition_write(struct udevice *dev, int offset, + const u8 *buf, int size) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + struct udevice *parent = dev_get_parent(dev); + + if (!parent) + return -ENODEV; + if (offset + size > priv->size) + return -EINVAL; + + return i2c_eeprom_write(parent, offset + priv->offset, (uint8_t *)buf, + size); +} + +static int i2c_eeprom_partition_size(struct udevice *dev) +{ + struct i2c_eeprom_partition *priv = dev_get_priv(dev); + + return priv->size; +} + +static const struct i2c_eeprom_ops i2c_eeprom_partition_ops = { + .read = i2c_eeprom_partition_read, + .write = i2c_eeprom_partition_write, + .size = i2c_eeprom_partition_size, +}; + +U_BOOT_DRIVER(i2c_eeprom_partition) = { + .name = "i2c_eeprom_partition", + .id = UCLASS_I2C_EEPROM, + .probe = i2c_eeprom_partition_probe, + .ofdata_to_platdata = i2c_eeprom_partition_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct i2c_eeprom_partition), + .ops = &i2c_eeprom_partition_ops, +}; + UCLASS_DRIVER(i2c_eeprom) = { .id = UCLASS_I2C_EEPROM, .name = "i2c_eeprom", diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c index 29ed45923f..16758a0ef9 100644 --- a/drivers/misc/i2c_eeprom_emul.c +++ b/drivers/misc/i2c_eeprom_emul.c @@ -23,10 +23,13 @@ struct sandbox_i2c_flash_plat_data { const char *filename; int offset_len; /* Length of an offset in bytes */ int size; /* Size of data buffer */ + uint chip_addr_offset_mask; /* mask of addr bits used for offset */ }; struct sandbox_i2c_flash { uint8_t *data; + uint prev_addr; /* slave address of previous access */ + uint prev_offset; /* offset of previous access */ }; void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev, @@ -44,36 +47,65 @@ void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len) plat->offset_len = offset_len; } +void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev, + uint mask) +{ + struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev); + + plat->chip_addr_offset_mask = mask; +} + +uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev) +{ + struct sandbox_i2c_flash *priv = dev_get_priv(dev); + + return priv->prev_addr; +} + +uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev) +{ + struct sandbox_i2c_flash *priv = dev_get_priv(dev); + + return priv->prev_offset; +} + static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg, int nmsgs) { struct sandbox_i2c_flash *priv = dev_get_priv(emul); - uint offset = 0; + struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(emul); + uint offset = msg->addr & plat->chip_addr_offset_mask; debug("\n%s\n", __func__); debug_buffer(0, priv->data, 1, 16, 0); + + /* store addr for testing visibity */ + priv->prev_addr = msg->addr; + for (; nmsgs > 0; nmsgs--, msg++) { - struct sandbox_i2c_flash_plat_data *plat = - dev_get_platdata(emul); int len; u8 *ptr; if (!plat->size) return -ENODEV; - if (msg->addr + msg->len > plat->size) { - debug("%s: Address %x, len %x is outside range 0..%x\n", - __func__, msg->addr, msg->len, plat->size); - return -EINVAL; - } len = msg->len; - debug(" %s: msg->len=%d", + debug(" %s: msg->addr=%x msg->len=%d", msg->flags & I2C_M_RD ? "read" : "write", - msg->len); + msg->addr, msg->len); if (msg->flags & I2C_M_RD) { if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE) len = 1; debug(", offset %x, len %x: ", offset, len); - memcpy(msg->buf, priv->data + offset, len); + if (offset + len > plat->size) { + int overflow = offset + len - plat->size; + int initial = len - overflow; + + memcpy(msg->buf, priv->data + offset, initial); + memcpy(msg->buf + initial, priv->data, + overflow); + } else { + memcpy(msg->buf, priv->data + offset, len); + } memset(msg->buf + len, '\xff', msg->len - len); debug_buffer(0, msg->buf, 1, msg->len, 0); } else if (len >= plat->offset_len) { @@ -87,15 +119,24 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg, if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE) len = min(len, 1); - /* For testing, map offsets into our limited buffer */ - for (i = 24; i > 0; i -= 8) { - if (offset > (1 << i)) { - offset = (offset >> i) | - (offset & ((1 << i) - 1)); - offset += i; - } + /* store offset for testing visibility */ + priv->prev_offset = offset; + + /* For testing, map offsets into our limited buffer. + * offset wraps every 256 bytes + */ + offset &= 0xff; + debug("mapped offset to %x\n", offset); + + if (offset + len > plat->size) { + int overflow = offset + len - plat->size; + int initial = len - overflow; + + memcpy(priv->data + offset, ptr, initial); + memcpy(priv->data, ptr + initial, overflow); + } else { + memcpy(priv->data + offset, ptr, len); } - memcpy(priv->data + offset, ptr, len); } } debug_buffer(0, priv->data, 1, 16, 0); @@ -120,6 +161,7 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev) } plat->test_mode = SIE_TEST_MODE_NONE; plat->offset_len = 1; + plat->chip_addr_offset_mask = 0; return 0; } diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c new file mode 100644 index 0000000000..d5182cf149 --- /dev/null +++ b/drivers/misc/irq-uclass.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> + */ + +#include <common.h> +#include <dm.h> +#include <irq.h> + +int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) +{ + const struct irq_ops *ops = irq_get_ops(dev); + + if (!ops->route_pmc_gpio_gpe) + return -ENOSYS; + + return ops->route_pmc_gpio_gpe(dev, pmc_gpe_num); +} + +int irq_set_polarity(struct udevice *dev, uint irq, bool active_low) +{ + const struct irq_ops *ops = irq_get_ops(dev); + + if (!ops->set_polarity) + return -ENOSYS; + + return ops->set_polarity(dev, irq, active_low); +} + +int irq_snapshot_polarities(struct udevice *dev) +{ + const struct irq_ops *ops = irq_get_ops(dev); + + if (!ops->snapshot_polarities) + return -ENOSYS; + + return ops->snapshot_polarities(dev); +} + +int irq_restore_polarities(struct udevice *dev) +{ + const struct irq_ops *ops = irq_get_ops(dev); + + if (!ops->restore_polarities) + return -ENOSYS; + + return ops->restore_polarities(dev); +} + +UCLASS_DRIVER(irq) = { + .id = UCLASS_IRQ, + .name = "irq", +}; diff --git a/drivers/misc/irq_sandbox.c b/drivers/misc/irq_sandbox.c new file mode 100644 index 0000000000..6dda1a4c44 --- /dev/null +++ b/drivers/misc/irq_sandbox.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sandbox driver for interrupts + * + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <irq.h> + +static int sandbox_set_polarity(struct udevice *dev, uint irq, bool active_low) +{ + if (irq > 10) + return -EINVAL; + + return 0; +} + +static int sandbox_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num) +{ + if (pmc_gpe_num > 10) + return -ENOENT; + + return pmc_gpe_num + 1; +} + +static int sandbox_snapshot_polarities(struct udevice *dev) +{ + return 0; +} + +static int sandbox_restore_polarities(struct udevice *dev) +{ + return 0; +} + +static const struct irq_ops sandbox_irq_ops = { + .route_pmc_gpio_gpe = sandbox_route_pmc_gpio_gpe, + .set_polarity = sandbox_set_polarity, + .snapshot_polarities = sandbox_snapshot_polarities, + .restore_polarities = sandbox_restore_polarities, +}; + +static const struct udevice_id sandbox_irq_ids[] = { + { .compatible = "sandbox,irq"}, + { } +}; + +U_BOOT_DRIVER(sandbox_irq_drv) = { + .name = "sandbox_irq", + .id = UCLASS_IRQ, + .of_match = sandbox_irq_ids, + .ops = &sandbox_irq_ops, +}; diff --git a/drivers/misc/p2sb-uclass.c b/drivers/misc/p2sb-uclass.c new file mode 100644 index 0000000000..a198700b5f --- /dev/null +++ b/drivers/misc/p2sb-uclass.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Uclass for Primary-to-sideband bus, used to access various peripherals + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <mapmem.h> +#include <p2sb.h> +#include <spl.h> +#include <asm/io.h> +#include <dm/uclass-internal.h> + +#define PCR_COMMON_IOSF_1_0 1 + +static void *_pcr_reg_address(struct udevice *dev, uint offset) +{ + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + struct udevice *p2sb = dev_get_parent(dev); + struct p2sb_uc_priv *upriv = dev_get_uclass_priv(p2sb); + uintptr_t reg_addr; + + /* Create an address based off of port id and offset */ + reg_addr = upriv->mmio_base; + reg_addr += pplat->pid << PCR_PORTID_SHIFT; + reg_addr += offset; + + return map_sysmem(reg_addr, 4); +} + +/* + * The mapping of addresses via the SBREG_BAR assumes the IOSF-SB + * agents are using 32-bit aligned accesses for their configuration + * registers. For IOSF versions greater than 1_0, IOSF-SB + * agents can use any access (8/16/32 bit aligned) for their + * configuration registers + */ +static inline void check_pcr_offset_align(uint offset, uint size) +{ + const size_t align = PCR_COMMON_IOSF_1_0 ? sizeof(uint32_t) : size; + + assert(IS_ALIGNED(offset, align)); +} + +uint pcr_read32(struct udevice *dev, uint offset) +{ + void *ptr; + uint val; + + /* Ensure the PCR offset is correctly aligned */ + assert(IS_ALIGNED(offset, sizeof(uint32_t))); + + ptr = _pcr_reg_address(dev, offset); + val = readl(ptr); + unmap_sysmem(ptr); + + return val; +} + +uint pcr_read16(struct udevice *dev, uint offset) +{ + /* Ensure the PCR offset is correctly aligned */ + check_pcr_offset_align(offset, sizeof(uint16_t)); + + return readw(_pcr_reg_address(dev, offset)); +} + +uint pcr_read8(struct udevice *dev, uint offset) +{ + /* Ensure the PCR offset is correctly aligned */ + check_pcr_offset_align(offset, sizeof(uint8_t)); + + return readb(_pcr_reg_address(dev, offset)); +} + +/* + * After every write one needs to perform a read an innocuous register to + * ensure the writes are completed for certain ports. This is done for + * all ports so that the callers don't need the per-port knowledge for + * each transaction. + */ +static void write_completion(struct udevice *dev, uint offset) +{ + readl(_pcr_reg_address(dev, ALIGN_DOWN(offset, sizeof(uint32_t)))); +} + +void pcr_write32(struct udevice *dev, uint offset, uint indata) +{ + /* Ensure the PCR offset is correctly aligned */ + assert(IS_ALIGNED(offset, sizeof(indata))); + + writel(indata, _pcr_reg_address(dev, offset)); + /* Ensure the writes complete */ + write_completion(dev, offset); +} + +void pcr_write16(struct udevice *dev, uint offset, uint indata) +{ + /* Ensure the PCR offset is correctly aligned */ + check_pcr_offset_align(offset, sizeof(uint16_t)); + + writew(indata, _pcr_reg_address(dev, offset)); + /* Ensure the writes complete */ + write_completion(dev, offset); +} + +void pcr_write8(struct udevice *dev, uint offset, uint indata) +{ + /* Ensure the PCR offset is correctly aligned */ + check_pcr_offset_align(offset, sizeof(uint8_t)); + + writeb(indata, _pcr_reg_address(dev, offset)); + /* Ensure the writes complete */ + write_completion(dev, offset); +} + +void pcr_clrsetbits32(struct udevice *dev, uint offset, uint clr, uint set) +{ + uint data32; + + data32 = pcr_read32(dev, offset); + data32 &= ~clr; + data32 |= set; + pcr_write32(dev, offset, data32); +} + +void pcr_clrsetbits16(struct udevice *dev, uint offset, uint clr, uint set) +{ + uint data16; + + data16 = pcr_read16(dev, offset); + data16 &= ~clr; + data16 |= set; + pcr_write16(dev, offset, data16); +} + +void pcr_clrsetbits8(struct udevice *dev, uint offset, uint clr, uint set) +{ + uint data8; + + data8 = pcr_read8(dev, offset); + data8 &= ~clr; + data8 |= set; + pcr_write8(dev, offset, data8); +} + +int p2sb_get_port_id(struct udevice *dev) +{ + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + + return pplat->pid; +} + +int p2sb_set_port_id(struct udevice *dev, int portid) +{ + struct udevice *ps2b; + struct p2sb_child_platdata *pplat; + + if (!CONFIG_IS_ENABLED(OF_PLATDATA)) + return -ENOSYS; + + uclass_find_first_device(UCLASS_P2SB, &ps2b); + if (!ps2b) + return -EDEADLK; + dev->parent = ps2b; + + /* + * We must allocate this, since when the device was bound it did not + * have a parent. + * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc + */ + dev->parent_platdata = malloc(sizeof(*pplat)); + if (!dev->parent_platdata) + return -ENOMEM; + pplat = dev_get_parent_platdata(dev); + pplat->pid = portid; + + return 0; +} + +static int p2sb_child_post_bind(struct udevice *dev) +{ +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + int ret; + u32 pid; + + ret = dev_read_u32(dev, "intel,p2sb-port-id", &pid); + if (ret) + return ret; + pplat->pid = pid; +#endif + + return 0; +} + +static int p2sb_post_bind(struct udevice *dev) +{ + if (spl_phase() > PHASE_TPL && !CONFIG_IS_ENABLED(OF_PLATDATA)) + return dm_scan_fdt_dev(dev); + + return 0; +} + +UCLASS_DRIVER(p2sb) = { + .id = UCLASS_P2SB, + .name = "p2sb", + .per_device_auto_alloc_size = sizeof(struct p2sb_uc_priv), + .post_bind = p2sb_post_bind, + .child_post_bind = p2sb_child_post_bind, + .per_child_platdata_auto_alloc_size = + sizeof(struct p2sb_child_platdata), +}; diff --git a/drivers/misc/p2sb_emul.c b/drivers/misc/p2sb_emul.c new file mode 100644 index 0000000000..c3795c59c0 --- /dev/null +++ b/drivers/misc/p2sb_emul.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * PCI emulation device for an x86 Primary-to-Sideband bus + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#define LOG_CATEGORY UCLASS_MISC +#define LOG_DEBUG + +#include <common.h> +#include <axi.h> +#include <dm.h> +#include <pci.h> +#include <asm/test.h> +#include <p2sb.h> + +/** + * struct p2sb_emul_platdata - platform data for this device + * + * @command: Current PCI command value + * @bar: Current base address values + */ +struct p2sb_emul_platdata { + u16 command; + u32 bar[6]; +}; + +enum { + /* This emulator supports 16 different devices */ + MEMMAP_SIZE = 16 << PCR_PORTID_SHIFT, +}; + +static struct pci_bar { + int type; + u32 size; +} barinfo[] = { + { PCI_BASE_ADDRESS_MEM_TYPE_32, MEMMAP_SIZE }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, +}; + +struct p2sb_emul_priv { + u8 regs[16]; +}; + +static int sandbox_p2sb_emul_read_config(struct udevice *emul, uint offset, + ulong *valuep, enum pci_size_t size) +{ + struct p2sb_emul_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + *valuep = plat->command; + break; + case PCI_HEADER_TYPE: + *valuep = PCI_HEADER_TYPE_NORMAL; + break; + case PCI_VENDOR_ID: + *valuep = SANDBOX_PCI_VENDOR_ID; + break; + case PCI_DEVICE_ID: + *valuep = SANDBOX_PCI_P2SB_EMUL_ID; + break; + case PCI_CLASS_DEVICE: + if (size == PCI_SIZE_8) { + *valuep = SANDBOX_PCI_CLASS_SUB_CODE; + } else { + *valuep = (SANDBOX_PCI_CLASS_CODE << 8) | + SANDBOX_PCI_CLASS_SUB_CODE; + } + break; + case PCI_CLASS_CODE: + *valuep = SANDBOX_PCI_CLASS_CODE; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: + case PCI_BASE_ADDRESS_2: + case PCI_BASE_ADDRESS_3: + case PCI_BASE_ADDRESS_4: + case PCI_BASE_ADDRESS_5: { + int barnum; + u32 *bar; + + barnum = pci_offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + *valuep = sandbox_pci_read_bar(*bar, barinfo[barnum].type, + barinfo[barnum].size); + break; + } + case PCI_CAPABILITY_LIST: + *valuep = PCI_CAP_ID_PM_OFFSET; + break; + } + + return 0; +} + +static int sandbox_p2sb_emul_write_config(struct udevice *emul, uint offset, + ulong value, enum pci_size_t size) +{ + struct p2sb_emul_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + plat->command = value; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: { + int barnum; + u32 *bar; + + barnum = pci_offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + log_debug("w bar %d=%lx\n", barnum, value); + *bar = value; + /* space indicator (bit#0) is read-only */ + *bar |= barinfo[barnum].type; + break; + } + } + + return 0; +} + +static int sandbox_p2sb_emul_find_bar(struct udevice *emul, unsigned int addr, + int *barnump, unsigned int *offsetp) +{ + struct p2sb_emul_platdata *plat = dev_get_platdata(emul); + int barnum; + + for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) { + unsigned int size = barinfo[barnum].size; + u32 base = plat->bar[barnum] & ~PCI_BASE_ADDRESS_SPACE; + + if (addr >= base && addr < base + size) { + *barnump = barnum; + *offsetp = addr - base; + return 0; + } + } + *barnump = -1; + + return -ENOENT; +} + +static int sandbox_p2sb_emul_read_io(struct udevice *dev, unsigned int addr, + ulong *valuep, enum pci_size_t size) +{ + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_p2sb_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + if (barnum == 4) + *valuep = offset; + else if (barnum == 0) + *valuep = offset; + + return 0; +} + +static int sandbox_p2sb_emul_write_io(struct udevice *dev, unsigned int addr, + ulong value, enum pci_size_t size) +{ + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_p2sb_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + return 0; +} + +static int find_p2sb_channel(struct udevice *emul, uint offset, + struct udevice **devp) +{ + uint pid = offset >> PCR_PORTID_SHIFT; + struct udevice *p2sb, *dev; + int ret; + + ret = sandbox_pci_get_client(emul, &p2sb); + if (ret) + return log_msg_ret("No client", ret); + + device_foreach_child(dev, p2sb) { + struct p2sb_child_platdata *pplat = + dev_get_parent_platdata(dev); + + log_debug(" - child %s, pid %d, want %d\n", dev->name, + pplat->pid, pid); + if (pid == pplat->pid) { + *devp = dev; + return 0; + } + } + + return -ENOENT; +} + +static int sandbox_p2sb_emul_map_physmem(struct udevice *dev, + phys_addr_t addr, unsigned long *lenp, + void **ptrp) +{ + struct p2sb_emul_priv *priv = dev_get_priv(dev); + struct udevice *child; + unsigned int offset; + int barnum; + int ret; + + log_debug("map %x: ", (uint)addr); + ret = sandbox_p2sb_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return log_msg_ret("Cannot find bar", ret); + log_debug("bar %d, offset %x\n", barnum, offset); + + if (barnum != 0) + return log_msg_ret("Unknown BAR", -EINVAL); + + ret = find_p2sb_channel(dev, offset, &child); + if (ret) + return log_msg_ret("Cannot find channel", ret); + + offset &= ((1 << PCR_PORTID_SHIFT) - 1); + ret = axi_read(child, offset, priv->regs, AXI_SIZE_32); + if (ret) + return log_msg_ret("Child read failed", ret); + *ptrp = priv->regs + (offset & 3); + *lenp = 4; + + return 0; +} + +static struct dm_pci_emul_ops sandbox_p2sb_emul_emul_ops = { + .read_config = sandbox_p2sb_emul_read_config, + .write_config = sandbox_p2sb_emul_write_config, + .read_io = sandbox_p2sb_emul_read_io, + .write_io = sandbox_p2sb_emul_write_io, + .map_physmem = sandbox_p2sb_emul_map_physmem, +}; + +static const struct udevice_id sandbox_p2sb_emul_ids[] = { + { .compatible = "sandbox,p2sb-emul" }, + { } +}; + +U_BOOT_DRIVER(sandbox_p2sb_emul_emul) = { + .name = "sandbox_p2sb_emul_emul", + .id = UCLASS_PCI_EMUL, + .of_match = sandbox_p2sb_emul_ids, + .ops = &sandbox_p2sb_emul_emul_ops, + .priv_auto_alloc_size = sizeof(struct p2sb_emul_priv), + .platdata_auto_alloc_size = sizeof(struct p2sb_emul_platdata), +}; + +static struct pci_device_id sandbox_p2sb_emul_supported[] = { + { PCI_VDEVICE(SANDBOX, SANDBOX_PCI_PMC_EMUL_ID) }, + {}, +}; + +U_BOOT_PCI_DEVICE(sandbox_p2sb_emul_emul, sandbox_p2sb_emul_supported); diff --git a/drivers/misc/p2sb_sandbox.c b/drivers/misc/p2sb_sandbox.c new file mode 100644 index 0000000000..ce50a9732e --- /dev/null +++ b/drivers/misc/p2sb_sandbox.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sandbox P2SB for testing + * + * Copyright 2019 Google LLC + */ + +#define LOG_CATEGORY UCLASS_P2SB + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <p2sb.h> + +struct sandbox_p2sb_priv { + ulong base; +}; + +static int sandbox_p2sb_probe(struct udevice *dev) +{ + struct p2sb_uc_priv *upriv = dev_get_uclass_priv(dev); + + upriv->mmio_base = dm_pci_read_bar32(dev, 0); + + return 0; +} + +static const struct udevice_id sandbox_p2sb_ids[] = { + { .compatible = "sandbox,p2sb" }, + { } +}; + +U_BOOT_DRIVER(p2sb_sandbox) = { + .name = "p2sb_sandbox", + .id = UCLASS_P2SB, + .of_match = sandbox_p2sb_ids, + .probe = sandbox_p2sb_probe, + .priv_auto_alloc_size = sizeof(struct sandbox_p2sb_priv), +}; diff --git a/drivers/misc/sandbox_adder.c b/drivers/misc/sandbox_adder.c new file mode 100644 index 0000000000..df262e6255 --- /dev/null +++ b/drivers/misc/sandbox_adder.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sandbox adder for p2sb testing + * + * Copyright 2019 Google LLC + */ + +#define LOG_CATEGORY UCLASS_MISC + +#include <common.h> +#include <axi.h> +#include <dm.h> +#include <misc.h> +#include <p2sb.h> +#include <asm/io.h> + +struct sandbox_adder_priv { + ulong base; +}; + +int sandbox_adder_read(struct udevice *dev, ulong address, void *data, + enum axi_size_t size) +{ + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + u32 *val = data; + + *val = pplat->pid << 24 | address; + + return 0; +} + +int sandbox_adder_write(struct udevice *dev, ulong address, void *data, + enum axi_size_t size) +{ + return 0; +} + +static int sandbox_adder_probe(struct udevice *dev) +{ + return 0; +} + +static struct axi_ops sandbox_adder_ops = { + .read = sandbox_adder_read, + .write = sandbox_adder_write, +}; + +static const struct udevice_id sandbox_adder_ids[] = { + { .compatible = "sandbox,adder" }, + { } +}; + +U_BOOT_DRIVER(adder_sandbox) = { + .name = "sandbox_adder", + .id = UCLASS_AXI, + .of_match = sandbox_adder_ids, + .probe = sandbox_adder_probe, + .ops = &sandbox_adder_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_adder_priv), +}; diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index f1afab742d..f7b754bd9d 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -150,7 +150,7 @@ struct fsl_esdhc_priv { struct udevice *vqmmc_dev; struct udevice *vmmc_dev; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; #endif @@ -303,8 +303,9 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, return -ETIMEDOUT; } } else { -#ifdef CONFIG_DM_GPIO - if (dm_gpio_is_valid(&priv->wp_gpio) && dm_gpio_get_value(&priv->wp_gpio)) { +#if CONFIG_IS_ENABLED(DM_GPIO) + if (dm_gpio_is_valid(&priv->wp_gpio) && + dm_gpio_get_value(&priv->wp_gpio)) { printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); return -ETIMEDOUT; } @@ -1092,7 +1093,7 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) #if CONFIG_IS_ENABLED(DM_MMC) if (priv->non_removable) return 1; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (dm_gpio_is_valid(&priv->cd_gpio)) return dm_gpio_get_value(&priv->cd_gpio); #endif @@ -1454,7 +1455,7 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->non_removable = 1; } else { priv->non_removable = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); #endif @@ -1464,7 +1465,7 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->wp_enable = 1; } else { priv->wp_enable = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index dab3425e97..5d0cfb2ebd 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -184,7 +184,7 @@ static int omap_mmc_setup_gpio_in(int gpio, const char *label) { int ret; -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) if (!gpio_is_valid(gpio)) return -1; #endif diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index f051e473ff..72b6ee702d 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -137,7 +137,7 @@ static int spi_flash_std_get_sw_write_prot(struct udevice *dev) return spi_flash_cmd_get_sw_write_prot(flash); } -static int spi_flash_std_probe(struct udevice *dev) +int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 5c2d5e5a79..19fc34f771 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -82,7 +82,7 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, return ret; } -#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO) static int dw_mdio_reset(struct mii_dev *bus) { struct udevice *dev = bus->priv; @@ -128,7 +128,7 @@ static int dw_mdio_init(const char *name, void *priv) bus->read = dw_mdio_read; bus->write = dw_mdio_write; snprintf(bus->name, sizeof(bus->name), "%s", name); -#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO) bus->reset = dw_mdio_reset; #endif @@ -807,12 +807,12 @@ const struct eth_ops designware_eth_ops = { int designware_eth_ofdata_to_platdata(struct udevice *dev) { struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct dw_eth_dev *priv = dev_get_priv(dev); #endif struct eth_pdata *pdata = &dw_pdata->eth_pdata; const char *phy_mode; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) int reset_flags = GPIOD_IS_OUT; #endif int ret = 0; @@ -829,7 +829,7 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev) pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (dev_read_bool(dev, "snps,reset-active-low")) reset_flags |= GPIOD_ACTIVE_LOW; diff --git a/drivers/net/designware.h b/drivers/net/designware.h index dea12b7048..3519a4167a 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -7,7 +7,7 @@ #ifndef _DW_ETH_H #define _DW_ETH_H -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm-generic/gpio.h> #endif @@ -235,7 +235,7 @@ struct dw_eth_dev { #ifndef CONFIG_DM_ETH struct eth_device *dev; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; #endif #ifdef CONFIG_CLK diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 2aa1029d42..bc5b63d788 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1309,7 +1309,7 @@ static int fec_phy_init(struct fec_priv *priv, struct udevice *dev) return 0; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* FEC GPIO reset */ static void fec_gpio_reset(struct fec_priv *priv) { @@ -1402,7 +1402,7 @@ static int fecmxc_probe(struct udevice *dev) } #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) fec_gpio_reset(priv); #endif /* Reset chip. */ @@ -1508,7 +1508,7 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev) device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply); #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) ret = gpio_request_by_name(dev, "phy-reset-gpios", 0, &priv->phy_reset_gpio, GPIOD_IS_OUT); if (ret < 0) diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 723b06a651..159aec8967 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -255,7 +255,7 @@ struct fec_priv { #ifdef CONFIG_DM_REGULATOR struct udevice *phy_supply; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; uint32_t reset_delay; uint32_t reset_post_delay; diff --git a/drivers/net/fsl-mc/Kconfig b/drivers/net/fsl-mc/Kconfig index 25a2cb8ffa..2cf651d3b3 100644 --- a/drivers/net/fsl-mc/Kconfig +++ b/drivers/net/fsl-mc/Kconfig @@ -22,4 +22,16 @@ config SYS_MC_RSV_MEM_ALIGN Reserved memory needs to be aligned for MC to use. Default value is 512MB. +config MC_DRAM_SPB_OFFSET + hex "Soft Parser SPB DRAM offset" + default 0x00F40000 + help + Set the DRAM offset for Soft Parser Blob. + +config MC_SPB_MAX_SIZE + hex "Soft Parser SPB maximum size" + default 0x00020000 + help + Set the maximum size for Soft Parser Blob. + endif # FSL_MC_ENET diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/Makefile index 1b1b4a77f8..5a1acd576a 100644 --- a/drivers/net/fsl-mc/Makefile +++ b/drivers/net/fsl-mc/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # # Copyright 2014 Freescale Semiconductor, Inc. +# Copyright 2018 NXP # Layerscape MC driver obj-y += mc.o \ @@ -9,5 +10,6 @@ obj-y += mc.o \ dprc.o \ dpbp.o \ dpni.o \ - dpmac.o + dpmac.o \ + dpsparser.o obj-y += dpio/ diff --git a/drivers/net/fsl-mc/dpsparser.c b/drivers/net/fsl-mc/dpsparser.c new file mode 100644 index 0000000000..cfd1ba66a0 --- /dev/null +++ b/drivers/net/fsl-mc/dpsparser.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Data Path Soft Parser + * + * Copyright 2018 NXP + */ +#include <fsl-mc/fsl_mc_sys.h> +#include <fsl-mc/fsl_mc_cmd.h> +#include <fsl-mc/fsl_dpsparser.h> + +int dpsparser_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *token) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_OPEN, + cmd_flags, + 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *token = MC_CMD_HDR_READ_TOKEN(cmd.header); + + return err; +} + +int dpsparser_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_CLOSE, cmd_flags, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpsparser_create(struct fsl_mc_io *mc_io, + u16 token, + u32 cmd_flags, + u32 *obj_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_CREATE, + cmd_flags, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + MC_CMD_READ_OBJ_ID(cmd, *obj_id); + + return 0; +} + +int dpsparser_destroy(struct fsl_mc_io *mc_io, + u16 token, + u32 cmd_flags, + u32 obj_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_DESTROY, + cmd_flags, + token); + + /* set object id to destroy */ + CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, obj_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpsparser_apply_spb(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u64 blob_addr, + u16 *error) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_APPLY_SPB, + cmd_flags, + token); + DPSPARSER_CMD_BLOB_SET_ADDR(cmd, blob_addr); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters: MC error code */ + DPSPARSER_CMD_BLOB_REPORT_ERROR(cmd, *error); + + return 0; +} + +int dpsparser_get_api_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *major_ver, + u16 *minor_ver) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_GET_API_VERSION, + cmd_flags, 0); + + /* send command to mc */ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + mc_cmd_read_api_version(&cmd, major_ver, minor_ver); + + return 0; +} diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index ffc408e3a4..8ff43a91c7 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2014 Freescale Semiconductor, Inc. - * Copyright 2017 NXP * Copyright 2017-2018 NXP */ #include <common.h> @@ -21,6 +20,7 @@ #include <fsl-mc/fsl_dprc.h> #include <fsl-mc/fsl_dpio.h> #include <fsl-mc/fsl_dpni.h> +#include <fsl-mc/fsl_dpsparser.h> #include <fsl-mc/fsl_qbman_portal.h> #include <fsl-mc/ldpaa_wriop.h> @@ -35,6 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; static int mc_memset_resv_ram; +static struct mc_version mc_ver_info; static int mc_boot_status = -1; static int mc_dpl_applied = -1; #ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET @@ -49,6 +50,9 @@ struct fsl_dpbp_obj *dflt_dpbp = NULL; struct fsl_dpio_obj *dflt_dpio = NULL; struct fsl_dpni_obj *dflt_dpni = NULL; static u64 mc_lazy_dpl_addr; +static u32 dpsparser_obj_id; +static u16 dpsparser_handle; +static char *mc_err_msg_apply_spb[] = MC_ERROR_MSG_APPLY_SPB; #ifdef DEBUG void dump_ram_words(const char *title, void *addr) @@ -92,7 +96,6 @@ void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs) #endif /* DEBUG */ -#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR /** * Copying MC firmware or DPL image to DDR */ @@ -105,6 +108,7 @@ static int mc_copy_image(const char *title, return 0; } +#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR /** * MC firmware FIT image parser checks if the image is in FIT * format, verifies integrity of the image and calculates @@ -691,7 +695,6 @@ int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr) const void *raw_image_addr; size_t raw_image_size = 0; #endif - struct mc_version mc_ver_info; u8 mc_ram_num_256mb_blocks; size_t mc_ram_size = mc_get_dram_block_size(); @@ -1447,6 +1450,170 @@ err: return err; } +static bool is_dpsparser_supported(void) +{ + /* dpsparser support was first introduced in MC version: 10.12.0 */ + if (mc_ver_info.major < 10) + return false; + if (mc_ver_info.major == 10) + return (mc_ver_info.minor >= 12); + return true; +} + +static int dpsparser_version_check(struct fsl_mc_io *mc_io) +{ + int error; + u16 major_ver, minor_ver; + + if (!is_dpsparser_supported()) + return 0; + + error = dpsparser_get_api_version(mc_io, 0, + &major_ver, + &minor_ver); + if (error < 0) { + printf("dpsparser_get_api_version() failed: %d\n", error); + return error; + } + + if (major_ver < DPSPARSER_VER_MAJOR || (major_ver == + DPSPARSER_VER_MAJOR && minor_ver < DPSPARSER_VER_MINOR)) { + printf("DPSPARSER version mismatch found %u.%u,", + major_ver, minor_ver); + printf("supported version is %u.%u\n", + DPSPARSER_VER_MAJOR, DPSPARSER_VER_MINOR); + } + + return error; +} + +static int dpsparser_init(void) +{ + int err = 0; + + if (!is_dpsparser_supported()) + return 0; + + err = dpsparser_create(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, + &dpsparser_obj_id); + if (err) + printf("dpsparser_create() failed\n"); + + err = dpsparser_version_check(dflt_mc_io); + if (err < 0) { + printf("dpsparser_version_check() failed: %d\n", err); + goto err_version_check; + } + + err = dpsparser_open(dflt_mc_io, + MC_CMD_NO_FLAGS, + &dpsparser_handle); + if (err < 0) { + printf("dpsparser_open() failed: %d\n", err); + goto err_open; + } + + return err; + +err_open: +err_version_check: + dpsparser_destroy(dflt_mc_io, + dflt_dprc_handle, + MC_CMD_NO_FLAGS, dpsparser_obj_id); + + return err; +} + +#ifdef DPSPARSER_DESTROY +/* TODO: refactoring needed in the future to allow DPSPARSER object destroy + * Workaround: DO NOT destroy DPSPARSER object because it needs to be available + * on Apply DPL + */ +static int dpsparser_exit(void) +{ + int err; + + if (!is_dpsparser_supported()) + return 0; + + dpsparser_close(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle); + if (err < 0) { + printf("dpsparser_close() failed: %d\n", err); + goto err; + } + + err = dpsparser_destroy(dflt_mc_io, dflt_dprc_handle, + MC_CMD_NO_FLAGS, dpsparser_obj_id); + if (err < 0) { + printf("dpsparser_destroy() failed: %d\n", err); + goto err; + } + return 0; + +err: + return err; +} +#endif + +int mc_apply_spb(u64 mc_spb_addr) +{ + int err = 0; + u16 error, err_arr_size; + u64 mc_spb_offset; + u32 spb_size; + struct sp_blob_header *sp_blob; + u64 mc_ram_addr = mc_get_dram_addr(); + + if (!is_dpsparser_supported()) + return 0; + + if (!mc_spb_addr) { + printf("fsl-mc: Invalid Blob address\n"); + return -1; + } + +#ifdef CONFIG_MC_DRAM_SPB_OFFSET + mc_spb_offset = CONFIG_MC_DRAM_SPB_OFFSET; +#else +#error "CONFIG_MC_DRAM_SPB_OFFSET not defined" +#endif + + // Read blob header and get size of SPB blob + sp_blob = (struct sp_blob_header *)mc_spb_addr; + spb_size = le32_to_cpu(sp_blob->length); + if (spb_size > CONFIG_MC_SPB_MAX_SIZE) { + printf("\nfsl-mc: ERROR: Bad SPB image (too large: %d)\n", + spb_size); + return -EINVAL; + } + + mc_copy_image("MC SP Blob", mc_spb_addr, spb_size, + mc_ram_addr + mc_spb_offset); + + //Invoke MC command to apply SPB blob + printf("fsl-mc: Applying soft parser blob... "); + err = dpsparser_apply_spb(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle, + mc_spb_offset, &error); + if (err) + return err; + + if (error == 0) { + printf("SUCCESS\n"); + } else { + printf("FAILED with error code = %d:\n", error); + err_arr_size = (u16)ARRAY_SIZE(mc_err_msg_apply_spb); + + if (error > 0 && error < err_arr_size) + printf(mc_err_msg_apply_spb[error]); + else + printf(MC_ERROR_MSG_SPB_UNKNOWN); + } + + return err; +} + static int mc_init_object(void) { int err = 0; @@ -1475,6 +1642,12 @@ static int mc_init_object(void) goto err; } + err = dpsparser_init(); + if (err < 0) { + printf("dpsparser_init() failed: %d\n", err); + goto err; + } + return 0; err: return err; @@ -1608,39 +1781,87 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } break; - case 'l': + case 'l': { + /* lazyapply */ + u64 mc_dpl_addr; + + if (argc < 4) + goto usage; + + if (get_dpl_apply_status() == 0) { + printf("fsl-mc: DPL already applied\n"); + return err; + } + + mc_dpl_addr = simple_strtoull(argv[3], NULL, 16); + + if (get_mc_boot_status() != 0) { + printf("fsl-mc: Deploying data path layout .."); + printf("ERROR (MC is not booted)\n"); + return -ENODEV; + } + + /* + * We will do the actual dpaa exit and dpl apply + * later from announce_and_cleanup(). + */ + mc_lazy_dpl_addr = mc_dpl_addr; + break; + } + case 'a': { - u64 mc_dpl_addr; + /* apply */ + char sub_cmd; + u64 mc_apply_addr; - if (argc < 4) - goto usage; + if (argc < 4) + goto usage; + + sub_cmd = argv[2][0]; + switch (sub_cmd) { + case 'd': + case 'D': if (get_dpl_apply_status() == 0) { printf("fsl-mc: DPL already applied\n"); return err; } - - mc_dpl_addr = simple_strtoull(argv[3], NULL, - 16); - if (get_mc_boot_status() != 0) { printf("fsl-mc: Deploying data path layout .."); printf("ERROR (MC is not booted)\n"); return -ENODEV; } - if (argv[1][0] == 'l') { - /* - * We will do the actual dpaa exit and dpl apply - * later from announce_and_cleanup(). - */ - mc_lazy_dpl_addr = mc_dpl_addr; - } else { - /* The user wants it applied now */ - if (!fsl_mc_ldpaa_exit(NULL)) - err = mc_apply_dpl(mc_dpl_addr); + mc_apply_addr = simple_strtoull(argv[3], NULL, 16); + + /* The user wants DPL applied now */ + if (!fsl_mc_ldpaa_exit(NULL)) + err = mc_apply_dpl(mc_apply_addr); + break; + + case 's': + if (!is_dpsparser_supported()) { + printf("fsl-mc: apply spb command .. "); + printf("ERROR: requires at least MC 10.12.0\n"); + return err; } + if (get_mc_boot_status() != 0) { + printf("fsl-mc: Deploying Soft Parser Blob..."); + printf("ERROR (MC is not booted)\n"); + return err; + } + + mc_apply_addr = simple_strtoull(argv[3], NULL, 16); + + /* Apply spb (Soft Parser Blob) */ + err = mc_apply_spb(mc_apply_addr); break; + + default: + printf("Invalid option: %s\n", argv[2]); + goto usage; + } + break; } default: printf("Invalid option: %s\n", argv[1]); @@ -1658,6 +1879,7 @@ U_BOOT_CMD( "start mc [FW_addr] [DPC_addr] - Start Management Complex\n" "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n" "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n" + "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n" "fsl_mc start aiop [FW_addr] - Start AIOP\n" ); diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index 6f76a6b0dc..5fe8500199 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -276,7 +276,7 @@ struct mvneta_port { int init; int phyaddr; struct phy_device *phydev; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; #endif struct mii_dev *bus; @@ -1754,7 +1754,7 @@ static int mvneta_probe(struct udevice *dev) if (ret) return ret; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "phy-reset-gpios", 0, &pp->phy_reset_gpio, GPIOD_IS_OUT); diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index c5d1f9cf9f..917d06b6e0 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -959,7 +959,8 @@ struct mvpp2_port { phy_interface_t phy_interface; int phyaddr; struct udevice *mdio_dev; -#ifdef CONFIG_DM_GPIO + struct mii_dev *bus; +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; struct gpio_desc phy_tx_disable_gpio; #endif @@ -4742,7 +4743,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) return -EINVAL; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "phy-reset-gpios", 0, &port->phy_reset_gpio, GPIOD_IS_OUT); gpio_request_by_name(dev, "marvell,sfp-tx-disable-gpio", 0, @@ -4769,7 +4770,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) return 0; } -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* Port GPIO initialization */ static void mvpp2_gpio_init(struct mvpp2_port *port) { @@ -4802,7 +4803,7 @@ static int mvpp2_port_probe(struct udevice *dev, } mvpp2_port_power_up(port); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) mvpp2_gpio_init(port); #endif diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 9551918796..6f10578c88 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -24,7 +24,7 @@ #include <net.h> #include <reset.h> #include <dt-bindings/pinctrl/sun4i-a10.h> -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm-generic/gpio.h> #endif @@ -142,7 +142,7 @@ struct emac_eth_dev { struct clk ephy_clk; struct reset_ctl tx_rst; struct reset_ctl ephy_rst; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; #endif }; @@ -696,7 +696,7 @@ err_tx_clk: return ret; } -#if defined(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static int sun8i_mdio_reset(struct mii_dev *bus) { struct udevice *dev = bus->priv; @@ -743,7 +743,7 @@ static int sun8i_mdio_init(const char *name, struct udevice *priv) bus->write = sun8i_mdio_write; snprintf(bus->name, sizeof(bus->name), name); bus->priv = (void *)priv; -#if defined(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) bus->reset = sun8i_mdio_reset; #endif @@ -905,7 +905,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) const fdt32_t *reg; int node = dev_of_offset(dev); int offset = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) int reset_flags = GPIOD_IS_OUT; #endif int ret; @@ -999,7 +999,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) printf("%s: Invalid RX delay value %d\n", __func__, sun8i_pdata->rx_delay_ps); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "snps,reset-active-low")) reset_flags |= GPIOD_ACTIVE_LOW; diff --git a/drivers/pch/Kconfig b/drivers/pch/Kconfig index 18f006de24..c49a92885a 100644 --- a/drivers/pch/Kconfig +++ b/drivers/pch/Kconfig @@ -7,3 +7,21 @@ config PCH northbridge / southbridge architecture that was previously used. The PCH allows for higher performance since the memory functions are handled in the CPU. + +config X86_PCH7 + bool "Add support for Intel PCH7" + default y if X86 + help + Enable this if your SoC uses Platform Controller Hub 7 (PCH7). This + dates from about 2011 and is used on baytrail, for example. The + PCH provides access to the GPIO and SPI base addresses, among other + functions. + +config X86_PCH9 + bool "Add support for Intel PCH9" + default y if X86 + help + Enable this if your SoC uses Platform Controller Hub 9 (PCH9). This + dates from about 2015 and is used on baytrail, for example. The + PCH provides access to the GPIO and SPI base addresses, among other + functions. diff --git a/drivers/pch/Makefile b/drivers/pch/Makefile index 8ea6b7852a..d5de3e48be 100644 --- a/drivers/pch/Makefile +++ b/drivers/pch/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += pch-uclass.o -obj-y += pch7.o -obj-y += pch9.o +obj-$(CONFIG_X86_PCH7) += pch7.o +obj-$(CONFIG_X86_PCH9) += pch9.o obj-$(CONFIG_SANDBOX) += sandbox_pch.o diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 13603b9d57..437cd9a055 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -143,6 +143,30 @@ config PCIE_LAYERSCAPE_GEN4 several PCIe controllers. The PCIe controller can work in RC or EP mode according to RCW[HOST_AGT_PEX] setting. +config FSL_PCIE_COMPAT + string "PCIe compatible of Kernel DT" + depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4 + default "fsl,ls1012a-pcie" if ARCH_LS1012A + default "fsl,ls1028a-pcie" if ARCH_LS1028A + default "fsl,ls1043a-pcie" if ARCH_LS1043A + default "fsl,ls1046a-pcie" if ARCH_LS1046A + default "fsl,ls2080a-pcie" if ARCH_LS2080A + default "fsl,ls1088a-pcie" if ARCH_LS1088A + default "fsl,lx2160a-pcie" if ARCH_LX2160A + default "fsl,ls1021a-pcie" if ARCH_LS1021A + help + This compatible is used to find pci controller node in Kernel DT + to complete fixup. + +config FSL_PCIE_EP_COMPAT + string "PCIe EP compatible of Kernel DT" + depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4 + default "fsl,lx2160a-pcie-ep" if ARCH_LX2160A + default "fsl,ls-pcie-ep" + help + This compatible is used to find pci controller ep node in Kernel DT + to complete fixup. + config PCIE_INTEL_FPGA bool "Intel FPGA PCIe support" depends on DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index da8b826d69..8a33eb0266 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -36,7 +36,7 @@ obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \ - pcie_layerscape_gen4_fixup.o + pcie_layerscape_gen4_fixup.o pcie_layerscape.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c index 864ac16f57..aa0b4bc845 100644 --- a/drivers/pci/pci-aardvark.c +++ b/drivers/pci/pci-aardvark.c @@ -610,7 +610,7 @@ static int pcie_advk_probe(struct udevice *dev) { struct pcie_advk *pcie = dev_get_priv(dev); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; gpio_request_by_name(dev, "reset-gpio", 0, &reset_gpio, @@ -636,7 +636,7 @@ static int pcie_advk_probe(struct udevice *dev) } #else dev_dbg(pcie->dev, "PCIE Reset on GPIO support is missing\n"); -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */ pcie->first_busno = dev->seq; pcie->dev = pci_get_controller(dev); diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index fab20fc60e..7308f612b6 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -975,12 +975,15 @@ static int pci_uclass_pre_probe(struct udevice *bus) hose->bus = bus; hose->first_busno = bus->seq; hose->last_busno = bus->seq; + hose->skip_auto_config_until_reloc = + dev_read_bool(bus, "u-boot,skip-auto-config-until-reloc"); return 0; } static int pci_uclass_post_probe(struct udevice *bus) { + struct pci_controller *hose = dev_get_uclass_priv(bus); int ret; debug("%s: probing bus %d\n", __func__, bus->seq); @@ -988,11 +991,13 @@ static int pci_uclass_post_probe(struct udevice *bus) if (ret) return ret; -#if CONFIG_IS_ENABLED(PCI_PNP) - ret = pci_auto_config_devices(bus); - if (ret < 0) - return ret; -#endif + if (CONFIG_IS_ENABLED(PCI_PNP) && + (!hose->skip_auto_config_until_reloc || + (gd->flags & GD_FLG_RELOC))) { + ret = pci_auto_config_devices(bus); + if (ret < 0) + return log_msg_ret("pci auto-config", ret); + } #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) /* @@ -1018,22 +1023,6 @@ static int pci_uclass_post_probe(struct udevice *bus) return 0; } -int pci_get_devfn(struct udevice *dev) -{ - struct fdt_pci_addr addr; - int ret; - - /* Extract the devfn from fdt_pci_addr */ - ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, - "reg", &addr); - if (ret) { - if (ret != -ENOENT) - return -EINVAL; - } - - return addr.phys_hi & 0xff00; -} - static int pci_uclass_child_post_bind(struct udevice *dev) { struct pci_child_platdata *pplat; diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c index 95fb41966f..693591e375 100644 --- a/drivers/pci/pcie_dw_mvebu.c +++ b/drivers/pci/pcie_dw_mvebu.c @@ -476,7 +476,7 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) struct pcie_dw_mvebu *pcie = dev_get_priv(dev); struct udevice *ctlr = pci_get_controller(dev); struct pci_controller *hose = dev_get_uclass_priv(ctlr); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; gpio_request_by_name(dev, "marvell,reset-gpio", 0, &reset_gpio, @@ -496,7 +496,7 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) } #else debug("PCIE Reset on GPIO support is missing\n"); -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */ pcie->first_busno = dev->seq; diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index 5ad7c28773..47394bdba7 100644 --- a/drivers/pci/pcie_layerscape.c +++ b/drivers/pci/pcie_layerscape.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017 NXP + * Copyright 2017-2019 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ @@ -339,6 +339,7 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie) dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN); ls_pcie_disable_bars(pcie); + pcie->stream_id_cur = 0; } static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie) diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h index ddfbba6538..95454bc188 100644 --- a/drivers/pci/pcie_layerscape.h +++ b/drivers/pci/pcie_layerscape.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright 2017 NXP + * Copyright 2017-2019 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ @@ -144,6 +144,7 @@ struct ls_pcie { bool big_endian; bool enabled; int next_lut_index; + int stream_id_cur; int mode; }; diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c index 089e031724..27ef20d4c3 100644 --- a/drivers/pci/pcie_layerscape_fixup.c +++ b/drivers/pci/pcie_layerscape_fixup.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017 NXP + * Copyright 2017-2019 NXP * Copyright 2014-2015 Freescale Semiconductor, Inc. * Layerscape PCIe driver */ @@ -69,8 +69,8 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid, * msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count] * [devid] [phandle-to-msi-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie, - u32 devid, u32 streamid) +static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie, + u32 devid, u32 streamid) { u32 *prop; u32 phandle; @@ -122,8 +122,8 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie, * iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count] * [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie *pcie, - u32 devid, u32 streamid) +static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie, + u32 devid, u32 streamid) { u32 *prop; u32 iommu_map[4]; @@ -175,7 +175,7 @@ static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie *pcie, } } -static void fdt_fixup_pcie(void *blob) +static void fdt_fixup_pcie_ls(void *blob) { struct udevice *dev, *bus; struct ls_pcie *pcie; @@ -209,11 +209,11 @@ static void fdt_fixup_pcie(void *blob) ls_pcie_lut_set_mapping(pcie, index, bdf >> 8, streamid); /* update msi-map in device tree */ - fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, - streamid); + fdt_pcie_set_msi_map_entry_ls(blob, pcie, bdf >> 8, + streamid); /* update iommu-map in device tree */ - fdt_pcie_set_iommu_map_entry(blob, pcie, bdf >> 8, - streamid); + fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8, + streamid); } } #endif @@ -253,7 +253,7 @@ static void ft_pcie_ep_fix(void *blob, struct ls_pcie *pcie) { int off; - off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie-ep", + off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT, pcie->dbi_res.start); if (off < 0) return; @@ -279,7 +279,7 @@ void ft_pci_setup(void *blob, bd_t *bd) ft_pcie_ls_setup(blob, pcie); #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) - fdt_fixup_pcie(blob); + fdt_fixup_pcie_ls(blob); #endif } diff --git a/drivers/pci/pcie_layerscape_gen4_fixup.c b/drivers/pci/pcie_layerscape_gen4_fixup.c index 1c9e5750bd..da9817159f 100644 --- a/drivers/pci/pcie_layerscape_gen4_fixup.c +++ b/drivers/pci/pcie_layerscape_gen4_fixup.c @@ -37,7 +37,7 @@ static int ls_pcie_g4_next_streamid(struct ls_pcie_g4 *pcie) { int stream_id = pcie->stream_id_cur; - if (stream_id > FSL_PEX_STREAM_ID_NUM) + if (stream_id > FSL_PEX_STREAM_ID_END) return -EINVAL; pcie->stream_id_cur++; @@ -64,8 +64,9 @@ static void ls_pcie_g4_lut_set_mapping(struct ls_pcie_g4 *pcie, int index, * msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count] * [devid] [phandle-to-msi-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie_g4 *pcie, - u32 devid, u32 streamid) +static void fdt_pcie_set_msi_map_entry_ls_gen4(void *blob, + struct ls_pcie_g4 *pcie, + u32 devid, u32 streamid) { u32 *prop; u32 phandle; @@ -106,8 +107,9 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie_g4 *pcie, * iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count] * [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>; */ -static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie_g4 *pcie, - u32 devid, u32 streamid) +static void fdt_pcie_set_iommu_map_entry_ls_gen4(void *blob, + struct ls_pcie_g4 *pcie, + u32 devid, u32 streamid) { u32 *prop; u32 iommu_map[4]; @@ -145,7 +147,7 @@ static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie_g4 *pcie, fdt_appendprop(blob, nodeoff, "iommu-map", iommu_map, 16); } -static void fdt_fixup_pcie(void *blob) +static void fdt_fixup_pcie_ls_gen4(void *blob) { struct udevice *dev, *bus; struct ls_pcie_g4 *pcie; @@ -176,9 +178,11 @@ static void fdt_fixup_pcie(void *blob) /* map PCI b.d.f to streamID in LUT */ ls_pcie_g4_lut_set_mapping(pcie, index, bdf >> 8, streamid); /* update msi-map in device tree */ - fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, streamid); + fdt_pcie_set_msi_map_entry_ls_gen4(blob, pcie, bdf >> 8, + streamid); /* update iommu-map in device tree */ - fdt_pcie_set_iommu_map_entry(blob, pcie, bdf >> 8, streamid); + fdt_pcie_set_iommu_map_entry_ls_gen4(blob, pcie, bdf >> 8, + streamid); } } #endif @@ -187,7 +191,7 @@ static void ft_pcie_ep_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie) { int off; - off = fdt_node_offset_by_compat_reg(blob, "fsl,lx2160a-pcie-ep", + off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT, pcie->ccsr_res.start); if (off < 0) { @@ -238,7 +242,7 @@ void ft_pci_setup(void *blob, bd_t *bd) ft_pcie_layerscape_gen4_setup(blob, pcie); #if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2) - fdt_fixup_pcie(blob); + fdt_fixup_pcie_ls_gen4(blob); #endif } diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index eadcfd6652..83e39b9de3 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -82,6 +82,13 @@ config SPL_PINCTRL This option is an SPL-variant of the PINCTRL option. See the help of PINCTRL for details. +config TPL_PINCTRL + bool "Support pin controllers in TPL" + depends on TPL && TPL_DM + help + This option is an TPL variant of the PINCTRL option. + See the help of PINCTRL for details. + config SPL_PINCTRL_FULL bool "Support full pin controllers in SPL" depends on SPL_PINCTRL && SPL_OF_CONTROL @@ -91,6 +98,13 @@ config SPL_PINCTRL_FULL This option is an SPL-variant of the PINCTRL_FULL option. See the help of PINCTRL_FULL for details. +config TPL_PINCTRL_FULL + bool "Support full pin controllers in TPL" + depends on TPL_PINCTRL && TPL_OF_CONTROL + help + This option is an TPL-variant of the PINCTRL_FULL option. + See the help of PINCTRL_FULL for details. + config SPL_PINCTRL_GENERIC bool "Support generic pin controllers in SPL" depends on SPL_PINCTRL_FULL @@ -163,6 +177,14 @@ config PINCTRL_AT91PIO4 This option is to enable the AT91 pinctrl driver for AT91 PIO4 controller which is available on SAMA5D2 SoC. +config PINCTRL_INTEL + bool "Standard Intel pin-control and pin-mux driver" + help + Recent Intel chips such as Apollo Lake (APL) use a common pin control + and GPIO scheme. The settings for this come from an SoC-specific + driver which must be separately enabled. The driver supports setting + pins on start-up and changing the GPIO attributes. + config PINCTRL_PIC32 bool "Microchip PIC32 pin-control and pin-mux driver" depends on DM && MACH_PIC32 @@ -266,6 +288,7 @@ endif source "drivers/pinctrl/broadcom/Kconfig" source "drivers/pinctrl/exynos/Kconfig" +source "drivers/pinctrl/intel/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/mscc/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index ce0879a2b7..4f662c4f6d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -9,6 +9,7 @@ obj-y += nxp/ obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_ATH79) += ath79/ +obj-$(CONFIG_PINCTRL_INTEL) += intel/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig new file mode 100644 index 0000000000..e62a2e0349 --- /dev/null +++ b/drivers/pinctrl/intel/Kconfig @@ -0,0 +1,26 @@ +# +# Intel PINCTRL drivers +# + +if PINCTRL_INTEL + +config INTEL_PINCTRL_DUAL_ROUTE_SUPPORT + bool + default y + +config INTEL_PINCTRL_PADCFG_PADTOL + bool n + +config INTEL_PINCTRL_IOSTANDBY + bool + default y + +config PINCTRL_INTEL_APL + bool "Support Intel Apollo Lake (APL)" + help + Add support for Intel Apollo Lake pin-control and pin-mux settings. + These are mostly read from the device tree, with the early-pads + property in the host bridge and the pads property in the fsp-s + subnode of the host bridge. + +endif diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile new file mode 100644 index 0000000000..3aed8e9663 --- /dev/null +++ b/drivers/pinctrl/intel/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC + +obj-y += pinctrl.o +obj-$(CONFIG_PINCTRL_INTEL_APL) += pinctrl_apl.o diff --git a/drivers/pinctrl/intel/pinctrl.c b/drivers/pinctrl/intel/pinctrl.c new file mode 100644 index 0000000000..4875a3b0b5 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl.c @@ -0,0 +1,636 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Intel Corp. + * Copyright 2019 Google LLC + * + * Taken partly from coreboot gpio.c + * + * Pinctrl is modelled as a separate device-tree node and device for each + * 'community' (basically a set of GPIOs). The separate devices work together + * and many functions permit any PINCTRL device to be provided as a parameter, + * since the pad numbering is unique across all devices. + * + * Each pinctrl has a single child GPIO device to handle GPIO access and + * therefore there is a simple GPIO driver included in this file. + */ + +#define LOG_CATEGORY UCLASS_GPIO + +#include <common.h> +#include <dm.h> +#include <irq.h> +#include <p2sb.h> +#include <spl.h> +#include <asm-generic/gpio.h> +#include <asm/intel_pinctrl.h> +#include <asm/intel_pinctrl_defs.h> +#include <asm/arch/gpio.h> +#include <asm/arch/itss.h> +#include <dm/device-internal.h> +#include <dt-bindings/gpio/gpio.h> + +#define GPIO_DW_SIZE(x) (sizeof(u32) * (x)) +#define PAD_CFG_OFFSET(x, dw_num) ((x) + GPIO_DW_SIZE(dw_num)) +#define PAD_CFG0_OFFSET(x) PAD_CFG_OFFSET(x, 0) +#define PAD_CFG1_OFFSET(x) PAD_CFG_OFFSET(x, 1) + +#define MISCCFG_GPE0_DW0_SHIFT 8 +#define MISCCFG_GPE0_DW0_MASK (0xf << MISCCFG_GPE0_DW0_SHIFT) +#define MISCCFG_GPE0_DW1_SHIFT 12 +#define MISCCFG_GPE0_DW1_MASK (0xf << MISCCFG_GPE0_DW1_SHIFT) +#define MISCCFG_GPE0_DW2_SHIFT 16 +#define MISCCFG_GPE0_DW2_MASK (0xf << MISCCFG_GPE0_DW2_SHIFT) + +#define GPI_SMI_STS_OFFSET(comm, group) ((comm)->gpi_smi_sts_reg_0 + \ + ((group) * sizeof(u32))) +#define GPI_SMI_EN_OFFSET(comm, group) ((comm)->gpi_smi_en_reg_0 + \ + ((group) * sizeof(u32))) +#define GPI_IS_OFFSET(comm, group) ((comm)->gpi_int_sts_reg_0 + \ + ((group) * sizeof(uint32_t))) +#define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \ + ((group) * sizeof(uint32_t))) + +/** + * relative_pad_in_comm() - Get the relative position of a GPIO + * + * This finds the position of a GPIO within a community + * + * @comm: Community to search + * @gpio: Pad number to look up (assumed to be valid) + * @return offset, 0 for first GPIO in community + */ +static size_t relative_pad_in_comm(const struct pad_community *comm, + uint gpio) +{ + return gpio - comm->first_pad; +} + +/** + * pinctrl_group_index() - Find group for a a pad + * + * Find the group within the community that the pad is a part of + * + * @comm: Community to search + * @relative_pad: Pad to look up + * @return group number if found (see community_n_groups, etc.), or + * -ESPIPE if no groups, or -ENOENT if not found + */ +static int pinctrl_group_index(const struct pad_community *comm, + uint relative_pad) +{ + int i; + + if (!comm->groups) + return -ESPIPE; + + /* find the base pad number for this pad's group */ + for (i = 0; i < comm->num_groups; i++) { + if (relative_pad >= comm->groups[i].first_pad && + relative_pad < comm->groups[i].first_pad + + comm->groups[i].size) + return i; + } + + return -ENOENT; +} + +static int pinctrl_group_index_scaled(const struct pad_community *comm, + uint relative_pad, size_t scale) +{ + int ret; + + ret = pinctrl_group_index(comm, relative_pad); + if (ret < 0) + return ret; + + return ret * scale; +} + +static int pinctrl_within_group(const struct pad_community *comm, + uint relative_pad) +{ + int ret; + + ret = pinctrl_group_index(comm, relative_pad); + if (ret < 0) + return ret; + + return relative_pad - comm->groups[ret].first_pad; +} + +static u32 pinctrl_bitmask_within_group(const struct pad_community *comm, + uint relative_pad) +{ + return 1U << pinctrl_within_group(comm, relative_pad); +} + +/** + * pinctrl_get_device() - Find the device for a particular pad + * + * Each pinctr, device is attached to one community and this supports a number + * of pads. This function finds the device which controls a particular pad. + * + * @pad: Pad to check + * @devp: Returns the device for that pad + * @return 0 if OK, -ENOTBLK if no device was found for the given pin + */ +static int pinctrl_get_device(uint pad, struct udevice **devp) +{ + struct udevice *dev; + + /* + * We have to probe each one of these since the community link is only + * attached in intel_pinctrl_ofdata_to_platdata(). + */ + uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const struct pad_community *comm = priv->comm; + + if (pad >= comm->first_pad && pad <= comm->last_pad) { + *devp = dev; + return 0; + } + } + printf("pad %d not found\n", pad); + + return -ENOTBLK; +} + +int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp) +{ + const struct pad_community *comm; + struct intel_pinctrl_priv *priv; + struct udevice *dev; + int ret; + + ret = pinctrl_get_device(pad, &dev); + if (ret) + return log_msg_ret("pad", ret); + priv = dev_get_priv(dev); + comm = priv->comm; + *devp = dev; + *offsetp = relative_pad_in_comm(comm, pad); + + return 0; +} + +static int pinctrl_configure_owner(struct udevice *dev, + const struct pad_config *cfg, + const struct pad_community *comm) +{ + u32 hostsw_own; + u16 hostsw_own_offset; + int pin; + int ret; + + pin = relative_pad_in_comm(comm, cfg->pad); + + /* + * Based on the gpio pin number configure the corresponding bit in + * HOSTSW_OWN register. Value of 0x1 indicates GPIO Driver onwership. + */ + hostsw_own_offset = comm->host_own_reg_0; + ret = pinctrl_group_index_scaled(comm, pin, sizeof(u32)); + if (ret < 0) + return ret; + hostsw_own_offset += ret; + + hostsw_own = pcr_read32(dev, hostsw_own_offset); + + /* + *The 4th bit in pad_config 1 (RO) is used to indicate if the pad + * needs GPIO driver ownership. Set the bit if GPIO driver ownership + * requested, otherwise clear the bit. + */ + if (cfg->pad_config[1] & PAD_CFG1_GPIO_DRIVER) + hostsw_own |= pinctrl_bitmask_within_group(comm, pin); + else + hostsw_own &= ~pinctrl_bitmask_within_group(comm, pin); + + pcr_write32(dev, hostsw_own_offset, hostsw_own); + + return 0; +} + +static int gpi_enable_smi(struct udevice *dev, const struct pad_config *cfg, + const struct pad_community *comm) +{ + u32 value; + u16 sts_reg; + u16 en_reg; + int group; + int pin; + int ret; + + if ((cfg->pad_config[0] & PAD_CFG0_ROUTE_SMI) != PAD_CFG0_ROUTE_SMI) + return 0; + + pin = relative_pad_in_comm(comm, cfg->pad); + ret = pinctrl_group_index(comm, pin); + if (ret < 0) + return ret; + group = ret; + + sts_reg = GPI_SMI_STS_OFFSET(comm, group); + value = pcr_read32(dev, sts_reg); + /* Write back 1 to reset the sts bits */ + pcr_write32(dev, sts_reg, value); + + /* Set enable bits */ + en_reg = GPI_SMI_EN_OFFSET(comm, group); + pcr_setbits32(dev, en_reg, pinctrl_bitmask_within_group(comm, pin)); + + return 0; +} + +static int pinctrl_configure_itss(struct udevice *dev, + const struct pad_config *cfg, + uint pad_cfg_offset) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + + if (!priv->itss_pol_cfg) + return -ENOSYS; + + int irq; + + /* + * Set up ITSS polarity if pad is routed to APIC. + * + * The ITSS takes only active high interrupt signals. Therefore, + * if the pad configuration indicates an inversion assume the + * intent is for the ITSS polarity. Before forwarding on the + * request to the APIC there's an inversion setting for how the + * signal is forwarded to the APIC. Honor the inversion setting + * in the GPIO pad configuration so that a hardware active low + * signal looks that way to the APIC (double inversion). + */ + if (!(cfg->pad_config[0] & PAD_CFG0_ROUTE_IOAPIC)) + return 0; + + irq = pcr_read32(dev, PAD_CFG1_OFFSET(pad_cfg_offset)); + irq &= PAD_CFG1_IRQ_MASK; + if (!irq) { + log_err("GPIO %u doesn't support APIC routing\n", cfg->pad); + + return -EPROTONOSUPPORT; + } + irq_set_polarity(priv->itss, irq, + cfg->pad_config[0] & PAD_CFG0_RX_POL_INVERT); + + return 0; +} + +/* Number of DWx config registers can be different for different SOCs */ +static uint pad_config_offset(struct intel_pinctrl_priv *priv, uint pad) +{ + const struct pad_community *comm = priv->comm; + size_t offset; + + offset = relative_pad_in_comm(comm, pad); + offset *= GPIO_DW_SIZE(priv->num_cfgs); + + return offset + comm->pad_cfg_base; +} + +static int pinctrl_pad_reset_config_override(const struct pad_community *comm, + u32 config_value) +{ + const struct reset_mapping *rst_map = comm->reset_map; + int i; + + /* Logical reset values equal chipset values */ + if (!rst_map || !comm->num_reset_vals) + return config_value; + + for (i = 0; i < comm->num_reset_vals; i++, rst_map++) { + if ((config_value & PAD_CFG0_RESET_MASK) == rst_map->logical) { + config_value &= ~PAD_CFG0_RESET_MASK; + config_value |= rst_map->chipset; + + return config_value; + } + } + log_err("Logical-to-Chipset mapping not found\n"); + + return -ENOENT; +} + +static const int mask[4] = { + PAD_CFG0_TX_STATE | + PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE | PAD_CFG0_MODE_MASK | + PAD_CFG0_ROUTE_MASK | PAD_CFG0_RXTENCFG_MASK | + PAD_CFG0_RXINV_MASK | PAD_CFG0_PREGFRXSEL | + PAD_CFG0_TRIG_MASK | PAD_CFG0_RXRAW1_MASK | + PAD_CFG0_RXPADSTSEL_MASK | PAD_CFG0_RESET_MASK, + +#ifdef CONFIG_INTEL_PINCTRL_IOSTANDBY + PAD_CFG1_IOSTERM_MASK | PAD_CFG1_PULL_MASK | PAD_CFG1_IOSSTATE_MASK, +#else + PAD_CFG1_IOSTERM_MASK | PAD_CFG1_PULL_MASK, +#endif + + PAD_CFG2_DEBOUNCE_MASK, + + 0, +}; + +/** + * pinctrl_configure_pad() - Configure a pad + * + * @dev: Pinctrl device containing the pad (see pinctrl_get_device()) + * @cfg: Configuration to apply + * @return 0 if OK, -ve on error + */ +static int pinctrl_configure_pad(struct udevice *dev, + const struct pad_config *cfg) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const struct pad_community *comm = priv->comm; + uint config_offset; + u32 pad_conf, soc_pad_conf; + int ret; + int i; + + if (IS_ERR(comm)) + return PTR_ERR(comm); + config_offset = pad_config_offset(priv, cfg->pad); + for (i = 0; i < priv->num_cfgs; i++) { + pad_conf = pcr_read32(dev, PAD_CFG_OFFSET(config_offset, i)); + + soc_pad_conf = cfg->pad_config[i]; + if (i == 0) { + ret = pinctrl_pad_reset_config_override(comm, + soc_pad_conf); + if (ret < 0) + return ret; + soc_pad_conf = ret; + } + soc_pad_conf &= mask[i]; + soc_pad_conf |= pad_conf & ~mask[i]; + + log_debug("pinctrl_padcfg [0x%02x, %02zd] DW%d [0x%08x : 0x%08x : 0x%08x]\n", + comm->port, relative_pad_in_comm(comm, cfg->pad), i, + pad_conf,/* old value */ + /* value passed from pinctrl table */ + cfg->pad_config[i], + soc_pad_conf); /*new value*/ + pcr_write32(dev, PAD_CFG_OFFSET(config_offset, i), + soc_pad_conf); + } + ret = pinctrl_configure_itss(dev, cfg, config_offset); + if (ret && ret != -ENOSYS) + return log_msg_ret("itss config failed", ret); + ret = pinctrl_configure_owner(dev, cfg, comm); + if (ret) + return ret; + ret = gpi_enable_smi(dev, cfg, comm); + if (ret) + return ret; + + return 0; +} + +u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const struct pad_community *comm = priv->comm; + uint config_offset; + + assert(device_get_uclass_id(dev) == UCLASS_PINCTRL); + config_offset = comm->pad_cfg_base + offset * + GPIO_DW_SIZE(priv->num_cfgs); + + return config_offset; +} + +u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint offset) +{ + uint config_offset = intel_pinctrl_get_config_reg_addr(dev, offset); + + return pcr_read32(dev, config_offset); +} + +int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint offset) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const struct pad_community *comm = priv->comm; + int group; + + group = pinctrl_group_index(comm, offset); + + /* If pad base is not set then use GPIO number as ACPI pin number */ + if (comm->groups[group].acpi_pad_base == PAD_BASE_NONE) + return comm->first_pad + offset; + + /* + * If this group has a non-zero pad base then compute the ACPI pin + * number from the pad base and the relative pad in the group. + */ + return comm->groups[group].acpi_pad_base + + pinctrl_within_group(comm, offset); +} + +int pinctrl_route_gpe(struct udevice *itss, uint gpe0b, uint gpe0c, uint gpe0d) +{ + struct udevice *pinctrl_dev; + u32 misccfg_value; + u32 misccfg_clr; + int ret; + + /* + * Get the group here for community specific MISCCFG register. + * If any of these returns -1 then there is some error in devicetree + * where the group is probably hardcoded and does not comply with the + * PMC group defines. So we return from here and MISCFG is set to + * default. + */ + ret = irq_route_pmc_gpio_gpe(itss, gpe0b); + if (ret) + return ret; + gpe0b = ret; + + ret = irq_route_pmc_gpio_gpe(itss, gpe0c); + if (ret) + return ret; + gpe0c = ret; + + ret = irq_route_pmc_gpio_gpe(itss, gpe0d); + if (ret) + return ret; + gpe0d = ret; + + misccfg_value = gpe0b << MISCCFG_GPE0_DW0_SHIFT; + misccfg_value |= gpe0c << MISCCFG_GPE0_DW1_SHIFT; + misccfg_value |= gpe0d << MISCCFG_GPE0_DW2_SHIFT; + + /* Program GPIO_MISCCFG */ + misccfg_clr = MISCCFG_GPE0_DW2_MASK | MISCCFG_GPE0_DW1_MASK | + MISCCFG_GPE0_DW0_MASK; + + log_debug("misccfg_clr:%x misccfg_value:%x\n", misccfg_clr, + misccfg_value); + uclass_foreach_dev_probe(UCLASS_PINCTRL, pinctrl_dev) { + pcr_clrsetbits32(pinctrl_dev, GPIO_MISCCFG, misccfg_clr, + misccfg_value); + } + + return 0; +} + +int pinctrl_gpi_clear_int_cfg(void) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_PINCTRL, &uc); + if (ret) + return log_msg_ret("pinctrl uc", ret); + uclass_foreach_dev(dev, uc) { + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const struct pad_community *comm = priv->comm; + uint sts_value; + int group; + + for (group = 0; group < comm->num_gpi_regs; group++) { + /* Clear the enable register */ + pcr_write32(dev, GPI_IE_OFFSET(comm, group), 0); + + /* Read and clear the set status register bits*/ + sts_value = pcr_read32(dev, + GPI_IS_OFFSET(comm, group)); + pcr_write32(dev, GPI_IS_OFFSET(comm, group), sts_value); + } + } + + return 0; +} + +int pinctrl_config_pads(struct udevice *dev, u32 *pads, int pads_count) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + const u32 *ptr; + int i; + + log_debug("%s: pads_count=%d\n", __func__, pads_count); + for (ptr = pads, i = 0; i < pads_count; + ptr += 1 + priv->num_cfgs, i++) { + struct udevice *pad_dev = NULL; + struct pad_config *cfg; + int ret; + + cfg = (struct pad_config *)ptr; + ret = pinctrl_get_device(cfg->pad, &pad_dev); + if (ret) + return ret; + ret = pinctrl_configure_pad(pad_dev, cfg); + if (ret) + return ret; + } + + return 0; +} + +int pinctrl_read_pads(struct udevice *dev, ofnode node, const char *prop, + u32 **padsp, int *pad_countp) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + u32 *pads; + int size; + int ret; + + *padsp = NULL; + *pad_countp = 0; + size = ofnode_read_size(node, prop); + if (size < 0) + return 0; + + pads = malloc(size); + if (!pads) + return -ENOMEM; + size /= sizeof(fdt32_t); + ret = ofnode_read_u32_array(node, prop, pads, size); + if (ret) { + free(pads); + return ret; + } + *pad_countp = size / (1 + priv->num_cfgs); + *padsp = pads; + + return 0; +} + +int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + int count = 0; + int i; + + for (i = 0; i < size;) { + u32 val; + int j; + + for (val = j = 0; j < priv->num_cfgs + 1; j++) + val |= pads[i + j]; + if (!val) + break; + count++; + i += priv->num_cfgs + 1; + } + + return count; +} + +int pinctrl_config_pads_for_node(struct udevice *dev, ofnode node) +{ + int pads_count; + u32 *pads; + int ret; + + if (device_get_uclass_id(dev) != UCLASS_PINCTRL) + return log_msg_ret("uclass", -EPROTONOSUPPORT); + ret = pinctrl_read_pads(dev, node, "pads", &pads, &pads_count); + if (ret) + return log_msg_ret("no pads", ret); + ret = pinctrl_config_pads(dev, pads, pads_count); + free(pads); + if (ret) + return log_msg_ret("pad config", ret); + + return 0; +} + +int intel_pinctrl_ofdata_to_platdata(struct udevice *dev, + const struct pad_community *comm, + int num_cfgs) +{ + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev); + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + int ret; + + if (!comm) { + log_err("Cannot find community for pid %d\n", pplat->pid); + return -EDOM; + } + ret = uclass_first_device_err(UCLASS_IRQ, &priv->itss); + if (ret) + return log_msg_ret("Cannot find ITSS", ret); + priv->comm = comm; + priv->num_cfgs = num_cfgs; + + return 0; +} + +int intel_pinctrl_probe(struct udevice *dev) +{ + struct intel_pinctrl_priv *priv = dev_get_priv(dev); + + priv->itss_pol_cfg = true; + + return 0; +} + +const struct pinctrl_ops intel_pinctrl_ops = { + /* No operations are supported, but DM expects this to be present */ +}; diff --git a/drivers/pinctrl/intel/pinctrl_apl.c b/drivers/pinctrl/intel/pinctrl_apl.c new file mode 100644 index 0000000000..bd80435ffa --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl_apl.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 Intel Corp. + * Copyright 2019 Google LLC + * + * Taken partly from coreboot gpio.c + */ + +#define LOG_CATEGORY UCLASS_GPIO + +#include <common.h> +#include <dm.h> +#include <dt-structs.h> +#include <p2sb.h> +#include <asm/intel_pinctrl.h> +#include <asm-generic/gpio.h> +#include <asm/intel_pinctrl_defs.h> + +/** + * struct apl_gpio_platdata - platform data for each device + * + * @dtplat: of-platdata data from C struct + */ +struct apl_gpio_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + /* Put this first since driver model will copy the data here */ + struct dtd_intel_apl_pinctrl dtplat; +#endif +}; + +static const struct reset_mapping rst_map[] = { + { .logical = PAD_CFG0_LOGICAL_RESET_PWROK, .chipset = 0U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30 }, +}; + +/* Groups for each community */ +static const struct pad_group apl_community_n_groups[] = { + INTEL_GPP(N_OFFSET, N_OFFSET, GPIO_31), /* NORTH 0 */ + INTEL_GPP(N_OFFSET, GPIO_32, JTAG_TRST_B), /* NORTH 1 */ + INTEL_GPP(N_OFFSET, JTAG_TMS, SVID0_CLK), /* NORTH 2 */ +}; + +static const struct pad_group apl_community_w_groups[] = { + INTEL_GPP(W_OFFSET, W_OFFSET, OSC_CLK_OUT_1), /* WEST 0 */ + INTEL_GPP(W_OFFSET, OSC_CLK_OUT_2, SUSPWRDNACK),/* WEST 1 */ +}; + +static const struct pad_group apl_community_sw_groups[] = { + INTEL_GPP(SW_OFFSET, SW_OFFSET, SMB_ALERTB), /* SOUTHWEST 0 */ + INTEL_GPP(SW_OFFSET, SMB_CLK, LPC_FRAMEB), /* SOUTHWEST 1 */ +}; + +static const struct pad_group apl_community_nw_groups[] = { + INTEL_GPP(NW_OFFSET, NW_OFFSET, PROCHOT_B), /* NORTHWEST 0 */ + INTEL_GPP(NW_OFFSET, PMIC_I2C_SCL, GPIO_106), /* NORTHWEST 1 */ + INTEL_GPP(NW_OFFSET, GPIO_109, GPIO_123), /* NORTHWEST 2 */ +}; + +/* TODO(sjg@chromium.org): Consider moving this to device tree */ +static const struct pad_community apl_gpio_communities[] = { + { + .port = PID_GPIO_N, + .first_pad = N_OFFSET, + .last_pad = SVID0_CLK, + .num_gpi_regs = NUM_N_GPI_REGS, + .gpi_status_offset = NUM_NW_GPI_REGS + NUM_W_GPI_REGS + + NUM_SW_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPIO_GPE_N", + .acpi_path = "\\_SB.GPO0", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = apl_community_n_groups, + .num_groups = ARRAY_SIZE(apl_community_n_groups), + }, { + .port = PID_GPIO_NW, + .first_pad = NW_OFFSET, + .last_pad = GPIO_123, + .num_gpi_regs = NUM_NW_GPI_REGS, + .gpi_status_offset = NUM_W_GPI_REGS + NUM_SW_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPIO_GPE_NW", + .acpi_path = "\\_SB.GPO1", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = apl_community_nw_groups, + .num_groups = ARRAY_SIZE(apl_community_nw_groups), + }, { + .port = PID_GPIO_W, + .first_pad = W_OFFSET, + .last_pad = SUSPWRDNACK, + .num_gpi_regs = NUM_W_GPI_REGS, + .gpi_status_offset = NUM_SW_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPIO_GPE_W", + .acpi_path = "\\_SB.GPO2", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = apl_community_w_groups, + .num_groups = ARRAY_SIZE(apl_community_w_groups), + }, { + .port = PID_GPIO_SW, + .first_pad = SW_OFFSET, + .last_pad = LPC_FRAMEB, + .num_gpi_regs = NUM_SW_GPI_REGS, + .gpi_status_offset = 0, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPIO_GPE_SW", + .acpi_path = "\\_SB.GPO3", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = apl_community_sw_groups, + .num_groups = ARRAY_SIZE(apl_community_sw_groups), + }, +}; + +static int apl_pinctrl_ofdata_to_platdata(struct udevice *dev) +{ + struct p2sb_child_platdata *pplat; + const struct pad_community *comm = NULL; + int i; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct apl_gpio_platdata *plat = dev_get_platdata(dev); + int ret; + + /* + * It would be nice to do this in the bind() method, but with + * of-platdata binding happens in the order that DM finds things in the + * linker list (i.e. alphabetical order by driver name). So the GPIO + * device may well be bound before its parent (p2sb), and this call + * will fail if p2sb is not bound yet. + * + * TODO(sjg@chromium.org): Add a parent pointer to child devices in dtoc + */ + ret = p2sb_set_port_id(dev, plat->dtplat.intel_p2sb_port_id); + if (ret) + return log_msg_ret("Could not set port id", ret); +#endif + /* Attach this device to its community structure */ + pplat = dev_get_parent_platdata(dev); + for (i = 0; i < ARRAY_SIZE(apl_gpio_communities); i++) { + if (apl_gpio_communities[i].port == pplat->pid) + comm = &apl_gpio_communities[i]; + } + + return intel_pinctrl_ofdata_to_platdata(dev, comm, 2); +} + +static const struct udevice_id apl_gpio_ids[] = { + { .compatible = "intel,apl-pinctrl"}, + { } +}; + +U_BOOT_DRIVER(apl_pinctrl_drv) = { + .name = "intel_apl_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = apl_gpio_ids, + .probe = intel_pinctrl_probe, + .ops = &intel_pinctrl_ops, +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + .bind = dm_scan_fdt_dev, +#endif + .ofdata_to_platdata = apl_pinctrl_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct intel_pinctrl_priv), + .platdata_auto_alloc_size = sizeof(struct apl_gpio_platdata), +}; diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 9495dca33b..cb2c6fe3eb 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -1,5 +1,7 @@ menu "Power" +source "drivers/power/acpi_pmc/Kconfig" + source "drivers/power/domain/Kconfig" source "drivers/power/pmic/Kconfig" diff --git a/drivers/power/acpi_pmc/Kconfig b/drivers/power/acpi_pmc/Kconfig new file mode 100644 index 0000000000..fcd50e36ca --- /dev/null +++ b/drivers/power/acpi_pmc/Kconfig @@ -0,0 +1,34 @@ +config ACPI_PMC + bool "Power Manager (x86 PMC) support" + help + Enable support for an x86-style power-management controller which + provides features including checking whether the system started from + resume, powering off the system and enabling/disabling the reset + mechanism. + +config SPL_ACPI_PMC + bool "Power Manager (x86 PMC) support in SPL" + default y if ACPI_PMC + help + Enable support for an x86-style power-management controller which + provides features including checking whether the system started from + resume, powering off the system and enabling/disabling the reset + mechanism. + +config TPL_ACPI_PMC + bool "Power Manager (x86 PMC) support in TPL" + default y if ACPI_PMC + help + Enable support for an x86-style power-management controller which + provides features including checking whether the system started from + resume, powering off the system and enabling/disabling the reset + mechanism. + +config ACPI_PMC_SANDBOX + bool "Test power manager (PMC) for sandbox" + depends on ACPI_PMC && SANDBOX + help + This driver emulates a PMC (Power-Management Controller) so that + the uclass logic can be tested. You can use the 'pmc' command to + access information from the driver. It uses I/O access to read + from the PMC. diff --git a/drivers/power/acpi_pmc/Makefile b/drivers/power/acpi_pmc/Makefile new file mode 100644 index 0000000000..115788f109 --- /dev/null +++ b/drivers/power/acpi_pmc/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Google LLC + +obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC) += acpi-pmc-uclass.o +obj-$(CONFIG_$(SPL_TPL_)ACPI_PMC_SANDBOX) += sandbox.o pmc_emul.o diff --git a/drivers/power/acpi_pmc/acpi-pmc-uclass.c b/drivers/power/acpi_pmc/acpi-pmc-uclass.c new file mode 100644 index 0000000000..d43de87126 --- /dev/null +++ b/drivers/power/acpi_pmc/acpi-pmc-uclass.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#define LOG_CATEGORY UCLASS_ACPI_PMC + +#include <common.h> +#include <acpi_s3.h> +#include <dm.h> +#include <log.h> +#ifdef CONFIG_X86 +#include <asm/intel_pinctrl.h> +#endif +#include <asm/io.h> +#include <power/acpi_pmc.h> + +enum { + PM1_STS = 0x00, + PM1_EN = 0x02, + PM1_CNT = 0x04, + + GPE0_STS = 0x20, + GPE0_EN = 0x30, +}; + +struct tco_regs { + u32 tco_rld; + u32 tco_sts; + u32 tco1_cnt; + u32 tco_tmr; +}; + +enum { + TCO_STS_TIMEOUT = 1 << 3, + TCO_STS_SECOND_TO_STS = 1 << 17, + TCO1_CNT_HLT = 1 << 11, +}; + +#ifdef CONFIG_X86 +static int gpe0_shift(struct acpi_pmc_upriv *upriv, int regnum) +{ + return upriv->gpe0_dwx_shift_base + regnum * 4; +} + +int pmc_gpe_init(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + struct udevice *itss; + u32 *dw; + u32 gpio_cfg_mask; + u32 gpio_cfg; + int ret, i; + u32 mask; + + if (device_get_uclass_id(dev) != UCLASS_ACPI_PMC) + return log_msg_ret("uclass", -EPROTONOSUPPORT); + dw = upriv->gpe0_dw; + mask = upriv->gpe0_dwx_mask; + gpio_cfg_mask = 0; + for (i = 0; i < upriv->gpe0_count; i++) { + gpio_cfg_mask |= mask << gpe0_shift(upriv, i); + if (dw[i] & ~mask) + return log_msg_ret("Base GPE0 value", -EINVAL); + } + + /* + * Route the GPIOs to the GPE0 block. Determine that all values + * are different and if they aren't, use the reset values. + */ + if (dw[0] == dw[1] || dw[1] == dw[2]) { + log_info("PMC: Using default GPE route"); + gpio_cfg = readl(upriv->gpe_cfg); + for (i = 0; i < upriv->gpe0_count; i++) + dw[i] = gpio_cfg >> gpe0_shift(upriv, i); + } else { + gpio_cfg = 0; + for (i = 0; i < upriv->gpe0_count; i++) + gpio_cfg |= dw[i] << gpe0_shift(upriv, i); + clrsetbits_le32(upriv->gpe_cfg, gpio_cfg_mask, gpio_cfg); + } + + /* Set the routes in the GPIO communities as well */ + ret = uclass_first_device_err(UCLASS_IRQ, &itss); + if (ret) + return log_msg_ret("Cannot find itss", ret); + pinctrl_route_gpe(itss, dw[0], dw[1], dw[2]); + + return 0; +} +#endif /* CONFIG_X86 */ + +static void pmc_fill_pm_reg_info(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + int i; + + upriv->pm1_sts = inw(upriv->acpi_base + PM1_STS); + upriv->pm1_en = inw(upriv->acpi_base + PM1_EN); + upriv->pm1_cnt = inw(upriv->acpi_base + PM1_CNT); + + log_debug("pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n", + upriv->pm1_sts, upriv->pm1_en, upriv->pm1_cnt); + + for (i = 0; i < GPE0_REG_MAX; i++) { + upriv->gpe0_sts[i] = inl(upriv->acpi_base + GPE0_STS + i * 4); + upriv->gpe0_en[i] = inl(upriv->acpi_base + GPE0_EN + i * 4); + log_debug("gpe0_sts[%d]: %08x gpe0_en[%d]: %08x\n", i, + upriv->gpe0_sts[i], i, upriv->gpe0_en[i]); + } +} + +int pmc_disable_tco_base(ulong tco_base) +{ + struct tco_regs *regs = (struct tco_regs *)tco_base; + + debug("tco_base %lx = %x\n", (ulong)®s->tco1_cnt, TCO1_CNT_HLT); + setio_32(®s->tco1_cnt, TCO1_CNT_HLT); + + return 0; +} + +int pmc_init(struct udevice *dev) +{ + const struct acpi_pmc_ops *ops = acpi_pmc_get_ops(dev); + int ret; + + pmc_fill_pm_reg_info(dev); + if (!ops->init) + return -ENOSYS; + + ret = ops->init(dev); + if (ret) + return log_msg_ret("Failed to init pmc", ret); + +#ifdef DEBUG + pmc_dump_info(dev); +#endif + + return 0; +} + +int pmc_prev_sleep_state(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + const struct acpi_pmc_ops *ops = acpi_pmc_get_ops(dev); + int prev_sleep_state = ACPI_S0; /* Default to S0 */ + + if (upriv->pm1_sts & WAK_STS) { + switch (acpi_sleep_from_pm1(upriv->pm1_cnt)) { + case ACPI_S3: + if (IS_ENABLED(HAVE_ACPI_RESUME)) + prev_sleep_state = ACPI_S3; + break; + case ACPI_S5: + prev_sleep_state = ACPI_S5; + break; + default: + break; + } + + /* Clear SLP_TYP */ + outl(upriv->pm1_cnt & ~SLP_TYP, upriv->acpi_base + PM1_CNT); + } + + if (!ops->prev_sleep_state) + return prev_sleep_state; + + return ops->prev_sleep_state(dev, prev_sleep_state); +} + +int pmc_disable_tco(struct udevice *dev) +{ + const struct acpi_pmc_ops *ops = acpi_pmc_get_ops(dev); + + pmc_fill_pm_reg_info(dev); + if (!ops->disable_tco) + return -ENOSYS; + + return ops->disable_tco(dev); +} + +int pmc_global_reset_set_enable(struct udevice *dev, bool enable) +{ + const struct acpi_pmc_ops *ops = acpi_pmc_get_ops(dev); + + if (!ops->global_reset_set_enable) + return -ENOSYS; + + return ops->global_reset_set_enable(dev, enable); +} + +void pmc_dump_info(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + int i; + + printf("Device: %s\n", dev->name); + printf("ACPI base %x, pmc_bar0 %p, pmc_bar2 %p, gpe_cfg %p\n", + upriv->acpi_base, upriv->pmc_bar0, upriv->pmc_bar2, + upriv->gpe_cfg); + printf("pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n", + upriv->pm1_sts, upriv->pm1_en, upriv->pm1_cnt); + + for (i = 0; i < GPE0_REG_MAX; i++) { + printf("gpe0_sts[%d]: %08x gpe0_en[%d]: %08x\n", i, + upriv->gpe0_sts[i], i, upriv->gpe0_en[i]); + } + + printf("prsts: %08x\n", upriv->prsts); + printf("tco_sts: %04x %04x\n", upriv->tco1_sts, upriv->tco2_sts); + printf("gen_pmcon1: %08x gen_pmcon2: %08x gen_pmcon3: %08x\n", + upriv->gen_pmcon1, upriv->gen_pmcon2, upriv->gen_pmcon3); +} + +int pmc_ofdata_to_uc_platdata(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + int ret; + + ret = dev_read_u32(dev, "gpe0-dwx-mask", &upriv->gpe0_dwx_mask); + if (ret) + return log_msg_ret("no gpe0-dwx-mask", ret); + ret = dev_read_u32(dev, "gpe0-dwx-shift-base", + &upriv->gpe0_dwx_shift_base); + if (ret) + return log_msg_ret("no gpe0-dwx-shift-base", ret); + ret = dev_read_u32(dev, "gpe0-sts", &upriv->gpe0_sts_reg); + if (ret) + return log_msg_ret("no gpe0-sts", ret); + upriv->gpe0_sts_reg += upriv->acpi_base; + ret = dev_read_u32(dev, "gpe0-en", &upriv->gpe0_en_reg); + if (ret) + return log_msg_ret("no gpe0-en", ret); + upriv->gpe0_en_reg += upriv->acpi_base; + + return 0; +} + +UCLASS_DRIVER(acpi_pmc) = { + .id = UCLASS_ACPI_PMC, + .name = "power-mgr", + .per_device_auto_alloc_size = sizeof(struct acpi_pmc_upriv), +}; diff --git a/drivers/power/acpi_pmc/pmc_emul.c b/drivers/power/acpi_pmc/pmc_emul.c new file mode 100644 index 0000000000..15cc7acaf3 --- /dev/null +++ b/drivers/power/acpi_pmc/pmc_emul.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * PCI emulation device for an x86 Power-Management Controller (PMC) + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/test.h> +#include <power/acpi_pmc.h> + +/** + * struct pmc_emul_platdata - platform data for this device + * + * @command: Current PCI command value + * @bar: Current base address values + */ +struct pmc_emul_platdata { + u16 command; + u32 bar[6]; +}; + +enum { + MEMMAP_SIZE = 0x80, +}; + +static struct pci_bar { + int type; + u32 size; +} barinfo[] = { + { PCI_BASE_ADDRESS_MEM_TYPE_32, MEMMAP_SIZE }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { PCI_BASE_ADDRESS_SPACE_IO, 256 }, +}; + +struct pmc_emul_priv { + u8 regs[MEMMAP_SIZE]; +}; + +static int sandbox_pmc_emul_read_config(struct udevice *emul, uint offset, + ulong *valuep, enum pci_size_t size) +{ + struct pmc_emul_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + *valuep = plat->command; + break; + case PCI_HEADER_TYPE: + *valuep = 0; + break; + case PCI_VENDOR_ID: + *valuep = SANDBOX_PCI_VENDOR_ID; + break; + case PCI_DEVICE_ID: + *valuep = SANDBOX_PCI_PMC_EMUL_ID; + break; + case PCI_CLASS_DEVICE: + if (size == PCI_SIZE_8) { + *valuep = SANDBOX_PCI_CLASS_SUB_CODE; + } else { + *valuep = (SANDBOX_PCI_CLASS_CODE << 8) | + SANDBOX_PCI_CLASS_SUB_CODE; + } + break; + case PCI_CLASS_CODE: + *valuep = SANDBOX_PCI_CLASS_CODE; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: + case PCI_BASE_ADDRESS_2: + case PCI_BASE_ADDRESS_3: + case PCI_BASE_ADDRESS_4: + case PCI_BASE_ADDRESS_5: { + int barnum; + u32 *bar; + + barnum = pci_offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + *valuep = sandbox_pci_read_bar(*bar, barinfo[barnum].type, + barinfo[barnum].size); + break; + } + case PCI_CAPABILITY_LIST: + *valuep = PCI_CAP_ID_PM_OFFSET; + break; + } + + return 0; +} + +static int sandbox_pmc_emul_write_config(struct udevice *emul, uint offset, + ulong value, enum pci_size_t size) +{ + struct pmc_emul_platdata *plat = dev_get_platdata(emul); + + switch (offset) { + case PCI_COMMAND: + plat->command = value; + break; + case PCI_BASE_ADDRESS_0: + case PCI_BASE_ADDRESS_1: { + int barnum; + u32 *bar; + + barnum = pci_offset_to_barnum(offset); + bar = &plat->bar[barnum]; + + debug("w bar %d=%lx\n", barnum, value); + *bar = value; + /* space indicator (bit#0) is read-only */ + *bar |= barinfo[barnum].type; + break; + } + } + + return 0; +} + +static int sandbox_pmc_emul_find_bar(struct udevice *emul, unsigned int addr, + int *barnump, unsigned int *offsetp) +{ + struct pmc_emul_platdata *plat = dev_get_platdata(emul); + int barnum; + + for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) { + unsigned int size = barinfo[barnum].size; + u32 base = plat->bar[barnum] & ~PCI_BASE_ADDRESS_SPACE; + + if (addr >= base && addr < base + size) { + *barnump = barnum; + *offsetp = addr - base; + return 0; + } + } + *barnump = -1; + + return -ENOENT; +} + +static int sandbox_pmc_emul_read_io(struct udevice *dev, unsigned int addr, + ulong *valuep, enum pci_size_t size) +{ + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_pmc_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + if (barnum == 4) + *valuep = offset; + else if (barnum == 0) + *valuep = offset; + + return 0; +} + +static int sandbox_pmc_emul_write_io(struct udevice *dev, unsigned int addr, + ulong value, enum pci_size_t size) +{ + unsigned int offset; + int barnum; + int ret; + + ret = sandbox_pmc_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + return 0; +} + +static int sandbox_pmc_emul_map_physmem(struct udevice *dev, + phys_addr_t addr, unsigned long *lenp, + void **ptrp) +{ + struct pmc_emul_priv *priv = dev_get_priv(dev); + unsigned int offset, avail; + int barnum; + int ret; + + ret = sandbox_pmc_emul_find_bar(dev, addr, &barnum, &offset); + if (ret) + return ret; + + if (barnum == 0) { + *ptrp = priv->regs + offset; + avail = barinfo[0].size - offset; + if (avail > barinfo[0].size) + *lenp = 0; + else + *lenp = min(*lenp, (ulong)avail); + + return 0; + } + + return -ENOENT; +} + +static int sandbox_pmc_probe(struct udevice *dev) +{ + struct pmc_emul_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < MEMMAP_SIZE; i++) + priv->regs[i] = i; + + return 0; +} + +static struct dm_pci_emul_ops sandbox_pmc_emul_emul_ops = { + .read_config = sandbox_pmc_emul_read_config, + .write_config = sandbox_pmc_emul_write_config, + .read_io = sandbox_pmc_emul_read_io, + .write_io = sandbox_pmc_emul_write_io, + .map_physmem = sandbox_pmc_emul_map_physmem, +}; + +static const struct udevice_id sandbox_pmc_emul_ids[] = { + { .compatible = "sandbox,pmc-emul" }, + { } +}; + +U_BOOT_DRIVER(sandbox_pmc_emul_emul) = { + .name = "sandbox_pmc_emul_emul", + .id = UCLASS_PCI_EMUL, + .of_match = sandbox_pmc_emul_ids, + .ops = &sandbox_pmc_emul_emul_ops, + .probe = sandbox_pmc_probe, + .priv_auto_alloc_size = sizeof(struct pmc_emul_priv), + .platdata_auto_alloc_size = sizeof(struct pmc_emul_platdata), +}; + +static struct pci_device_id sandbox_pmc_emul_supported[] = { + { PCI_VDEVICE(SANDBOX, SANDBOX_PCI_PMC_EMUL_ID) }, + {}, +}; + +U_BOOT_PCI_DEVICE(sandbox_pmc_emul_emul, sandbox_pmc_emul_supported); diff --git a/drivers/power/acpi_pmc/sandbox.c b/drivers/power/acpi_pmc/sandbox.c new file mode 100644 index 0000000000..7fbbf97b45 --- /dev/null +++ b/drivers/power/acpi_pmc/sandbox.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Sandbox PMC for testing + * + * Copyright 2019 Google LLC + */ + +#define LOG_CATEGORY UCLASS_ACPI_PMC + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <power/acpi_pmc.h> + +#define GPIO_GPE_CFG 0x1050 + +/* Memory mapped IO registers behind PMC_BASE_ADDRESS */ +#define PRSTS 0x1000 +#define GEN_PMCON1 0x1020 +#define GEN_PMCON2 0x1024 +#define GEN_PMCON3 0x1028 + +/* Offset of TCO registers from ACPI base I/O address */ +#define TCO_REG_OFFSET 0x60 +#define TCO1_STS 0x64 +#define TCO2_STS 0x66 +#define TCO1_CNT 0x68 +#define TCO2_CNT 0x6a + +struct sandbox_pmc_priv { + ulong base; +}; + +static int sandbox_pmc_fill_power_state(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + upriv->tco1_sts = inw(upriv->acpi_base + TCO1_STS); + upriv->tco2_sts = inw(upriv->acpi_base + TCO2_STS); + + upriv->prsts = readl(upriv->pmc_bar0 + PRSTS); + upriv->gen_pmcon1 = readl(upriv->pmc_bar0 + GEN_PMCON1); + upriv->gen_pmcon2 = readl(upriv->pmc_bar0 + GEN_PMCON2); + upriv->gen_pmcon3 = readl(upriv->pmc_bar0 + GEN_PMCON3); + + return 0; +} + +static int sandbox_prev_sleep_state(struct udevice *dev, int prev_sleep_state) +{ + return prev_sleep_state; +} + +static int sandbox_disable_tco(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + + pmc_disable_tco_base(upriv->acpi_base + TCO_REG_OFFSET); + + return 0; +} + +static int sandbox_pmc_probe(struct udevice *dev) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev); + struct udevice *bus; + ulong base; + + uclass_first_device(UCLASS_PCI, &bus); + base = dm_pci_read_bar32(dev, 0); + if (base == FDT_ADDR_T_NONE) + return log_msg_ret("No base address", -EINVAL); + upriv->pmc_bar0 = map_sysmem(base, 0x2000); + upriv->gpe_cfg = (u32 *)(upriv->pmc_bar0 + GPIO_GPE_CFG); + + return pmc_ofdata_to_uc_platdata(dev); +} + +static struct acpi_pmc_ops sandbox_pmc_ops = { + .init = sandbox_pmc_fill_power_state, + .prev_sleep_state = sandbox_prev_sleep_state, + .disable_tco = sandbox_disable_tco, +}; + +static const struct udevice_id sandbox_pmc_ids[] = { + { .compatible = "sandbox,pmc" }, + { } +}; + +U_BOOT_DRIVER(pmc_sandbox) = { + .name = "pmc_sandbox", + .id = UCLASS_ACPI_PMC, + .of_match = sandbox_pmc_ids, + .probe = sandbox_pmc_probe, + .ops = &sandbox_pmc_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_pmc_priv), +}; diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index 2f7bc24887..1af5cc12f3 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -33,7 +33,7 @@ DECLARE_GLOBAL_DATA_PTR; * serial_buf_write == serial_buf_read -> empty buffer * (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer */ -static char serial_buf[16]; +static unsigned char serial_buf[16]; static unsigned int serial_buf_write; static unsigned int serial_buf_read; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8588866489..fae2040af8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -142,7 +142,6 @@ config FSL_DSPI config ICH_SPI bool "Intel ICH SPI driver" - imply SPI_FLASH_BAR help Enable the Intel ICH SPI driver. This driver can be used to access the SPI NOR flash on platforms embedding this Intel diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index cf4de9ee1a..f076e92a93 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -17,7 +17,7 @@ #ifdef CONFIG_DM_SPI #include <asm/arch/at91_spi.h> #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif @@ -228,7 +228,7 @@ struct atmel_spi_priv { unsigned int freq; /* Default frequency */ unsigned int mode; ulong bus_clk_rate; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc cs_gpios[MAX_CS_COUNT]; #endif }; @@ -285,7 +285,7 @@ static int atmel_spi_release_bus(struct udevice *dev) static void atmel_spi_cs_activate(struct udevice *dev) { -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -300,7 +300,7 @@ static void atmel_spi_cs_activate(struct udevice *dev) static void atmel_spi_cs_deactivate(struct udevice *dev) { -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -468,7 +468,7 @@ static int atmel_spi_probe(struct udevice *bus) bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct atmel_spi_priv *priv = dev_get_priv(bus); int i; diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 91e613e9cd..66ff8eeccd 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -126,7 +126,7 @@ static inline void dw_write(struct dw_spi_priv *priv, u32 offset, u32 val) static int request_gpio_cs(struct udevice *bus) { -#if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_GPIO) && !defined(CONFIG_SPL_BUILD) struct dw_spi_priv *priv = dev_get_priv(bus); int ret; @@ -373,7 +373,7 @@ static int poll_transfer(struct dw_spi_priv *priv) */ __weak void external_cs_manage(struct udevice *dev, bool on) { -#if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_GPIO) && !defined(CONFIG_SPL_BUILD) struct dw_spi_priv *priv = dev_get_priv(dev->parent); if (!dm_gpio_is_valid(&priv->cs_gpio)) diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index fbb58c783e..133b25b72e 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -5,28 +5,45 @@ * This file is derived from the flashrom project. */ +#define LOG_CATEGORY UCLASS_SPI + #include <common.h> +#include <div64.h> #include <dm.h> +#include <dt-structs.h> #include <errno.h> #include <malloc.h> #include <pch.h> #include <pci.h> #include <pci_ids.h> #include <spi.h> -#include <asm/io.h> +#include <spi_flash.h> #include <spi-mem.h> -#include <div64.h> +#include <spl.h> +#include <asm/fast_spi.h> +#include <asm/io.h> +#include <asm/mtrr.h> +#include <linux/sizes.h> #include "ich.h" -DECLARE_GLOBAL_DATA_PTR; - #ifdef DEBUG_TRACE #define debug_trace(fmt, args...) debug(fmt, ##args) #else #define debug_trace(x, args...) #endif +struct ich_spi_platdata { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_intel_fast_spi dtplat; +#endif + enum ich_version ich_version; /* Controller version, 7 or 9 */ + bool lockdown; /* lock down controller settings? */ + ulong mmio_base; /* Base of MMIO registers */ + pci_dev_t bdf; /* PCI address used by of-platdata */ + bool hwseq; /* Use hardware sequencing (not s/w) */ +}; + static u8 ich_readb(struct ich_spi_priv *priv, int reg) { u8 value = readb(priv->base + reg); @@ -89,22 +106,27 @@ static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr) const uint32_t bbar_mask = 0x00ffff00; uint32_t ichspi_bbar; - minaddr &= bbar_mask; - ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - ich_writel(ctlr, ichspi_bbar, ctlr->bbar); + if (ctlr->bbar) { + minaddr &= bbar_mask; + ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; + ichspi_bbar |= minaddr; + ich_writel(ctlr, ichspi_bbar, ctlr->bbar); + } } /* @return 1 if the SPI flash supports the 33MHz speed */ -static int ich9_can_do_33mhz(struct udevice *dev) +static bool ich9_can_do_33mhz(struct udevice *dev) { + struct ich_spi_priv *priv = dev_get_priv(dev); u32 fdod, speed; + if (!CONFIG_IS_ENABLED(PCI)) + return false; /* Observe SPI Descriptor Component Section 0 */ - dm_pci_write_config32(dev->parent, 0xb0, 0x1000); + dm_pci_write_config32(priv->pch, 0xb0, 0x1000); /* Extract the Write/Erase SPI Frequency from descriptor */ - dm_pci_read_config32(dev->parent, 0xb4, &fdod); + dm_pci_read_config32(priv->pch, 0xb4, &fdod); /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */ speed = (fdod >> 21) & 7; @@ -112,67 +134,6 @@ static int ich9_can_do_33mhz(struct udevice *dev) return speed == 1; } -static int ich_init_controller(struct udevice *dev, - struct ich_spi_platdata *plat, - struct ich_spi_priv *ctlr) -{ - ulong sbase_addr; - void *sbase; - - /* SBASE is similar */ - pch_get_spi_base(dev->parent, &sbase_addr); - sbase = (void *)sbase_addr; - debug("%s: sbase=%p\n", __func__, sbase); - - if (plat->ich_version == ICHV_7) { - struct ich7_spi_regs *ich7_spi = sbase; - - ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); - ctlr->menubytes = sizeof(ich7_spi->opmenu); - ctlr->optype = offsetof(struct ich7_spi_regs, optype); - ctlr->addr = offsetof(struct ich7_spi_regs, spia); - ctlr->data = offsetof(struct ich7_spi_regs, spid); - ctlr->databytes = sizeof(ich7_spi->spid); - ctlr->status = offsetof(struct ich7_spi_regs, spis); - ctlr->control = offsetof(struct ich7_spi_regs, spic); - ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); - ctlr->preop = offsetof(struct ich7_spi_regs, preop); - ctlr->base = ich7_spi; - } else if (plat->ich_version == ICHV_9) { - struct ich9_spi_regs *ich9_spi = sbase; - - ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); - ctlr->menubytes = sizeof(ich9_spi->opmenu); - ctlr->optype = offsetof(struct ich9_spi_regs, optype); - ctlr->addr = offsetof(struct ich9_spi_regs, faddr); - ctlr->data = offsetof(struct ich9_spi_regs, fdata); - ctlr->databytes = sizeof(ich9_spi->fdata); - ctlr->status = offsetof(struct ich9_spi_regs, ssfs); - ctlr->control = offsetof(struct ich9_spi_regs, ssfc); - ctlr->speed = ctlr->control + 2; - ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); - ctlr->preop = offsetof(struct ich9_spi_regs, preop); - ctlr->bcr = offsetof(struct ich9_spi_regs, bcr); - ctlr->pr = &ich9_spi->pr[0]; - ctlr->base = ich9_spi; - } else { - debug("ICH SPI: Unrecognised ICH version %d\n", - plat->ich_version); - return -EINVAL; - } - - /* Work out the maximum speed we can support */ - ctlr->max_speed = 20000000; - if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev)) - ctlr->max_speed = 33000000; - debug("ICH SPI: Version ID %d detected at %p, speed %ld\n", - plat->ich_version, ctlr->base, ctlr->max_speed); - - ich_set_bbar(ctlr, 0); - - return 0; -} - static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase) { if (plat->ich_version == ICHV_7) { @@ -233,8 +194,7 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans, } if (opcode_index == ctlr->menubytes) { - printf("ICH SPI: Opcode %x not found\n", - trans->opcode); + debug("ICH SPI: Opcode %x not found\n", trans->opcode); return -EINVAL; } @@ -242,8 +202,8 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans, optype = (optypes >> (opcode_index * 2)) & 0x3; if (optype != trans->type) { - printf("ICH SPI: Transaction doesn't fit type %d\n", - optype); + debug("ICH SPI: Transaction doesn't fit type %d\n", + optype); return -ENOSPC; } return opcode_index; @@ -274,9 +234,9 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask, } udelay(10); } + debug("ICH SPI: SCIP timeout, read %x, expected %x, wts %x %x\n", + status, bitmask, wait_til_set, status & bitmask); - printf("ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); return -ETIMEDOUT; } @@ -295,7 +255,8 @@ static void ich_spi_config_opcode(struct udevice *dev) ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32)); } -static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) +static int ich_spi_exec_op_swseq(struct spi_slave *slave, + const struct spi_mem_op *op) { struct udevice *bus = dev_get_parent(slave->dev); struct ich_spi_platdata *plat = dev_get_platdata(bus); @@ -466,6 +427,228 @@ static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) return 0; } +/* + * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and + * that the operation does not cross page boundary. + */ +static uint get_xfer_len(u32 offset, int len, int page_size) +{ + uint xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE); + uint bytes_left = ALIGN(offset, page_size) - offset; + + if (bytes_left) + xfer_len = min(xfer_len, bytes_left); + + return xfer_len; +} + +/* Fill FDATAn FIFO in preparation for a write transaction */ +static void fill_xfer_fifo(struct fast_spi_regs *regs, const void *data, + uint len) +{ + memcpy(regs->fdata, data, len); +} + +/* Drain FDATAn FIFO after a read transaction populates data */ +static void drain_xfer_fifo(struct fast_spi_regs *regs, void *dest, uint len) +{ + memcpy(dest, regs->fdata, len); +} + +/* Fire up a transfer using the hardware sequencer */ +static void start_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle, + uint offset, uint len) +{ + /* Make sure all W1C status bits get cleared */ + u32 hsfsts; + + hsfsts = readl(®s->hsfsts_ctl); + hsfsts &= ~(HSFSTS_FCYCLE_MASK | HSFSTS_FDBC_MASK); + hsfsts |= HSFSTS_AEL | HSFSTS_FCERR | HSFSTS_FDONE; + + /* Set up transaction parameters */ + hsfsts |= hsfsts_cycle << HSFSTS_FCYCLE_SHIFT; + hsfsts |= ((len - 1) << HSFSTS_FDBC_SHIFT) & HSFSTS_FDBC_MASK; + hsfsts |= HSFSTS_FGO; + + writel(offset, ®s->faddr); + writel(hsfsts, ®s->hsfsts_ctl); +} + +static int wait_for_hwseq_xfer(struct fast_spi_regs *regs, uint offset) +{ + ulong start; + u32 hsfsts; + + start = get_timer(0); + do { + hsfsts = readl(®s->hsfsts_ctl); + if (hsfsts & HSFSTS_FCERR) { + debug("SPI transaction error at offset %x HSFSTS = %08x\n", + offset, hsfsts); + return -EIO; + } + if (hsfsts & HSFSTS_AEL) + return -EPERM; + + if (hsfsts & HSFSTS_FDONE) + return 0; + } while (get_timer(start) < SPIBAR_HWSEQ_XFER_TIMEOUT_MS); + + debug("SPI transaction timeout at offset %x HSFSTS = %08x, timer %d\n", + offset, hsfsts, (uint)get_timer(start)); + + return -ETIMEDOUT; +} + +/** + * exec_sync_hwseq_xfer() - Execute flash transfer by hardware sequencing + * + * This waits until complete or timeout + * + * @regs: SPI registers + * @hsfsts_cycle: Cycle type (enum hsfsts_cycle_t) + * @offset: Offset to access + * @len: Number of bytes to transfer (can be 0) + * @return 0 if OK, -EIO on flash-cycle error (FCERR), -EPERM on access error + * (AEL), -ETIMEDOUT on timeout + */ +static int exec_sync_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle, + uint offset, uint len) +{ + start_hwseq_xfer(regs, hsfsts_cycle, offset, len); + + return wait_for_hwseq_xfer(regs, offset); +} + +static int ich_spi_exec_op_hwseq(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct spi_flash *flash = dev_get_uclass_priv(slave->dev); + struct udevice *bus = dev_get_parent(slave->dev); + struct ich_spi_priv *priv = dev_get_priv(bus); + struct fast_spi_regs *regs = priv->base; + uint page_size; + uint offset; + int cycle; + uint len; + bool out; + int ret; + u8 *buf; + + offset = op->addr.val; + len = op->data.nbytes; + + switch (op->cmd.opcode) { + case SPINOR_OP_RDID: + cycle = HSFSTS_CYCLE_RDID; + break; + case SPINOR_OP_READ_FAST: + cycle = HSFSTS_CYCLE_READ; + break; + case SPINOR_OP_PP: + cycle = HSFSTS_CYCLE_WRITE; + break; + case SPINOR_OP_WREN: + /* Nothing needs to be done */ + return 0; + case SPINOR_OP_WRSR: + cycle = HSFSTS_CYCLE_WR_STATUS; + break; + case SPINOR_OP_RDSR: + cycle = HSFSTS_CYCLE_RD_STATUS; + break; + case SPINOR_OP_WRDI: + return 0; /* ignore */ + case SPINOR_OP_BE_4K: + cycle = HSFSTS_CYCLE_4K_ERASE; + while (len) { + uint xfer_len = 0x1000; + + ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0); + if (ret) + return ret; + offset += xfer_len; + len -= xfer_len; + } + return 0; + default: + debug("Unknown cycle %x\n", op->cmd.opcode); + return -EINVAL; + }; + + out = op->data.dir == SPI_MEM_DATA_OUT; + buf = out ? (u8 *)op->data.buf.out : op->data.buf.in; + page_size = flash->page_size ? : 256; + + while (len) { + uint xfer_len = get_xfer_len(offset, len, page_size); + + if (out) + fill_xfer_fifo(regs, buf, xfer_len); + + ret = exec_sync_hwseq_xfer(regs, cycle, offset, xfer_len); + if (ret) + return ret; + + if (!out) + drain_xfer_fifo(regs, buf, xfer_len); + + offset += xfer_len; + buf += xfer_len; + len -= xfer_len; + } + + return 0; +} + +static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct ich_spi_platdata *plat = dev_get_platdata(bus); + int ret; + + bootstage_start(BOOTSTAGE_ID_ACCUM_SPI, "fast_spi"); + if (plat->hwseq) + ret = ich_spi_exec_op_hwseq(slave, op); + else + ret = ich_spi_exec_op_swseq(slave, op); + bootstage_accum(BOOTSTAGE_ID_ACCUM_SPI); + + return ret; +} + +static int ich_get_mmap_bus(struct udevice *bus, ulong *map_basep, + uint *map_sizep, uint *offsetp) +{ + pci_dev_t spi_bdf; + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + struct pci_child_platdata *pplat = dev_get_parent_platdata(bus); + + spi_bdf = pplat->devfn; +#else + struct ich_spi_platdata *plat = dev_get_platdata(bus); + + /* + * We cannot rely on plat->bdf being set up yet since this method can + * be called before the device is probed. Use the of-platdata directly + * instead. + */ + spi_bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]); +#endif + + return fast_spi_get_bios_mmap(spi_bdf, map_basep, map_sizep, offsetp); +} + +static int ich_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct udevice *bus = dev_get_parent(dev); + + return ich_get_mmap_bus(bus, map_basep, map_sizep, offsetp); +} + static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op) { unsigned int page_offset; @@ -480,9 +663,11 @@ static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op) 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); + if (op->data.dir == SPI_MEM_DATA_IN) { + if (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); @@ -493,26 +678,18 @@ static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op) 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) +static int ich_protect_lockdown(struct udevice *dev) { struct ich_spi_platdata *plat = dev_get_platdata(dev); struct ich_spi_priv *priv = dev_get_priv(dev); - uint8_t bios_cntl; - int ret; + int ret = -ENOSYS; - ret = ich_init_controller(dev, plat, priv); - if (ret) - return ret; /* Disable the BIOS write protect so write commands are allowed */ - ret = pch_set_spi_protect(dev->parent, false); + if (priv->pch) + ret = pch_set_spi_protect(priv->pch, false); if (ret == -ENOSYS) { + u8 bios_cntl; + bios_cntl = ich_readb(priv, priv->bcr); bios_cntl &= ~BIT(5); /* clear Enable InSMM_STS (EISS) */ bios_cntl |= 1; /* Write Protect Disable (WPD) */ @@ -529,6 +706,111 @@ static int ich_spi_probe(struct udevice *dev) spi_lock_down(plat, priv->base); } + return 0; +} + +static int ich_init_controller(struct udevice *dev, + struct ich_spi_platdata *plat, + struct ich_spi_priv *ctlr) +{ + if (spl_phase() == PHASE_TPL) { + struct ich_spi_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = fast_spi_early_init(plat->bdf, plat->mmio_base); + if (ret) + return ret; + } + + ctlr->base = (void *)plat->mmio_base; + if (plat->ich_version == ICHV_7) { + struct ich7_spi_regs *ich7_spi = ctlr->base; + + ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); + ctlr->menubytes = sizeof(ich7_spi->opmenu); + ctlr->optype = offsetof(struct ich7_spi_regs, optype); + ctlr->addr = offsetof(struct ich7_spi_regs, spia); + ctlr->data = offsetof(struct ich7_spi_regs, spid); + ctlr->databytes = sizeof(ich7_spi->spid); + ctlr->status = offsetof(struct ich7_spi_regs, spis); + ctlr->control = offsetof(struct ich7_spi_regs, spic); + ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); + ctlr->preop = offsetof(struct ich7_spi_regs, preop); + } else if (plat->ich_version == ICHV_9) { + struct ich9_spi_regs *ich9_spi = ctlr->base; + + ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); + ctlr->menubytes = sizeof(ich9_spi->opmenu); + ctlr->optype = offsetof(struct ich9_spi_regs, optype); + ctlr->addr = offsetof(struct ich9_spi_regs, faddr); + ctlr->data = offsetof(struct ich9_spi_regs, fdata); + ctlr->databytes = sizeof(ich9_spi->fdata); + ctlr->status = offsetof(struct ich9_spi_regs, ssfs); + ctlr->control = offsetof(struct ich9_spi_regs, ssfc); + ctlr->speed = ctlr->control + 2; + ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); + ctlr->preop = offsetof(struct ich9_spi_regs, preop); + ctlr->bcr = offsetof(struct ich9_spi_regs, bcr); + ctlr->pr = &ich9_spi->pr[0]; + } else if (plat->ich_version == ICHV_APL) { + } else { + debug("ICH SPI: Unrecognised ICH version %d\n", + plat->ich_version); + return -EINVAL; + } + + /* Work out the maximum speed we can support */ + ctlr->max_speed = 20000000; + if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev)) + ctlr->max_speed = 33000000; + debug("ICH SPI: Version ID %d detected at %lx, speed %ld\n", + plat->ich_version, plat->mmio_base, ctlr->max_speed); + + ich_set_bbar(ctlr, 0); + + return 0; +} + +static int ich_cache_bios_region(struct udevice *dev) +{ + ulong map_base; + uint map_size; + uint offset; + ulong base; + int ret; + + ret = ich_get_mmap_bus(dev, &map_base, &map_size, &offset); + if (ret) + return ret; + + /* Don't use WRBACK since we are not supposed to write to SPI flash */ + base = SZ_4G - map_size; + mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size); + log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size); + + return 0; +} + +static int ich_spi_probe(struct udevice *dev) +{ + struct ich_spi_platdata *plat = dev_get_platdata(dev); + struct ich_spi_priv *priv = dev_get_priv(dev); + int ret; + + ret = ich_init_controller(dev, plat, priv); + if (ret) + return ret; + + if (spl_phase() == PHASE_TPL) { + /* Cache the BIOS to speed things up */ + ret = ich_cache_bios_region(dev); + if (ret) + return ret; + } else { + ret = ich_protect_lockdown(dev); + if (ret) + return ret; + } priv->cur_speed = priv->max_speed; return 0; @@ -570,9 +852,11 @@ static int ich_spi_child_pre_probe(struct udevice *dev) /* * Yes this controller can only write a small number of bytes at - * once! The limit is typically 64 bytes. + * once! The limit is typically 64 bytes. For hardware sequencing a + * a loop is used to get around this. */ - slave->max_write_size = priv->databytes; + if (!plat->hwseq) + slave->max_write_size = priv->databytes; /* * ICH 7 SPI controller only supports array read command * and byte program command for SST flash @@ -586,23 +870,37 @@ static int ich_spi_child_pre_probe(struct udevice *dev) static int ich_spi_ofdata_to_platdata(struct udevice *dev) { struct ich_spi_platdata *plat = dev_get_platdata(dev); - int node = dev_of_offset(dev); - int ret; - ret = fdt_node_check_compatible(gd->fdt_blob, node, "intel,ich7-spi"); - if (ret == 0) { - plat->ich_version = ICHV_7; - } else { - ret = fdt_node_check_compatible(gd->fdt_blob, node, - "intel,ich9-spi"); - if (ret == 0) - plat->ich_version = ICHV_9; - } +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + struct ich_spi_priv *priv = dev_get_priv(dev); - plat->lockdown = fdtdec_get_bool(gd->fdt_blob, node, - "intel,spi-lock-down"); + /* Find a PCH if there is one */ + uclass_first_device(UCLASS_PCH, &priv->pch); + if (!priv->pch) + priv->pch = dev_get_parent(dev); + + plat->ich_version = dev_get_driver_data(dev); + plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down"); + if (plat->ich_version == ICHV_APL) { + plat->mmio_base = dm_pci_read_bar32(dev, 0); + } else { + /* SBASE is similar */ + pch_get_spi_base(priv->pch, &plat->mmio_base); + } + /* + * Use an int so that the property is present in of-platdata even + * when false. + */ + plat->hwseq = dev_read_u32_default(dev, "intel,hardware-seq", 0); +#else + plat->ich_version = ICHV_APL; + plat->mmio_base = plat->dtplat.early_regs[0]; + plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]); + plat->hwseq = plat->dtplat.intel_hardware_seq; +#endif + debug("%s: mmio_base=%lx\n", __func__, plat->mmio_base); - return ret; + return 0; } static const struct spi_controller_mem_ops ich_controller_mem_ops = { @@ -612,10 +910,11 @@ static const struct spi_controller_mem_ops ich_controller_mem_ops = { }; static const struct dm_spi_ops ich_spi_ops = { - .xfer = ich_spi_xfer, + /* xfer is not supported */ .set_speed = ich_spi_set_speed, .set_mode = ich_spi_set_mode, .mem_ops = &ich_controller_mem_ops, + .get_mmap = ich_get_mmap, /* * cs_info is not needed, since we require all chip selects to be * in the device tree explicitly @@ -623,13 +922,14 @@ static const struct dm_spi_ops ich_spi_ops = { }; static const struct udevice_id ich_spi_ids[] = { - { .compatible = "intel,ich7-spi" }, - { .compatible = "intel,ich9-spi" }, + { .compatible = "intel,ich7-spi", ICHV_7 }, + { .compatible = "intel,ich9-spi", ICHV_9 }, + { .compatible = "intel,fast-spi", ICHV_APL }, { } }; -U_BOOT_DRIVER(ich_spi) = { - .name = "ich_spi", +U_BOOT_DRIVER(intel_fast_spi) = { + .name = "intel_fast_spi", .id = UCLASS_SPI, .of_match = ich_spi_ids, .ops = &ich_spi_ops, diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h index 3dfb2aaff1..d7f1ffdf37 100644 --- a/drivers/spi/ich.h +++ b/drivers/spi/ich.h @@ -163,14 +163,49 @@ struct spi_trans { #define ICH_BOUNDARY 0x1000 +#define HSFSTS_FDBC_SHIFT 24 +#define HSFSTS_FDBC_MASK (0x3f << HSFSTS_FDBC_SHIFT) +#define HSFSTS_WET BIT(21) +#define HSFSTS_FCYCLE_SHIFT 17 +#define HSFSTS_FCYCLE_MASK (0xf << HSFSTS_FCYCLE_SHIFT) + +/* Supported flash cycle types */ +enum hsfsts_cycle_t { + HSFSTS_CYCLE_READ = 0, + HSFSTS_CYCLE_WRITE = 2, + HSFSTS_CYCLE_4K_ERASE, + HSFSTS_CYCLE_64K_ERASE, + HSFSTS_CYCLE_RDSFDP, + HSFSTS_CYCLE_RDID, + HSFSTS_CYCLE_WR_STATUS, + HSFSTS_CYCLE_RD_STATUS, +}; + +#define HSFSTS_FGO BIT(16) +#define HSFSTS_FLOCKDN BIT(15) +#define HSFSTS_FDV BIT(14) +#define HSFSTS_FDOPSS BIT(13) +#define HSFSTS_WRSDIS BIT(11) +#define HSFSTS_SAF_CE BIT(8) +#define HSFSTS_SAF_ACTIVE BIT(7) +#define HSFSTS_SAF_LE BIT(6) +#define HSFSTS_SCIP BIT(5) +#define HSFSTS_SAF_DLE BIT(4) +#define HSFSTS_SAF_ERROR BIT(3) +#define HSFSTS_AEL BIT(2) +#define HSFSTS_FCERR BIT(1) +#define HSFSTS_FDONE BIT(0) +#define HSFSTS_W1C_BITS 0xff + +/* Maximum bytes of data that can fit in FDATAn (0x10) registers */ +#define SPIBAR_FDATA_FIFO_SIZE 0x40 + +#define SPIBAR_HWSEQ_XFER_TIMEOUT_MS 5000 + enum ich_version { ICHV_7, ICHV_9, -}; - -struct ich_spi_platdata { - enum ich_version ich_version; /* Controller version, 7 or 9 */ - bool lockdown; /* lock down controller settings? */ + ICHV_APL, }; struct ich_spi_priv { @@ -191,6 +226,7 @@ struct ich_spi_priv { ulong max_speed; /* Maximum bus speed in MHz */ ulong cur_speed; /* Current bus speed */ struct spi_trans trans; /* current transaction in progress */ + struct udevice *pch; /* PCH, used to control SPI access */ }; #endif /* _ICH_H_ */ diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 665611f7e2..af910e9efc 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -85,11 +85,14 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); if (bus->uclass->uc_drv->id != UCLASS_SPI) return -EOPNOTSUPP; + if (!ops->xfer) + return -ENOSYS; - return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags); + return ops->xfer(dev, bitlen, dout, din, flags); } int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 5f4bc6edb6..96cc49273f 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -174,6 +174,29 @@ config X86_TSC_TIMER help Select this to enable Time-Stamp Counter (TSC) timer for x86. +config X86_TSC_READ_BASE + bool "Read the TSC timer base on start-up" + depends on X86_TSC_TIMER + help + On x86 platforms the TSC timer tick starts at the value 0 on reset. + This it makes no sense to read the timer on boot and use that as the + base, since we will miss some time taken to load U-Boot, etc. This + delay is controlled by the SoC and we cannot reduce it, but for + bootstage we want to record the time since reset as accurately as + possible. + + The only exception is when U-Boot is used as a secondary bootloader, + where this option should be enabled. + +config TPL_X86_TSC_TIMER_NATIVE + bool "x86 TSC timer uses native calibration" + depends on TPL && X86_TSC_TIMER + help + Selects native timer calibration for TPL and don't include the other + methods in the code. This helps to reduce code size in TPL and works + on fairly modern Intel chips. Code-size reductions is about 700 + bytes. + config MTK_TIMER bool "MediaTek timer support" depends on TIMER diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 0df551f94c..43cb2d820e 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -50,8 +50,7 @@ static unsigned long native_calibrate_tsc(void) return 0; crystal_freq = tsc_info.ecx / 1000; - - if (!crystal_freq) { + if (!CONFIG_IS_ENABLED(X86_TSC_TIMER_NATIVE) && !crystal_freq) { switch (gd->arch.x86_model) { case INTEL_FAM6_SKYLAKE_MOBILE: case INTEL_FAM6_SKYLAKE_DESKTOP: @@ -397,7 +396,8 @@ static void tsc_timer_ensure_setup(bool early) { if (gd->arch.tsc_inited) return; - gd->arch.tsc_base = rdtsc(); + if (IS_ENABLED(CONFIG_X86_TSC_READ_BASE)) + gd->arch.tsc_base = rdtsc(); if (!gd->arch.clock_rate) { unsigned long fast_calibrate; @@ -406,6 +406,10 @@ static void tsc_timer_ensure_setup(bool early) if (fast_calibrate) goto done; + /* Reduce code size by dropping other methods */ + if (CONFIG_IS_ENABLED(X86_TSC_TIMER_NATIVE)) + panic("no timer"); + fast_calibrate = cpu_mhz_from_cpuid(); if (fast_calibrate) goto done; diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c index 3d105fddba..713111f6c3 100644 --- a/drivers/tpm/tpm2_tis_spi.c +++ b/drivers/tpm/tpm2_tis_spi.c @@ -587,7 +587,7 @@ static int tpm_tis_spi_probe(struct udevice *dev) /* Use the TPM v2 stack */ priv->version = TPM_V2; - if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct gpio_desc reset_gpio; ret = gpio_request_by_name(dev, "gpio-reset", 0, diff --git a/include/binman.h b/include/binman.h new file mode 100644 index 0000000000..b462dc8542 --- /dev/null +++ b/include/binman.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Access to binman information at runtime + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef _BINMAN_H_ +#define _BINMAN_H_ + +/** + *struct binman_entry - information about a binman entry + * + * @image_pos: Position of entry in the image + * @size: Size of entry + */ +struct binman_entry { + u32 image_pos; + u32 size; +}; + +/** + * binman_entry_find() - Find a binman symbol + * + * This searches the binman information in the device tree for a symbol of the + * given name + * + * @name: Path to entry to examine (e.g. "/read-only/u-boot") + * @entry: Returns information about the entry + * @return 0 if OK, -ENOENT if the path is not found, other -ve value if the + * binman information is invalid (missing image-pos or size) + */ +int binman_entry_find(const char *name, struct binman_entry *entry); + +/** + * binman_init() - Set up the binman symbol information + * + * This locates the binary symbol information in the device tree ready for use + * + * @return 0 if OK, -ENOMEM if out of memory, -EINVAL if there is no binman node + */ +int binman_init(void); + +#endif diff --git a/include/bootstage.h b/include/bootstage.h index d105ae0181..82f0307ef1 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -202,6 +202,9 @@ enum bootstage_id { BOOTSTATE_ID_ACCUM_DM_SPL, BOOTSTATE_ID_ACCUM_DM_F, BOOTSTATE_ID_ACCUM_DM_R, + BOOTSTATE_ID_ACCUM_FSP_M, + BOOTSTATE_ID_ACCUM_FSP_S, + BOOTSTAGE_ID_ACCUM_MMAP_SPI, /* a few spare for the user, from here */ BOOTSTAGE_ID_USER, diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h index c2f9735ce7..31da6215b3 100644 --- a/include/config_uncmd_spl.h +++ b/include/config_uncmd_spl.h @@ -12,7 +12,6 @@ #ifndef CONFIG_SPL_DM #undef CONFIG_DM_SERIAL -#undef CONFIG_DM_GPIO #undef CONFIG_DM_I2C #undef CONFIG_DM_SPI #endif diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h index d19fd3153c..6e9793ab81 100644 --- a/include/configs/at91-sama5_common.h +++ b/include/configs/at91-sama5_common.h @@ -9,6 +9,8 @@ #ifndef __AT91_SAMA5_COMMON_H #define __AT91_SAMA5_COMMON_H +#include <linux/kconfig.h> + /* ARM asynchronous clock */ #define CONFIG_SYS_AT91_SLOW_CLOCK 32768 #define CONFIG_SYS_AT91_MAIN_CLOCK 12000000 /* from 12 MHz crystal */ @@ -18,11 +20,10 @@ #endif /* general purpose I/O */ -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define CONFIG_AT91_GPIO #endif - /* * BOOTP options */ diff --git a/include/configs/chromebook_coral.h b/include/configs/chromebook_coral.h new file mode 100644 index 0000000000..a63c3c9eea --- /dev/null +++ b/include/configs/chromebook_coral.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + */ + +/* + * board/config.h - configuration options, board-specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_BOOTCOMMAND \ + "fatload mmc 1:c 1000000 syslinux/vmlinuz.A; zboot 1000000" + +#include <configs/x86-common.h> +#include <configs/x86-chromebook.h> + +#undef CONFIG_STD_DEVICES_SETTINGS +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ + "stdout=vidconsole,serial\0" \ + "stderr=vidconsole,serial\0" + +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_OFFSET 0x003f8000 + +#define CONFIG_TPL_TEXT_BASE 0xffff8000 + +#define CONFIG_SYS_NS16550_MEM32 +#undef CONFIG_SYS_NS16550_PORT_MAPPED + +#endif /* __CONFIG_H */ diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index 894f8b1114..d169aa19de 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -36,7 +36,6 @@ /* Driver Model */ #ifndef CONFIG_SPL_BUILD -#define CONFIG_DM_GPIO #define CONFIG_DM_THERMAL #endif diff --git a/include/configs/km/keymile-common.h b/include/configs/km/keymile-common.h index 8433d8e568..e690d8f39d 100644 --- a/include/configs/km/keymile-common.h +++ b/include/configs/km/keymile-common.h @@ -38,11 +38,6 @@ "actual_bank=0\0" #endif -#ifndef CONFIG_KM_DEF_NETDEV -#define CONFIG_KM_DEF_NETDEV \ - "netdev=eth0\0" -#endif - #ifndef CONFIG_KM_UBI_PARTITION_NAME_BOOT #define CONFIG_KM_UBI_PARTITION_NAME_BOOT "ubi0" #endif /* CONFIG_KM_UBI_PARTITION_NAME_BOOT */ @@ -168,7 +163,7 @@ #ifndef CONFIG_KM_DEF_ENV #define CONFIG_KM_DEF_ENV \ CONFIG_KM_DEF_ENV_BOOTPARAMS \ - CONFIG_KM_DEF_NETDEV \ + "netdev=" __stringify(CONFIG_KM_DEF_NETDEV) "\0" \ CONFIG_KM_DEF_ENV_CPU \ CONFIG_KM_DEF_ENV_BOOTTARGETS \ CONFIG_KM_DEF_ENV_BOOTARGS \ diff --git a/include/configs/km/km-mpc8309.h b/include/configs/km/km-mpc8309.h index 9aaea273e0..e710c04493 100644 --- a/include/configs/km/km-mpc8309.h +++ b/include/configs/km/km-mpc8309.h @@ -22,6 +22,7 @@ * System IO Config */ /* 0x14000180 SICR_1 */ +#ifndef CONFIG_SYS_SICRL #define CONFIG_SYS_SICRL (0 \ | SICR_1_UART1_UART1RTS \ | SICR_1_I2C_CKSTOP \ @@ -38,6 +39,7 @@ | SICR_1_FEC1_FEC1 \ | SICR_1_FEC2_FEC2 \ ) +#endif /* 0x00080400 SICR_2 */ #define CONFIG_SYS_SICRH (0 \ diff --git a/include/configs/kmcoge5ne.h b/include/configs/kmcoge5ne.h index fc78b27cbb..cdfb280aee 100644 --- a/include/configs/kmcoge5ne.h +++ b/include/configs/kmcoge5ne.h @@ -9,8 +9,6 @@ #define __CONFIG_H #define CONFIG_HOSTNAME "kmcoge5ne" -#define CONFIG_KM_BOARD_NAME "kmcoge5ne" -#define CONFIG_KM_DEF_NETDEV "netdev=eth1\0" #define CONFIG_NAND_ECC_BCH #define CONFIG_NAND_KMETER1 #define CONFIG_SYS_MAX_NAND_DEVICE 1 diff --git a/include/configs/kmeter1.h b/include/configs/kmeter1.h index bfa7ca27c7..4245875e39 100644 --- a/include/configs/kmeter1.h +++ b/include/configs/kmeter1.h @@ -9,8 +9,6 @@ #define __CONFIG_H #define CONFIG_HOSTNAME "kmeter1" -#define CONFIG_KM_BOARD_NAME "kmeter1" -#define CONFIG_KM_DEF_NETDEV "netdev=eth2\0" /* include common defines/options for all Keymile boards */ #include "km/keymile-common.h" @@ -18,11 +16,6 @@ #include "km/km-mpc83xx.h" #include "km/km-mpc8360.h" -/* - * Serial Port - */ -#define CONFIG_CONS_INDEX 1 - #define CONFIG_SYS_DDR_CS0_CONFIG (CSCONFIG_EN | CSCONFIG_AP | \ CSCONFIG_ROW_BIT_13 | \ CSCONFIG_COL_BIT_10 | \ diff --git a/include/configs/kmopti2.h b/include/configs/kmopti2.h index 67e864fc98..5050c70303 100644 --- a/include/configs/kmopti2.h +++ b/include/configs/kmopti2.h @@ -23,7 +23,6 @@ /* * High Level Configuration Options */ -#define CONFIG_KM_BOARD_NAME "kmopti2" #define CONFIG_HOSTNAME "kmopti2" /* include common defines/options for all Keymile boards */ diff --git a/include/configs/kmp204x.h b/include/configs/kmp204x.h index 771d0248f7..6cee3b47b3 100644 --- a/include/configs/kmp204x.h +++ b/include/configs/kmp204x.h @@ -9,7 +9,6 @@ #if defined(CONFIG_KMCOGE4) #define CONFIG_HOSTNAME "kmcoge4" -#define CONFIG_KM_BOARD_NAME "kmcoge4" #else #error ("Board not supported") @@ -17,8 +16,6 @@ #define CONFIG_KMP204X -#define CONFIG_KM_DEF_NETDEV "netdev=eth0\0" - /* an additionnal option is required for UBI as subpage access is * supported in u-boot */ diff --git a/include/configs/kmsupx5.h b/include/configs/kmsupx5.h index ba33e6074b..e3de6c61e7 100644 --- a/include/configs/kmsupx5.h +++ b/include/configs/kmsupx5.h @@ -23,7 +23,6 @@ /* * High Level Configuration Options */ -#define CONFIG_KM_BOARD_NAME "kmsupx5" #define CONFIG_HOSTNAME "kmsupx5" /* include common defines/options for all Keymile boards */ diff --git a/include/configs/kmtegr1.h b/include/configs/kmtegr1.h index e627606222..bdd35cc7fb 100644 --- a/include/configs/kmtegr1.h +++ b/include/configs/kmtegr1.h @@ -21,7 +21,6 @@ */ #define CONFIG_HOSTNAME "kmtegr1" -#define CONFIG_KM_BOARD_NAME "kmtegr1" #define CONFIG_KM_UBI_PARTITION_NAME_BOOT "ubi0" #define CONFIG_KM_UBI_PARTITION_NAME_APP "ubi1" @@ -30,6 +29,23 @@ #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define NAND_MAX_CHIPS 1 +#define CONFIG_SYS_SICRL (0 \ + | SICR_1_UART1_UART1RTS \ + | SICR_1_I2C_CKSTOP \ + | SICR_1_IRQ_A_IRQ \ + | SICR_1_IRQ_B_IRQ \ + | SICR_1_GPIO_A_GPIO \ + | SICR_1_GPIO_B_GPIO \ + | SICR_1_GPIO_C_GPIO \ + | SICR_1_GPIO_D_GPIO \ + | SICR_1_GPIO_E_LCS \ + | SICR_1_GPIO_F_GPIO \ + | SICR_1_USB_A_UART2S \ + | SICR_1_USB_B_UART2RTS \ + | SICR_1_FEC1_FEC1 \ + | SICR_1_FEC2_FEC2 \ + ) + /* include common defines/options for all Keymile boards */ #include "km/keymile-common.h" #include "km/km-powerpc.h" diff --git a/include/configs/kmtepr2.h b/include/configs/kmtepr2.h index e0c907d11a..a4ceb1c50d 100644 --- a/include/configs/kmtepr2.h +++ b/include/configs/kmtepr2.h @@ -23,7 +23,6 @@ /* * High Level Configuration Options */ -#define CONFIG_KM_BOARD_NAME "kmtepr2" #define CONFIG_HOSTNAME "kmtepr2" /* include common defines/options for all Keymile boards */ diff --git a/include/configs/ls1028a_common.h b/include/configs/ls1028a_common.h index 4bd510d42e..05b8cf00ee 100644 --- a/include/configs/ls1028a_common.h +++ b/include/configs/ls1028a_common.h @@ -210,6 +210,9 @@ #define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5 +/* DisplayPort */ +#define DP_PWD_EN_DEFAULT_MASK 0x8 + #ifdef CONFIG_NXP_ESBC #include <asm/fsl_secure_boot.h> #endif diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h index b082d8549a..d02ad083e8 100644 --- a/include/configs/ls1088ardb.h +++ b/include/configs/ls1088ardb.h @@ -305,8 +305,8 @@ "mmcinfo;mmc read 0x80000000 0x5000 0x800;" \ "mmc read 0x80100000 0x7000 0x800;" \ "env exists secureboot && " \ - "mmc read 0x80700000 0x3800 0x10 && " \ - "mmc read 0x80740000 0x3A00 0x10 && " \ + "mmc read 0x80700000 0x3800 0x20 && " \ + "mmc read 0x80740000 0x3A00 0x20 && " \ "esbc_validate 0x80700000 && " \ "esbc_validate 0x80740000 ;" \ "fsl_mc start mc 0x80000000 0x80100000\0" @@ -327,8 +327,8 @@ "mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;" \ "mmc read 0x80100000 0x7000 0x800;" \ "env exists secureboot && " \ - "mmc read 0x80700000 0x3800 0x10 && " \ - "mmc read 0x80740000 0x3A00 0x10 && " \ + "mmc read 0x80700000 0x3800 0x20 && " \ + "mmc read 0x80740000 0x3A00 0x20 && " \ "esbc_validate 0x80700000 && " \ "esbc_validate 0x80740000 ;" \ "fsl_mc start mc 0x80000000 0x80100000\0" \ @@ -362,7 +362,7 @@ "load_addr=0xa0000000\0" \ "kernel_size=0x2800000\0" \ "kernel_size_sd=0x14000\0" \ - "kernelhdr_size_sd=0x10\0" \ + "kernelhdr_size_sd=0x20\0" \ QSPI_MC_INIT_CMD \ "mcmemsize=0x70000000\0" \ BOOTENV \ @@ -431,7 +431,7 @@ "load_addr=0xa0000000\0" \ "kernel_size=0x2800000\0" \ "kernel_size_sd=0x14000\0" \ - "kernelhdr_size_sd=0x10\0" \ + "kernelhdr_size_sd=0x20\0" \ MC_INIT_CMD \ BOOTENV \ "boot_scripts=ls1088ardb_boot.scr\0" \ @@ -478,7 +478,7 @@ #undef CONFIG_BOOTCOMMAND #ifdef CONFIG_TFABOOT #define QSPI_NOR_BOOTCOMMAND \ - "sf read 0x80001000 0xd00000 0x100000;" \ + "sf read 0x80001000 0xd00000 0x100000;" \ "env exists mcinitcmd && env exists secureboot " \ " && sf read 0x80780000 0x780000 0x100000 " \ "&& esbc_validate 0x80780000;env exists mcinitcmd " \ @@ -489,7 +489,7 @@ "env exists mcinitcmd && mmcinfo; " \ "mmc read 0x80001000 0x6800 0x800; " \ "env exists mcinitcmd && env exists secureboot " \ - " && mmc read 0x80780000 0x3C00 0x10 " \ + " && mmc read 0x80780000 0x3C00 0x20 " \ "&& esbc_validate 0x80780000;env exists mcinitcmd " \ "&& fsl_mc lazyapply dpl 0x80001000;" \ "run distro_bootcmd;run sd_bootcmd;" \ @@ -512,7 +512,7 @@ "env exists mcinitcmd && mmcinfo; " \ "mmc read 0x80001000 0x6800 0x800; " \ "env exists mcinitcmd && env exists secureboot " \ - " && mmc read 0x80780000 0x3C00 0x10 " \ + " && mmc read 0x80780000 0x3C00 0x20 " \ "&& esbc_validate 0x80780000;env exists mcinitcmd " \ "&& fsl_mc lazyapply dpl 0x80001000;" \ "run distro_bootcmd;run sd_bootcmd;" \ diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index b251c795b0..de14fb4ac8 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -330,8 +330,8 @@ unsigned long get_board_sys_clk(void); "mmcinfo;mmc read 0x80a00000 0x5000 0x1200;" \ "mmc read 0x80e00000 0x7000 0x800;" \ "env exists secureboot && " \ - "mmc read 0x80700000 0x3800 0x10 && " \ - "mmc read 0x80740000 0x3A00 0x10 && " \ + "mmc read 0x80700000 0x3800 0x20 && " \ + "mmc read 0x80740000 0x3A00 0x20 && " \ "esbc_validate 0x80700000 && " \ "esbc_validate 0x80740000 ;" \ "fsl_mc start mc 0x80a00000 0x80e00000\0" @@ -352,8 +352,8 @@ unsigned long get_board_sys_clk(void); "mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;" \ "mmc read 0x80100000 0x7000 0x800;" \ "env exists secureboot && " \ - "mmc read 0x80700000 0x3800 0x10 && " \ - "mmc read 0x80740000 0x3A00 0x10 && " \ + "mmc read 0x80700000 0x3800 0x20 && " \ + "mmc read 0x80740000 0x3A00 0x20 && " \ "esbc_validate 0x80700000 && " \ "esbc_validate 0x80740000 ;" \ "fsl_mc start mc 0x80000000 0x80100000\0" \ diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h index cfb20d3fb0..cd3e2c4c85 100644 --- a/include/configs/lx2160a_common.h +++ b/include/configs/lx2160a_common.h @@ -197,8 +197,8 @@ unsigned long get_board_ddr_clk(void); "mmc read 0x80a00000 0x5000 0x1200;" \ "mmc read 0x80e00000 0x7000 0x800;" \ "env exists secureboot && " \ - "mmc read 0x80700000 0x3800 0x10 && " \ - "mmc read 0x80740000 0x3A00 0x10 && " \ + "mmc read 0x80700000 0x3800 0x20 && " \ + "mmc read 0x80740000 0x3A00 0x20 && " \ "esbc_validate 0x80700000 && " \ "esbc_validate 0x80740000 ;" \ "fsl_mc start mc 0x80a00000 0x80e00000\0" @@ -224,7 +224,7 @@ unsigned long get_board_ddr_clk(void); "kernel_addr_sd=0x8000\0" \ "kernelhdr_addr_sd=0x3E00\0" \ "kernel_size_sd=0x1d000\0" \ - "kernelhdr_size_sd=0x10\0" \ + "kernelhdr_size_sd=0x20\0" \ "console=ttyAMA0,38400n8\0" \ BOOTENV \ "mcmemsize=0x70000000\0" \ @@ -262,7 +262,7 @@ unsigned long get_board_ddr_clk(void); "env exists mcinitcmd && mmcinfo; " \ "mmc read 0x80d00000 0x6800 0x800; " \ "env exists mcinitcmd && env exists secureboot " \ - " && mmc read 0x80780000 0x3C00 0x10 " \ + " && mmc read 0x80780000 0x3C00 0x20 " \ "&& esbc_validate 0x80780000;env exists mcinitcmd " \ "&& fsl_mc lazyapply dpl 0x80d00000;" \ "run distro_bootcmd;run sd_bootcmd;" \ diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h index c21d633ca0..5cc15b6d2f 100644 --- a/include/configs/mx6ul_14x14_evk.h +++ b/include/configs/mx6ul_14x14_evk.h @@ -44,6 +44,7 @@ #define CONFIG_SYS_I2C_SPEED 100000 #endif +/* Note: This is incorrect and should move to Kconfig / defconfig */ #ifdef CONFIG_DM_GPIO #define CONFIG_DM_74X164 #endif diff --git a/include/configs/suvd3.h b/include/configs/suvd3.h index 1705f9cafb..d74707971b 100644 --- a/include/configs/suvd3.h +++ b/include/configs/suvd3.h @@ -21,7 +21,6 @@ */ #define CONFIG_HOSTNAME "suvd3" -#define CONFIG_KM_BOARD_NAME "suvd3" /* include common defines/options for all Keymile boards */ #include "km/keymile-common.h" diff --git a/include/configs/tuge1.h b/include/configs/tuge1.h index 808538ef9d..d43ccbe8dd 100644 --- a/include/configs/tuge1.h +++ b/include/configs/tuge1.h @@ -23,7 +23,6 @@ /* * High Level Configuration Options */ -#define CONFIG_KM_BOARD_NAME "tuge1" #define CONFIG_HOSTNAME "tuge1" /* include common defines/options for all Keymile boards */ diff --git a/include/configs/tuxx1.h b/include/configs/tuxx1.h index 0eb673a947..f5a9f1284a 100644 --- a/include/configs/tuxx1.h +++ b/include/configs/tuxx1.h @@ -23,7 +23,6 @@ /* * High Level Configuration Options */ -#define CONFIG_KM_BOARD_NAME "tuxx1" #define CONFIG_HOSTNAME "tuxx1" /* include common defines/options for all Keymile boards */ diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5c4cbf0998..4282169706 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -118,7 +118,7 @@ static inline ofnode offset_to_ofnode(int of_offset) if (of_live_active()) node.np = NULL; else - node.of_offset = of_offset; + node.of_offset = of_offset >= 0 ? of_offset : -1; return node; } diff --git a/include/dm/pci.h b/include/dm/pci.h new file mode 100644 index 0000000000..10f9fd9e37 --- /dev/null +++ b/include/dm/pci.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019 Google, Inc + */ + +#ifndef __DM_PCI_H +#define __DM_PCI_H + +struct udevice; + +/** + * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device + * + * Get devfn from fdt_pci_addr of the specified device + * + * This returns an int to avoid a dependency on pci.h + * + * @dev: PCI device + * @return devfn in bits 15...8 if found (pci_dev_t format), or -ENODEV if not + * found + */ +int pci_get_devfn(struct udevice *dev); + +/** + * pci_ofplat_get_devfn() - Get the PCI dev/fn from of-platdata + * + * This function is used to obtain a PCI device/function from of-platdata + * register data. In this case the first cell of the 'reg' property contains + * the required information. + * + * This returns an int to avoid a dependency on pci.h + * + * @reg: reg value from dt-platdata.c array (first member). This is not a + * pointer type, since the caller may use fdt32_t or fdt64_t depending on + * the address sizes. + * @return device/function for that device (pci_dev_t format) + */ +static inline int pci_ofplat_get_devfn(u32 reg) +{ + return reg & 0xff00; +} + +#endif diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 0c563d898b..c1bab17ad1 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -28,6 +28,7 @@ enum uclass_id { UCLASS_AXI_EMUL, /* sandbox AXI bus device emulator */ /* U-Boot uclasses start here - in alphabetical order */ + UCLASS_ACPI_PMC, /* (x86) Power-management controller (PMC) */ UCLASS_ADC, /* Analog-to-digital converter */ UCLASS_AHCI, /* SATA disk controller */ UCLASS_AUDIO_CODEC, /* Audio codec with control and data path */ @@ -69,6 +70,7 @@ enum uclass_id { UCLASS_NOP, /* No-op devices */ UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */ UCLASS_NVME, /* NVM Express device */ + UCLASS_P2SB, /* (x86) Primary-to-Sideband Bus */ UCLASS_PANEL, /* Display panel, such as an LCD */ UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */ UCLASS_PCH, /* x86 platform controller hub */ diff --git a/include/fsl-mc/fsl_dpsparser.h b/include/fsl-mc/fsl_dpsparser.h new file mode 100644 index 0000000000..48fb495059 --- /dev/null +++ b/include/fsl-mc/fsl_dpsparser.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Data Path Soft Parser API + * + * Copyright 2018 NXP + */ +#ifndef _FSL_DPSPARSER_H +#define _FSL_DPSPARSER_H + +/* DPSPARSER last supported API version */ +#define DPSPARSER_VER_MAJOR 1 +#define DPSPARSER_VER_MINOR 0 + +/* Command IDs */ +#define DPSPARSER_CMDID_CLOSE 0x8001 +#define DPSPARSER_CMDID_OPEN 0x8111 +#define DPSPARSER_CMDID_CREATE 0x9111 +#define DPSPARSER_CMDID_DESTROY 0x9911 +#define DPSPARSER_CMDID_GET_API_VERSION 0xa111 + +#define DPSPARSER_CMDID_APPLY_SPB 0x1181 + +/* cmd, param, offset, width, type, arg_name */ +#define DPSPARSER_CMD_BLOB_SET_ADDR(cmd, addr) \ + MC_CMD_OP(cmd, 0, 0, 64, u64, addr) + +/* cmd, param, offset, width, type, arg_name */ +#define DPSPARSER_CMD_BLOB_REPORT_ERROR(cmd, err) \ + MC_RSP_OP(cmd, 0, 0, 16, u16, err) + +/* Data Path Soft Parser API + * Contains initialization APIs and runtime control APIs for DPSPARSER + */ + +struct fsl_mc_io; + +/* MC Unknown error: */ +#define MC_ERROR_MSG_SPB_UNKNOWN "Unknown MC error\n" + +/* MC Error messages (in order for each error code defined above): */ +#define MC_ERROR_MSG_APPLY_SPB \ +{ \ + "OK\n", \ + "BLOB : Magic number does not match\n", \ + "BLOB : Version does not match MC API version\n", \ + "BLOB : IP revision does not match HW revision\n", \ + "BLOB : Blob length is not a multiple of 4\n", \ + "BLOB : Invalid length detected\n", \ + "BLOB : Name length < 0 in 'blob-name'\n", \ + "BLOB : Name length not a 4 multiple in 'blob-name'\n", \ + "BLOB : No target HW parser selected\n", \ + "BLOB : SP size is negative\n", \ + "BLOB : Size is zero\n", \ + "BLOB : Number of protocols is negative\n", \ + "BLOB : Zero protocols\n", \ + "BLOB : Protocol name is null\n", \ + "BLOB : SP 'seq-start' is not in [0x40, 0xffc0) range\n", \ + "BLOB : Invalid base protocol\n", \ + "BLOB : Invalid parameters section\n", \ + "BLOB : Invalid parameter\n", \ + "BLOB : Invalid parameter configuration\n", \ + "BLOB : Not aligned value\n", \ + "BLOB : Invalid section TAG detected\n", \ + "BLOB : Section size is zero\n", \ + "BLOB : Section size not a 4 multiple\n", \ + "BLOB : Section size is too big\n", \ + "BLOB : No 'bytecode' section before\n", \ + "BLOB : No 'sp-protocols' section before\n", \ + "BLOB : No 'bytecode' section defined\n", \ + "BLOB : No 'sp-protocols' section defined\n", \ + "BLOB : Soft Parser BLOB parsing : Error detected\n", \ + "apply spb : Soft Parser BLOB is already applied\n", \ + "apply spb : BLOB address is not set\n", \ + "BLOB : SP parameter offset is not a 4 multiple\n", \ + "BLOB : SP parameter offset can't be less than 0x40\n", \ + "BLOB : Bytecode size is not a 4 multiple\n", \ + "BLOB : Bytecode size cannot be zero\n", \ + "BLOB : Bytecode can't overwrite the 0xFFE address\n", \ + "BLOB : No hardware parser selected as target\n", \ + "BLOB : Bytecode overlap detected\n", \ + "BLOB : No parser support\n", \ + "BLOB : Too many bytecode sections on WRIOP ingress\n", \ + "BLOB : Too many bytecode sections on WRIOP egress\n", \ + "BLOB : Too many bytecode sections on AIOP\n", \ + "BLOB : Duplicated protocol is already registered\n", \ + "BLOB : Maximum number of allowed protocols was exceeded\n", \ + "BLOB : Protocols limit exceeded\n", \ + "BLOB : Protocol is linked twice\n", \ + "BLOB : Soft parser is linked twice\n", \ + "BLOB : Parameter offset exceeds the maximum parameters limit\n", \ + "BLOB : Parameter size can't be 0 or greater than 64\n", \ + "BLOB : Parameter offset plus size exceeds the maximum limit\n", \ + "BLOB : Parameters number exceeds the maximum limit\n", \ + "BLOB : Duplicated parameter name\n", \ + "BLOB : Parameters overlapped detected\n", \ + "apply spb : No dpsparser handle.\n", \ + \ + MC_ERROR_MSG_SPB_UNKNOWN, \ + NULL, \ +} + +/** + * dpsparser_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpsparser_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsparser_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *token); + +/** + * dpsparser_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSPARSER object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsparser_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); + +/** + * dpsparser_create() - Create the DPSPARSER object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Returned token; use in subsequent API calls + * + * Create the DPSPARSER object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpsparser_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsparser_create(struct fsl_mc_io *mc_io, + u16 token, + u32 cmd_flags, + u32 *obj_id); + +/** + * dpsparser_destroy() - Destroy the DPSPARSER object and release all its + * resources. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSPARSER object + * + * Return: '0' on Success; error code otherwise. + */ +int dpsparser_destroy(struct fsl_mc_io *mc_io, + u16 token, + u32 cmd_flags, + u32 obj_id); + +/** + * dpsparser_apply_spb() - Applies the Soft Parser Blob loaded at specified + * address. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSPARSER object + * @blob_addr: Blob loading address + * @error: Error reported by MC related to SP Blob parsing and apply + * + * Return: '0' on Success; error code otherwise. + */ +int dpsparser_apply_spb(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u64 blob_addr, + u16 *error); + +/** + * dpsparser_get_api_version - Retrieve DPSPARSER Major and Minor version info. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @major_ver: DPSPARSER major version + * @minor_ver: DPSPARSER minor version + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsparser_get_api_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *major_ver, + u16 *minor_ver); + +#endif /* _FSL_DPSPARSER_H */ diff --git a/include/fsl-mc/fsl_mc_private.h b/include/fsl-mc/fsl_mc_private.h index ba0bc379d5..28b6d45023 100644 --- a/include/fsl-mc/fsl_mc_private.h +++ b/include/fsl-mc/fsl_mc_private.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2014-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2017-2018 NXP */ #ifndef _FSL_MC_PRIVATE_H_ @@ -65,7 +65,22 @@ struct fsl_dpni_obj { extern struct fsl_dpni_obj *dflt_dpni; +/** + * struct sp_blob_header - SP Blob header structure + * @magic: SP Blob magic number + * @blob_ver: SP Blob version + * @ip_rev: SP IP revision + * @length: Length of the SP Blob + */ +struct sp_blob_header { + u32 magic; + u32 blob_ver; + u32 ip_rev; + u32 length; +}; + int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr); int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if); int mc_apply_dpl(u64 mc_dpl_addr); +int mc_apply_spb(u64 mc_spb_addr); #endif /* _FSL_MC_PRIVATE_H_ */ diff --git a/include/i2c.h b/include/i2c.h index 33570f5404..72e2e8e426 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -45,12 +45,26 @@ struct udevice; * represent up to 256 bytes. A value larger than 1 may be * needed for larger devices. * @flags: Flags for this chip (dm_i2c_chip_flags) + * @chip_addr_offset_mask: Mask of offset bits within chip_addr. Used for + * devices which steal addresses as part of offset. + * If offset_len is zero, then the offset is encoded + * completely within the chip address itself. + * e.g. a devce with chip address of 0x2c with 512 + * registers might use the bottom bit of the address + * to indicate which half of the address space is being + * accessed while still only using 1 byte offset. + * This means it will respond to chip address 0x2c and + * 0x2d. + * A real world example is the Atmel AT24C04. It's + * datasheet explains it's usage of this addressing + * mode. * @emul: Emulator for this chip address (only used for emulation) */ struct dm_i2c_chip { uint chip_addr; uint offset_len; uint flags; + uint chip_addr_offset_mask; #ifdef CONFIG_SANDBOX struct udevice *emul; bool test_mode; @@ -262,6 +276,25 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len); int i2c_get_chip_offset_len(struct udevice *dev); /** + * i2c_set_chip_addr_offset_mask() - set mask of address bits usable by offset + * + * Some devices listen on multiple chip addresses to achieve larger offsets + * than their single or multiple byte offsets would allow for. You can use this + * function to set the bits that are valid to be used for offset overflow. + * + * @mask: The mask to be used for high offset bits within address + * @return 0 if OK, other -ve value on error + */ +int i2c_set_chip_addr_offset_mask(struct udevice *dev, uint mask); + +/* + * i2c_get_chip_addr_offset_mask() - get mask of address bits usable by offset + * + * @return current chip addr offset mask + */ +uint i2c_get_chip_addr_offset_mask(struct udevice *dev); + +/** * i2c_deblock() - recover a bus that is in an unknown state * * See the deblock() method in 'struct dm_i2c_ops' for full information diff --git a/include/i2c_eeprom.h b/include/i2c_eeprom.h index 0fcdf3831b..b96254ae79 100644 --- a/include/i2c_eeprom.h +++ b/include/i2c_eeprom.h @@ -10,6 +10,7 @@ struct i2c_eeprom_ops { int (*read)(struct udevice *dev, int offset, uint8_t *buf, int size); int (*write)(struct udevice *dev, int offset, const uint8_t *buf, int size); + int (*size)(struct udevice *dev); }; struct i2c_eeprom { @@ -17,6 +18,8 @@ struct i2c_eeprom { unsigned long pagesize; /* The EEPROM's page width in bits (pagesize = 2^pagewidth) */ unsigned pagewidth; + /* The EEPROM's capacity in bytes */ + unsigned long size; }; /* @@ -43,4 +46,13 @@ int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size); */ int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size); +/* + * i2c_eeprom_size() - get size of I2C EEPROM chip + * + * @dev: Chip to query + * + * @return +ve size in bytes on success, -ve on failure + */ +int i2c_eeprom_size(struct udevice *dev); + #endif diff --git a/include/init.h b/include/init.h index 8b65b2afe4..970a39a6a0 100644 --- a/include/init.h +++ b/include/init.h @@ -67,6 +67,17 @@ int mach_cpu_init(void); */ int arch_fsp_init(void); +/** + * arch_fsp_init() - perform post-relocation firmware support package init + * + * Where U-Boot relies on binary blobs to handle part of the system init, this + * function can be used to set up the blobs. This is used on some Intel + * platforms. + * + * Return: 0 + */ +int arch_fsp_init_r(void); + int dram_init(void); /** diff --git a/include/irq.h b/include/irq.h new file mode 100644 index 0000000000..01ded64f16 --- /dev/null +++ b/include/irq.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * IRQ is a type of interrupt controller used on recent Intel SoC. + * + * Copyright 2019 Google LLC + */ + +#ifndef __irq_H +#define __irq_H + +/** + * struct irq_ops - Operations for the IRQ + */ +struct irq_ops { + /** + * route_pmc_gpio_gpe() - Get the GPIO for an event + * + * @dev: IRQ device + * @pmc_gpe_num: Event number to check + * @returns GPIO for the event, or -ENOENT if none + */ + int (*route_pmc_gpio_gpe)(struct udevice *dev, uint pmc_gpe_num); + + /** + * set_polarity() - Set the IRQ polarity + * + * @dev: IRQ device + * @irq: Interrupt number to set + * @active_low: true if active low, false for active high + * @return 0 if OK, -EINVAL if @irq is invalid + */ + int (*set_polarity)(struct udevice *dev, uint irq, bool active_low); + + /** + * snapshot_polarities() - record IRQ polarities for later restore + * + * @dev: IRQ device + * @return 0 + */ + int (*snapshot_polarities)(struct udevice *dev); + + /** + * restore_polarities() - restore IRQ polarities + * + * @dev: IRQ device + * @return 0 + */ + int (*restore_polarities)(struct udevice *dev); +}; + +#define irq_get_ops(dev) ((struct irq_ops *)(dev)->driver->ops) + +/** + * irq_route_pmc_gpio_gpe() - Get the GPIO for an event + * + * @dev: IRQ device + * @pmc_gpe_num: Event number to check + * @returns GPIO for the event, or -ENOENT if none + */ +int irq_route_pmc_gpio_gpe(struct udevice *dev, uint pmc_gpe_num); + +/** + * irq_set_polarity() - Set the IRQ polarity + * + * @dev: IRQ device + * @irq: Interrupt number to set + * @active_low: true if active low, false for active high + * @return 0 if OK, -EINVAL if @irq is invalid + */ +int irq_set_polarity(struct udevice *dev, uint irq, bool active_low); + +/** + * irq_snapshot_polarities() - record IRQ polarities for later restore + * + * @dev: IRQ device + * @return 0 + */ +int irq_snapshot_polarities(struct udevice *dev); + +/** + * irq_restore_polarities() - restore IRQ polarities + * + * @dev: IRQ device + * @return 0 + */ +int irq_restore_polarities(struct udevice *dev); + +#endif diff --git a/include/p2sb.h b/include/p2sb.h new file mode 100644 index 0000000000..60c7f70773 --- /dev/null +++ b/include/p2sb.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __p2sb_h +#define __p2sb_h + +/* Port Id lives in bits 23:16 and register offset lives in 15:0 of address */ +#define PCR_PORTID_SHIFT 16 + +/** + * struct p2sb_child_platdata - Information about each child of a p2sb device + * + * @pid: Port ID for this child + */ +struct p2sb_child_platdata { + uint pid; +}; + +/** + * struct p2sb_uc_priv - information for the uclass about each device + * + * This must be set up by the driver when it is probed + * + * @mmio_base: Base address of P2SB region + */ +struct p2sb_uc_priv { + uint mmio_base; +}; + +/** + * struct p2sb_ops - Operations for the P2SB (none at present) + */ +struct p2sb_ops { +}; + +#define p2sb_get_ops(dev) ((struct p2sb_ops *)(dev)->driver->ops) + +/** + * pcr_read32/16/8() - Read from a PCR device + * + * Reads data from a PCR device within the P2SB + * + * @dev: Device to read from + * @offset: Offset within device to read + * @return value read + */ +uint pcr_read32(struct udevice *dev, uint offset); +uint pcr_read16(struct udevice *dev, uint offset); +uint pcr_read8(struct udevice *dev, uint offset); + +/** + * pcr_read32/16/8() - Write to a PCR device + * + * Writes data to a PCR device within the P2SB + * + * @dev: Device to write to + * @offset: Offset within device to write + * @data: Data to write + */ +void pcr_write32(struct udevice *dev, uint offset, uint data); +void pcr_write16(struct udevice *dev, uint offset, uint data); +void pcr_write8(struct udevice *dev, uint offset, uint data); + +/** + * pcr_clrsetbits32/16/8() - Update a PCR device + * + * Updates dat in a PCR device within the P2SB + * + * This reads from the device, clears and set bits, then writes back. + * + * new_data = (old_data & ~clr) | set + * + * @dev: Device to update + * @offset: Offset within device to update + * @clr: Bits to clear after reading + * @set: Bits to set before writing + */ +void pcr_clrsetbits32(struct udevice *dev, uint offset, uint clr, uint set); +void pcr_clrsetbits16(struct udevice *dev, uint offset, uint clr, uint set); +void pcr_clrsetbits8(struct udevice *dev, uint offset, uint clr, uint set); + +static inline void pcr_setbits32(struct udevice *dev, uint offset, uint set) +{ + return pcr_clrsetbits32(dev, offset, 0, set); +} + +static inline void pcr_setbits16(struct udevice *dev, uint offset, uint set) +{ + return pcr_clrsetbits16(dev, offset, 0, set); +} + +static inline void pcr_setbits8(struct udevice *dev, uint offset, uint set) +{ + return pcr_clrsetbits8(dev, offset, 0, set); +} + +static inline void pcr_clrbits32(struct udevice *dev, uint offset, uint clr) +{ + return pcr_clrsetbits32(dev, offset, clr, 0); +} + +static inline void pcr_clrbits16(struct udevice *dev, uint offset, uint clr) +{ + return pcr_clrsetbits16(dev, offset, clr, 0); +} + +static inline void pcr_clrbits8(struct udevice *dev, uint offset, uint clr) +{ + return pcr_clrsetbits8(dev, offset, clr, 0); +} + +/** + * p2sb_set_port_id() - Set the port ID for a p2sb child device + * + * This must be called in a device's bind() method when OF_PLATDATA is used + * since the uclass cannot access the device's of-platdata. + * + * @dev: Child device (whose parent is UCLASS_P2SB) + * @portid: Port ID of child device + * @return 0 if OK, -ENODEV is the p2sb device could not be found + */ +int p2sb_set_port_id(struct udevice *dev, int portid); + +/** + * p2sb_get_port_id() - Get the port ID for a p2sb child device + * + * @dev: Child device (whose parent is UCLASS_P2SB) + * @return Port ID of that child + */ +int p2sb_get_port_id(struct udevice *dev); + +#endif diff --git a/include/pci.h b/include/pci.h index ff59ac0e69..8c761d8da3 100644 --- a/include/pci.h +++ b/include/pci.h @@ -482,6 +482,8 @@ #ifndef __ASSEMBLY__ +#include <dm/pci.h> + #ifdef CONFIG_SYS_PCI_64BIT typedef u64 pci_addr_t; typedef u64 pci_size_t; @@ -571,15 +573,22 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev #define INDIRECT_TYPE_NO_PCIE_LINK 1 -/* +/** * Structure of a PCI controller (host bridge) * * With driver model this is dev_get_uclass_priv(bus) + * + * @skip_auto_config_until_reloc: true to avoid auto-config until U-Boot has + * relocated. Normally if PCI is used before relocation, this happens + * before relocation also. Some platforms set up static configuration in + * TPL/SPL to reduce code size and boot time, since these phases only know + * about a small subset of PCI devices. This is normally false. */ struct pci_controller { #ifdef CONFIG_DM_PCI struct udevice *bus; struct udevice *ctlr; + bool skip_auto_config_until_reloc; #else struct pci_controller *next; #endif @@ -1612,16 +1621,6 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, */ int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp); -/** - * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device - * - * Get devfn from fdt_pci_addr of the specified device - * - * @dev: PCI device - * @return devfn in bits 15...8 if found, -ENODEV if not found - */ -int pci_get_devfn(struct udevice *dev); - #endif /* CONFIG_DM_PCI */ /** diff --git a/include/power/acpi_pmc.h b/include/power/acpi_pmc.h new file mode 100644 index 0000000000..1f50c23f5f --- /dev/null +++ b/include/power/acpi_pmc.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __ACPI_PMC_H +#define __ACPI_PMC_H + +enum { + GPE0_REG_MAX = 4, +}; + +/** + * struct acpi_pmc_upriv - holds common data for the x86 PMC + * + * @pmc_bar0: Base address 0 of PMC + * @pmc_bar1: Base address 2 of PMC + * @acpi_base: Base address of ACPI block + * @pm1_sts: PM1 status + * @pm1_en: PM1 enable + * @pm1_cnt: PM1 control + * @gpe_cfg: Address of GPE_CFG register + * @gpe0_dwx_mask: Mask to use for each GPE0 (typically 7 or 0xf) + * @gpe0_dwx_shift_base: Base shift value to use for GPE0 (0 or 4) + * @gpe0_sts_req: GPE0 status register offset + * @gpe0_en_req: GPE0 enable register offset + * @gpe0_sts: GPE0 status values + * @gpe0_en: GPE0 enable values + * @gpe0_dw: GPE0 DW values + * @gpe0_count: Number of GPE0 registers + * @tco1_sts: TCO1 status + * @tco2_sts: TCO2 status + * @prsts: Power and reset status + * @gen_pmcon1: General power mgmt configuration 1 + * @gen_pmcon2: General power mgmt configuration 2 + * @gen_pmcon3: General power mgmt configuration 3 + */ +struct acpi_pmc_upriv { + void *pmc_bar0; + void *pmc_bar2; + u32 acpi_base; + u16 pm1_sts; + u16 pm1_en; + u32 pm1_cnt; + u32 *gpe_cfg; + u32 gpe0_dwx_mask; + u32 gpe0_dwx_shift_base; + u32 gpe0_sts_reg; + u32 gpe0_en_reg; + u32 gpe0_sts[GPE0_REG_MAX]; + u32 gpe0_en[GPE0_REG_MAX]; + u32 gpe0_dw[GPE0_REG_MAX]; + int gpe0_count; + u16 tco1_sts; + u16 tco2_sts; + u32 prsts; + u32 gen_pmcon1; + u32 gen_pmcon2; + u32 gen_pmcon3; +}; + +struct acpi_pmc_ops { + /** + * init() - Set up the PMC for use + * + * This reads the current state of the PMC. Most of the state is read + * automatically by the uclass since it is common. + * + * This is optional. + * + * @dev: PMC device to use + * @return 0 if OK, -ve on error + */ + int (*init)(struct udevice *dev); + + /** + * prev_sleep_state() - Get the previous sleep state (optional) + * + * This reads various state registers and returns the sleep state from + * which the system woke. If this method is not provided, the uclass + * will return a calculated value. + * + * This is optional. + * + * @dev: PMC device to use + * @prev_sleep_state: Previous sleep state as calculated by the uclass. + * The method can use this as the return value or calculate its + * own. + * + * @return enum acpi_sleep_state indicating the previous sleep state + * (ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error + */ + int (*prev_sleep_state)(struct udevice *dev, int prev_sleep_state); + + /** + * disable_tco() - Disable the timer/counter + * + * Disables the timer/counter in the PMC + * + * This is optional. + * + * @dev: PMC device to use + * @return 0 + */ + int (*disable_tco)(struct udevice *dev); + + /** + * global_reset_set_enable() - Enable/Disable global reset + * + * Enable or disable global reset. If global reset is enabled, both hard + * reset and soft reset will trigger global reset, where both host and + * TXE are reset. This is cleared on cold boot, hard reset, soft reset + * and Sx. + * + * This is optional. + * + * @dev: PMC device to use + * @enable: true to enable global reset, false to disable + * @return 0 + */ + int (*global_reset_set_enable)(struct udevice *dev, bool enable); +}; + +#define acpi_pmc_get_ops(dev) ((struct acpi_pmc_ops *)(dev)->driver->ops) + +/** + * init() - Set up the PMC for use + * + * This reads the current state of the PMC. This reads in the common registers, + * then calls the device's init() method to read the SoC-specific registers. + * + * @return 0 if OK, -ve on error + */ +int pmc_init(struct udevice *dev); + +/** + * pmc_prev_sleep_state() - Get the previous sleep state + * + * This reads various state registers and returns the sleep state from + * which the system woke. + * + * @return enum acpi_sleep_state indicating the previous sleep state + * (ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error + */ +int pmc_prev_sleep_state(struct udevice *dev); + +/** + * pmc_disable_tco() - Disable the timer/counter + * + * Disables the timer/counter in the PMC + * + * @dev: PMC device to use + * @return 0 + */ +int pmc_disable_tco(struct udevice *dev); + +/** + * pmc_global_reset_set_enable() - Enable/Disable global reset + * + * Enable or disable global reset. If global reset is enabled, both hard + * reset and soft reset will trigger global reset, where both host and + * TXE are reset. This is cleared on cold boot, hard reset, soft reset + * and Sx. + * + * @dev: PMC device to use + * @enable: true to enable global reset, false to disable + * @return 0 + */ +int pmc_global_reset_set_enable(struct udevice *dev, bool enable); + +int pmc_ofdata_to_uc_platdata(struct udevice *dev); + +int pmc_disable_tco_base(ulong tco_base); + +void pmc_dump_info(struct udevice *dev); + +/** + * pmc_gpe_init() - Set up general-purpose events + * + * @dev: PMC device + * @return 0 if OK, -ve on error + */ +int pmc_gpe_init(struct udevice *dev); + +#endif diff --git a/include/qfw.h b/include/qfw.h index 2f1a20416f..cea8e11d44 100644 --- a/include/qfw.h +++ b/include/qfw.h @@ -172,4 +172,12 @@ bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter); bool qemu_fwcfg_present(void); bool qemu_fwcfg_dma_present(void); +/** + * qemu_cpu_fixup() - Fix up the CPUs for QEMU + * + * @return 0 if OK, -ENODEV if no CPUs, -ENOMEM if out of memory, other -ve on + * on other error + */ +int qemu_cpu_fixup(void); + #endif diff --git a/include/spi.h b/include/spi.h index 6fbb4336ce..ba2c8406b2 100644 --- a/include/spi.h +++ b/include/spi.h @@ -224,7 +224,7 @@ void spi_release_bus(struct spi_slave *slave); int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen); /** - * SPI transfer + * SPI transfer (optional if mem_ops is used) * * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks * "bitlen" bits in the SPI MISO port. That's just the way SPI works. diff --git a/include/spi_flash.h b/include/spi_flash.h index 55b4721813..0b23f57a71 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -102,6 +102,18 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len); */ int spl_flash_get_sw_write_prot(struct udevice *dev); +/** + * spi_flash_std_probe() - Probe a SPI flash device + * + * This is the standard internal method for probing a SPI flash device to + * determine its type. It can be used in chip-specific drivers which need to + * do this, typically with of-platdata + * + * @dev: SPI-flash device to probe + * @return 0 if OK, -ve on error + */ +int spi_flash_std_probe(struct udevice *dev); + int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode, struct udevice **devp); diff --git a/include/spl.h b/include/spl.h index 08ffddac29..02aa1ff85d 100644 --- a/include/spl.h +++ b/include/spl.h @@ -169,10 +169,29 @@ struct spl_load_info { * We need to know the position of U-Boot in memory so we can jump to it. We * allow any U-Boot binary to be used (u-boot.bin, u-boot-nodtb.bin, * u-boot.img), hence the '_any'. These is no checking here that the correct - * image is found. For * example if u-boot.img is used we don't check that + * image is found. For example if u-boot.img is used we don't check that * spl_parse_image_header() can parse a valid header. + * + * Similarly for SPL, so that TPL can jump to SPL. */ binman_sym_extern(ulong, u_boot_any, image_pos); +binman_sym_extern(ulong, u_boot_any, size); +binman_sym_extern(ulong, spl, image_pos); +binman_sym_extern(ulong, spl, size); + +/** + * spl_get_image_pos() - get the image position of the next phase + * + * This returns the image position to use to load the next phase of U-Boot + */ +ulong spl_get_image_pos(void); + +/** + * spl_get_image_size() - get the size of the next phase + * + * This returns the size to use to load the next phase of U-Boot + */ +ulong spl_get_image_size(void); /** * spl_load_simple_fit_skip_processing() - Hook to allow skipping the FIT diff --git a/lib/Kconfig b/lib/Kconfig index 965cf7bc03..d040a87d26 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -7,6 +7,16 @@ config BCH This is used by SoC platforms which do not have built-in ELM hardware engine required for BCH ECC correction. +config BINMAN_FDT + bool "Allow access to binman information in the device tree" + depends on BINMAN && OF_CONTROL + default y + help + This enables U-Boot to access information about binman entries, + stored in the device tree in a binman node. Typical uses are to + locate entries in the firmware image. See binman.h for the available + functionality. + config CC_OPTIMIZE_LIBS_FOR_SPEED bool "Optimize libraries for speed" help diff --git a/lib/Makefile b/lib/Makefile index 1fb650cd90..6b7b9ce85c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_ASN1_DECODER) += asn1_decoder.o obj-y += crypto/ obj-$(CONFIG_AES) += aes.o +obj-$(CONFIG_$(SPL_TPL_)BINMAN_FDT) += binman.o ifndef API_BUILD ifneq ($(CONFIG_UT_UNICODE)$(CONFIG_EFI_LOADER),) @@ -77,7 +78,7 @@ endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o -obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o +obj-y += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o obj-y += qsort.o diff --git a/lib/binman.c b/lib/binman.c new file mode 100644 index 0000000000..1774bdf2e5 --- /dev/null +++ b/lib/binman.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Intel +/* + * Access to binman information at runtime + * + * Copyright 2019 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <binman.h> +#include <dm.h> + +struct binman_info { + ofnode image; +}; + +static struct binman_info *binman; + +int binman_entry_find(const char *name, struct binman_entry *entry) +{ + ofnode node; + int ret; + + node = ofnode_find_subnode(binman->image, name); + if (!ofnode_valid(node)) + return log_msg_ret("no binman node", -ENOENT); + + ret = ofnode_read_u32(node, "image-pos", &entry->image_pos); + if (ret) + return log_msg_ret("bad binman node1", ret); + ret = ofnode_read_u32(node, "size", &entry->size); + if (ret) + return log_msg_ret("bad binman node2", ret); + + return 0; +} + +int binman_init(void) +{ + binman = malloc(sizeof(struct binman_info)); + if (!binman) + return log_msg_ret("space for binman", -ENOMEM); + binman->image = ofnode_path("/binman"); + if (!ofnode_valid(binman->image)) + return log_msg_ret("binman node", -EINVAL); + + return 0; +} diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig index 919e314a0c..93b8564492 100644 --- a/lib/efi/Kconfig +++ b/lib/efi/Kconfig @@ -1,6 +1,7 @@ config EFI bool "Support running U-Boot from EFI" depends on X86 + imply X86_TSC_READ_BASE help U-Boot can be started from EFI on certain platforms. This allows EFI to perform most of the system init and then jump to U-Boot for diff --git a/lib/net_utils.c b/lib/net_utils.c index ed5044c3de..8af7782970 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -56,3 +56,51 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr) addr = (*end) ? end + 1 : end; } } + +uint compute_ip_checksum(const void *vptr, uint nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +uint add_ip_checksums(uint offset, uint sum, uint new) +{ + ulong checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian-independent this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, uint nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} diff --git a/net/Makefile b/net/Makefile index 2a700c8401..fef71b940a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,7 +5,6 @@ #ccflags-y += -DDEBUG -obj-y += checksum.o obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o diff --git a/net/checksum.c b/net/checksum.c deleted file mode 100644 index 16ef416356..0000000000 --- a/net/checksum.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * This file was originally taken from the FreeBSD project. - * - * Copyright (c) 2001 Charles Mott <cm@linktel.net> - * Copyright (c) 2008 coresystems GmbH - * All rights reserved. - */ - -#include <common.h> -#include <net.h> - -unsigned compute_ip_checksum(const void *vptr, unsigned nbytes) -{ - int sum, oddbyte; - const unsigned short *ptr = vptr; - - sum = 0; - while (nbytes > 1) { - sum += *ptr++; - nbytes -= 2; - } - if (nbytes == 1) { - oddbyte = 0; - ((u8 *)&oddbyte)[0] = *(u8 *)ptr; - ((u8 *)&oddbyte)[1] = 0; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - sum = ~sum & 0xffff; - - return sum; -} - -unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new) -{ - unsigned long checksum; - - sum = ~sum & 0xffff; - new = ~new & 0xffff; - if (offset & 1) { - /* - * byte-swap the sum if it came from an odd offset; since the - * computation is endian independant this works. - */ - new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); - } - checksum = sum + new; - if (checksum > 0xffff) - checksum -= 0xffff; - - return (~checksum) & 0xffff; -} - -int ip_checksum_ok(const void *addr, unsigned nbytes) -{ - return !(compute_ip_checksum(addr, nbytes) & 0xfffe); -} diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ef116e0e0a..c10cd83a0a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -300,7 +300,9 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $(pre-tmp) ; \ $(DTC) -O dtb -o $@ -b 0 \ -i $(dir $<) $(DTC_FLAGS) \ - -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + -d $(depfile).dtc.tmp $(dtc-tmp) || \ + (echo "Check $(shell pwd)/$(pre-tmp) for errors" && false) \ + ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ; \ sed -i "s:$(pre-tmp):$(<):" $(depfile) diff --git a/scripts/Makefile.uncmd_spl b/scripts/Makefile.uncmd_spl index ba267d9ac6..6ea097d36d 100644 --- a/scripts/Makefile.uncmd_spl +++ b/scripts/Makefile.uncmd_spl @@ -6,7 +6,6 @@ ifdef CONFIG_SPL_BUILD ifndef CONFIG_SPL_DM CONFIG_DM_SERIAL= -CONFIG_DM_GPIO= CONFIG_DM_I2C= CONFIG_DM_SPI= CONFIG_DM_SPI_FLASH= diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index cf1808e051..594e6b726d 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -924,7 +924,6 @@ CONFIG_KMCOGE4 CONFIG_KMP204X CONFIG_KMTEGR1 CONFIG_KM_BOARD_EXTRA_ENV -CONFIG_KM_BOARD_NAME CONFIG_KM_COGE5UN CONFIG_KM_DEF_ARCH CONFIG_KM_DEF_BOOT_ARGS_CPU @@ -935,7 +934,6 @@ CONFIG_KM_DEF_ENV_BOOTTARGETS CONFIG_KM_DEF_ENV_CONSTANTS CONFIG_KM_DEF_ENV_CPU CONFIG_KM_DEF_ENV_FLASH_BOOT -CONFIG_KM_DEF_NETDEV CONFIG_KM_DEV_ENV_FLASH_BOOT_UBI CONFIG_KM_DISABLE_PCIE CONFIG_KM_ECC_MODE diff --git a/test/dm/Makefile b/test/dm/Makefile index 0c2fd5cb5e..a268783169 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock.o obj-$(CONFIG_DM_I2C) += i2c.o obj-$(CONFIG_SOUND) += i2s.o +obj-y += irq.o obj-$(CONFIG_LED) += led.o obj-$(CONFIG_DM_MAILBOX) += mailbox.o obj-$(CONFIG_DM_MMC) += mmc.o @@ -32,10 +33,12 @@ obj-y += ofnode.o obj-$(CONFIG_OSD) += osd.o obj-$(CONFIG_DM_VIDEO) += panel.o obj-$(CONFIG_DM_PCI) += pci.o +obj-$(CONFIG_P2SB) += p2sb.o obj-$(CONFIG_PCI_ENDPOINT) += pci_ep.o obj-$(CONFIG_PCH) += pch.o obj-$(CONFIG_PHY) += phy.o obj-$(CONFIG_POWER_DOMAIN) += power-domain.o +obj-$(CONFIG_ACPI_PMC) += pmc.o obj-$(CONFIG_DM_PWM) += pwm.o obj-$(CONFIG_RAM) += ram.o obj-y += regmap.o diff --git a/test/dm/i2c.c b/test/dm/i2c.c index cbbd4aa29a..cadbb43b9e 100644 --- a/test/dm/i2c.c +++ b/test/dm/i2c.c @@ -15,6 +15,7 @@ #include <dm/test.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <hexdump.h> #include <test/ut.h> static const int busnum; @@ -185,39 +186,123 @@ static int dm_test_i2c_offset(struct unit_test_state *uts) ut_assertok(i2c_set_chip_offset_len(dev, 0)); ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); - ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf))); + ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf)); + ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom)); /* Offset length 1 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 1); ut_assertok(i2c_set_chip_offset_len(dev, 1)); ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2)); + ut_asserteq(2, sanbox_i2c_eeprom_get_prev_offset(eeprom)); ut_assertok(dm_i2c_read(dev, 0, buf, 5)); - ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf))); + ut_asserteq_mem("ABAB\0", buf, sizeof(buf)); + ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom)); - /* Offset length 2 */ + /* Offset length 2 boundary - check model wrapping */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(dm_i2c_write(dev, 0x210, (uint8_t *)"AB", 2)); - ut_assertok(dm_i2c_read(dev, 0x210, buf, 5)); - ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); + ut_assertok(dm_i2c_write(dev, 0xFF, (uint8_t *)"A", 1)); + ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_assertok(dm_i2c_write(dev, 0x100, (uint8_t *)"B", 1)); + ut_asserteq(0x100, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_assertok(dm_i2c_write(dev, 0x101, (uint8_t *)"C", 1)); + ut_asserteq(0x101, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_assertok(dm_i2c_read(dev, 0xFF, buf, 5)); + ut_asserteq_mem("ABCAB", buf, sizeof(buf)); + ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom)); - /* Offset length 3 */ + /* Offset length 2 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(dm_i2c_write(dev, 0x410, (uint8_t *)"AB", 2)); - ut_assertok(dm_i2c_read(dev, 0x410, buf, 5)); - ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); + ut_assertok(dm_i2c_write(dev, 0x2020, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x2020, buf, 5)); + ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x2020, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + + /* Offset length 3 */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 3); + ut_assertok(i2c_set_chip_offset_len(dev, 3)); + ut_assertok(dm_i2c_write(dev, 0x303030, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x303030, buf, 5)); + ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x303030, sanbox_i2c_eeprom_get_prev_offset(eeprom)); /* Offset length 4 */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 4); + ut_assertok(i2c_set_chip_offset_len(dev, 4)); + ut_assertok(dm_i2c_write(dev, 0x40404040, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x40404040, buf, 5)); + ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x40404040, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + + /* Restore defaults */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 1); + + return 0; +} +DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +static int dm_test_i2c_addr_offset(struct unit_test_state *uts) +{ + struct udevice *eeprom; + struct udevice *dev; + u8 buf[5]; + + ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev)); + + /* Do a transfer so we can find the emulator */ + ut_assertok(dm_i2c_read(dev, 0, buf, 5)); + ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom)); + + /* Offset length 0 */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 0); + sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3); + ut_assertok(i2c_set_chip_offset_len(dev, 0)); + ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3)); + ut_assertok(dm_i2c_write(dev, 0x3, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x3, buf, 5)); + ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x3, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom)); + + /* Offset length 1 */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 1); + sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3); + ut_assertok(i2c_set_chip_offset_len(dev, 1)); + ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3)); + ut_assertok(dm_i2c_write(dev, 0x310, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x310, buf, 5)); + ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x310, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom)); + + /* Offset length 2 */ sandbox_i2c_eeprom_set_offset_len(eeprom, 2); + sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3); ut_assertok(i2c_set_chip_offset_len(dev, 2)); - ut_assertok(dm_i2c_write(dev, 0x420, (uint8_t *)"AB", 2)); - ut_assertok(dm_i2c_read(dev, 0x420, buf, 5)); - ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf))); + ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3)); + ut_assertok(dm_i2c_write(dev, 0x32020, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x32020, buf, 5)); + ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x32020, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom)); + + /* Offset length 3 */ + sandbox_i2c_eeprom_set_offset_len(eeprom, 3); + sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3); + ut_assertok(i2c_set_chip_offset_len(dev, 3)); + ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3)); + ut_assertok(dm_i2c_write(dev, 0x3303030, (uint8_t *)"AB", 2)); + ut_assertok(dm_i2c_read(dev, 0x3303030, buf, 5)); + ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf)); + ut_asserteq(0x3303030, sanbox_i2c_eeprom_get_prev_offset(eeprom)); + ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom)); /* Restore defaults */ sandbox_i2c_eeprom_set_offset_len(eeprom, 1); + sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0); return 0; } -DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +DM_TEST(dm_test_i2c_addr_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/irq.c b/test/dm/irq.c new file mode 100644 index 0000000000..726189c59f --- /dev/null +++ b/test/dm/irq.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for irq uclass + * + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <irq.h> +#include <dm/test.h> +#include <test/ut.h> + +/* Base test of the irq uclass */ +static int dm_test_irq_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_first_device_err(UCLASS_IRQ, &dev)); + + ut_asserteq(5, irq_route_pmc_gpio_gpe(dev, 4)); + ut_asserteq(-ENOENT, irq_route_pmc_gpio_gpe(dev, 14)); + + ut_assertok(irq_set_polarity(dev, 4, true)); + ut_asserteq(-EINVAL, irq_set_polarity(dev, 14, true)); + + ut_assertok(irq_snapshot_polarities(dev)); + ut_assertok(irq_restore_polarities(dev)); + + return 0; +} +DM_TEST(dm_test_irq_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/p2sb.c b/test/dm/p2sb.c new file mode 100644 index 0000000000..ccb75cf375 --- /dev/null +++ b/test/dm/p2sb.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for Primary-to-Sideband bus (P2SB) + * + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <p2sb.h> +#include <asm/test.h> +#include <dm/test.h> +#include <test/ut.h> + +/* Base test of the PMC uclass */ +static int dm_test_p2sb_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + sandbox_set_enable_memio(true); + ut_assertok(uclass_get_device_by_name(UCLASS_AXI, "adder", &dev)); + ut_asserteq(0x03000004, pcr_read32(dev, 4)); + ut_asserteq(0x300, pcr_read16(dev, 6)); + ut_asserteq(4, pcr_read8(dev, 4)); + + return 0; +} +DM_TEST(dm_test_p2sb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/dm/pmc.c b/test/dm/pmc.c new file mode 100644 index 0000000000..1a222838ab --- /dev/null +++ b/test/dm/pmc.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for power-management controller uclass (PMC) + * + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <dm.h> +#include <power/acpi_pmc.h> +#include <dm/test.h> +#include <test/ut.h> + +/* Base test of the PMC uclass */ +static int dm_test_pmc_base(struct unit_test_state *uts) +{ + struct acpi_pmc_upriv *upriv; + struct udevice *dev; + + ut_assertok(uclass_first_device_err(UCLASS_ACPI_PMC, &dev)); + + ut_assertok(pmc_disable_tco(dev)); + ut_assertok(pmc_init(dev)); + ut_assertok(pmc_prev_sleep_state(dev)); + + /* Check some values to see that I/O works */ + upriv = dev_get_uclass_priv(dev); + ut_asserteq(0x24, upriv->gpe0_sts[1]); + ut_asserteq(0x64, upriv->tco1_sts); + + return 0; +} +DM_TEST(dm_test_pmc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/py/conftest.py b/test/py/conftest.py index bffee6b8a3..472dd0545d 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -83,6 +83,26 @@ def pytest_configure(config): Returns: Nothing. """ + def parse_config(conf_file): + """Parse a config file, loading it into the ubconfig container + + Args: + conf_file: Filename to load (within build_dir) + + Raises + Exception if the file does not exist + """ + dot_config = build_dir + '/' + conf_file + if not os.path.exists(dot_config): + raise Exception(conf_file + ' does not exist; ' + + 'try passing --build option?') + + with open(dot_config, 'rt') as f: + ini_str = '[root]\n' + f.read() + ini_sio = io.StringIO(ini_str) + parser = configparser.RawConfigParser() + parser.read_file(ini_sio) + ubconfig.buildconfig.update(parser.items('root')) global log global console @@ -157,18 +177,13 @@ def pytest_configure(config): ubconfig.buildconfig = dict() - for conf_file in ('.config', 'include/autoconf.mk'): - dot_config = build_dir + '/' + conf_file - if not os.path.exists(dot_config): - raise Exception(conf_file + ' does not exist; ' + - 'try passing --build option?') - - with open(dot_config, 'rt') as f: - ini_str = '[root]\n' + f.read() - ini_sio = io.StringIO(ini_str) - parser = configparser.RawConfigParser() - parser.read_file(ini_sio) - ubconfig.buildconfig.update(parser.items('root')) + # buildman -k puts autoconf.mk in the rootdir, so handle this as well + # as the standard U-Boot build which leaves it in include/autoconf.mk + parse_config('.config') + if os.path.exists(build_dir + '/' + 'autoconf.mk'): + parse_config('autoconf.mk') + else: + parse_config('include/autoconf.mk') ubconfig.test_py_dir = test_py_dir ubconfig.source_dir = source_dir diff --git a/tools/buildman/README b/tools/buildman/README index e36619216d..c1ac0d0f58 100644 --- a/tools/buildman/README +++ b/tools/buildman/README @@ -1061,6 +1061,9 @@ Other options Buildman has various other command line options. Try --help to see them. +To find out what architecture or toolchain prefix buildman will use for a build, +see the -a and -A options. + When doing builds, Buildman's return code will reflect the overall result: 0 (success) No errors or warnings found diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index cfbe4c26b1..784c64122b 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -577,7 +577,8 @@ class Builder: sym = {} for line in fd.readlines(): try: - size, type, name = line[:-1].split() + if line.strip(): + size, type, name = line[:-1].split() except: Print("Invalid line in file '%s': '%s'" % (fname, line[:-1])) continue diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index 832a5145d2..b41209373d 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -13,6 +13,10 @@ def ParseArgs(): args: command lin arguments """ parser = OptionParser() + parser.add_option('-a', '--print-arch', action='store_true', + help='Print the architecture for a board (ARCH=)') + parser.add_option('-A', '--print-prefix', action='store_true', + help='Print the tool-chain prefix for a board (CROSS_COMPILE=)') parser.add_option('-b', '--branch', type='string', help='Branch name to build, or range of commits to build') parser.add_option('-B', '--bloat', dest='show_bloat', diff --git a/tools/buildman/control.py b/tools/buildman/control.py index c55a65d0c3..969d866547 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -107,6 +107,34 @@ def CheckOutputDir(output_dir): break path = parent +def ShowToolchainInfo(boards, toolchains, print_arch, print_prefix): + """Show information about a the tool chain used by one or more boards + + The function checks that all boards use the same toolchain. + + Args: + boards: Boards object containing selected boards + toolchains: Toolchains object containing available toolchains + print_arch: True to print ARCH value + print_prefix: True to print CROSS_COMPILE value + + Return: + None on success, string error message otherwise + """ + boards = boards.GetSelectedDict() + tc_set = set() + for brd in boards.values(): + tc_set.add(toolchains.Select(brd.arch)) + if len(tc_set) != 1: + return 'Supplied boards must share one toolchain' + return False + tc = tc_set.pop() + if print_arch: + print(tc.GetEnvArgs(toolchain.VAR_ARCH)) + if print_prefix: + print(tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + return None + def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, clean_dir=False): """The main control code for buildman @@ -170,42 +198,13 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, print() return 0 - # Work out how many commits to build. We want to build everything on the - # branch. We also build the upstream commit as a control so we can see - # problems introduced by the first commit on the branch. - count = options.count - has_range = options.branch and '..' in options.branch - if count == -1: - if not options.branch: - count = 1 - else: - if has_range: - count, msg = gitutil.CountCommitsInRange(options.git_dir, - options.branch) - else: - count, msg = gitutil.CountCommitsInBranch(options.git_dir, - options.branch) - if count is None: - sys.exit(col.Color(col.RED, msg)) - elif count == 0: - sys.exit(col.Color(col.RED, "Range '%s' has no commits" % - options.branch)) - if msg: - print(col.Color(col.YELLOW, msg)) - count += 1 # Build upstream commit also - - if not count: - str = ("No commits found to process in branch '%s': " - "set branch's upstream or use -c flag" % options.branch) - sys.exit(col.Color(col.RED, str)) - # Work out what subset of the boards we are building if not boards: if not os.path.exists(options.output_dir): os.makedirs(options.output_dir) board_file = os.path.join(options.output_dir, 'boards.cfg') genboardscfg = os.path.join(options.git, 'tools/genboardscfg.py') - status = subprocess.call([genboardscfg, '-o', board_file]) + status = subprocess.call([genboardscfg, '-q', '-o', board_file]) if status != 0: sys.exit("Failed to generate boards.cfg") @@ -217,7 +216,6 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, for arg in options.exclude: exclude += arg.split(',') - if options.boards: requested_boards = [] for b in options.boards: @@ -230,6 +228,42 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, if not len(selected): sys.exit(col.Color(col.RED, 'No matching boards found')) + if options.print_arch or options.print_prefix: + err = ShowToolchainInfo(boards, toolchains, options.print_arch, + options.print_prefix) + if err: + sys.exit(col.Color(col.RED, err)) + return 0 + + # Work out how many commits to build. We want to build everything on the + # branch. We also build the upstream commit as a control so we can see + # problems introduced by the first commit on the branch. + count = options.count + has_range = options.branch and '..' in options.branch + if count == -1: + if not options.branch: + count = 1 + else: + if has_range: + count, msg = gitutil.CountCommitsInRange(options.git_dir, + options.branch) + else: + count, msg = gitutil.CountCommitsInBranch(options.git_dir, + options.branch) + if count is None: + sys.exit(col.Color(col.RED, msg)) + elif count == 0: + sys.exit(col.Color(col.RED, "Range '%s' has no commits" % + options.branch)) + if msg: + print(col.Color(col.YELLOW, msg)) + count += 1 # Build upstream commit also + + if not count: + str = ("No commits found to process in branch '%s': " + "set branch's upstream or use -c flag" % options.branch) + sys.exit(col.Color(col.RED, str)) + # Read the metadata from the commits. First look at the upstream commit, # then the ones in the branch. We would like to do something like # upstream/master~..branch but that isn't possible if upstream/master is diff --git a/tools/buildman/test.py b/tools/buildman/test.py index b4e28d6867..acd862b3b0 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -451,6 +451,24 @@ class TestBuild(unittest.TestCase): 'crosstool/files/bin/x86_64/.*/' 'x86_64-gcc-.*-nolibc_arm-.*linux-gnueabi.tar.xz') + def testGetEnvArgs(self): + """Test the GetEnvArgs() function""" + tc = self.toolchains.Select('arm') + self.assertEqual('arm-linux-', + tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_PATH)) + self.assertEqual('arm', + tc.GetEnvArgs(toolchain.VAR_ARCH)) + self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS)) + + self.toolchains.Add('/path/to/x86_64-linux-gcc', test=False) + tc = self.toolchains.Select('x86') + self.assertEqual('/path/to', + tc.GetEnvArgs(toolchain.VAR_PATH)) + tc.override_toolchain = 'clang' + self.assertEqual('HOSTCC=clang CC=clang', + tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS)) + if __name__ == "__main__": unittest.main() diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index cc26e2ede5..4f39bfd0ce 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -18,6 +18,8 @@ import tools (PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH, PRIORITY_CALC) = list(range(4)) +(VAR_CROSS_COMPILE, VAR_PATH, VAR_ARCH, VAR_MAKE_ARGS) = range(4) + # Simple class to collect links from a page class MyHTMLParser(HTMLParser): def __init__(self, arch): @@ -145,6 +147,30 @@ class Toolchain: return value + def GetEnvArgs(self, which): + """Get an environment variable/args value based on the the toolchain + + Args: + which: VAR_... value to get + + Returns: + Value of that environment variable or arguments + """ + wrapper = self.GetWrapper() + if which == VAR_CROSS_COMPILE: + return wrapper + os.path.join(self.path, self.cross) + elif which == VAR_PATH: + return self.path + elif which == VAR_ARCH: + return self.arch + elif which == VAR_MAKE_ARGS: + args = self.MakeArgs() + if args: + return ' '.join(args) + return '' + else: + raise ValueError('Unknown arg to GetEnvArgs (%d)' % which) + def MakeEnvironment(self, full_path): """Returns an environment for using the toolchain. @@ -435,9 +461,10 @@ class Toolchains: self._make_flags['target'] = board.target arg_str = self.ResolveReferences(self._make_flags, self._make_flags.get(board.target, '')) - args = arg_str.split(' ') + args = re.findall("(?:\".*?\"|\S)+", arg_str) i = 0 while i < len(args): + args[i] = args[i].replace('"', '') if not args[i]: del args[i] else: diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index 4ff0bffaef..24df13e500 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -403,18 +403,20 @@ def format_and_output(params_list, output): with open(output, 'w', encoding="utf-8") as f: f.write(COMMENT_BLOCK + '\n'.join(output_lines) + '\n') -def gen_boards_cfg(output, jobs=1, force=False): +def gen_boards_cfg(output, jobs=1, force=False, quiet=False): """Generate a board database file. Arguments: output: The name of the output file jobs: The number of jobs to run simultaneously force: Force to generate the output even if it is new + quiet: True to avoid printing a message if nothing needs doing """ check_top_directory() if not force and output_is_new(output): - print("%s is up to date. Nothing to do." % output) + if not quiet: + print("%s is up to date. Nothing to do." % output) sys.exit(0) params_list = scan_defconfigs(jobs) @@ -435,9 +437,11 @@ def main(): help='the number of jobs to run simultaneously') parser.add_option('-o', '--output', default=OUTPUT_FILE, help='output file [default=%s]' % OUTPUT_FILE) + parser.add_option('-q', '--quiet', action="store_true", help='run silently') (options, args) = parser.parse_args() - gen_boards_cfg(options.output, jobs=options.jobs, force=options.force) + gen_boards_cfg(options.output, jobs=options.jobs, force=options.force, + quiet=options.quiet) if __name__ == '__main__': main() |