mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-26 13:44:29 +08:00
Merge branch 'next' of https://gitlab.denx.de/u-boot/custodians/u-boot-x86 into next
- Various x86 common codes updated for TPL/SPL - I2C designware driver updated for PCI - ICH SPI driver updated to support Apollo Lake - Add Intel FSP2 base support - Intel Apollo Lake platform specific drivers support - Add a new board Google Chromebook Coral
This commit is contained in:
commit
c0912f9bbf
9
Kconfig
9
Kconfig
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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[] = {
|
||||
|
@ -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 },
|
||||
|
@ -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));
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
96
arch/x86/cpu/apollolake/Kconfig
Normal file
96
arch/x86/cpu/apollolake/Kconfig
Normal file
@ -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
|
27
arch/x86/cpu/apollolake/Makefile
Normal file
27
arch/x86/cpu/apollolake/Makefile
Normal file
@ -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
|
41
arch/x86/cpu/apollolake/cpu.c
Normal file
41
arch/x86/cpu/apollolake/cpu.c
Normal file
@ -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,
|
||||
};
|
17
arch/x86/cpu/apollolake/cpu_common.c
Normal file
17
arch/x86/cpu/apollolake/cpu_common.c
Normal file
@ -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);
|
||||
}
|
271
arch/x86/cpu/apollolake/cpu_spl.c
Normal file
271
arch/x86/cpu/apollolake/cpu_spl.c
Normal file
@ -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;
|
||||
}
|
210
arch/x86/cpu/apollolake/fsp_m.c
Normal file
210
arch/x86/cpu/apollolake/fsp_m.c
Normal file
@ -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;
|
||||
}
|
661
arch/x86/cpu/apollolake/fsp_s.c
Normal file
661
arch/x86/cpu/apollolake/fsp_s.c
Normal file
@ -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;
|
||||
}
|
179
arch/x86/cpu/apollolake/hostbridge.c
Normal file
179
arch/x86/cpu/apollolake/hostbridge.c
Normal file
@ -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),
|
||||
};
|
214
arch/x86/cpu/apollolake/itss.c
Normal file
214
arch/x86/cpu/apollolake/itss.c
Normal file
@ -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),
|
||||
};
|
122
arch/x86/cpu/apollolake/lpc.c
Normal file
122
arch/x86/cpu/apollolake/lpc.c
Normal file
@ -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,
|
||||
};
|
166
arch/x86/cpu/apollolake/p2sb.c
Normal file
166
arch/x86/cpu/apollolake/p2sb.c
Normal file
@ -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,
|
||||
};
|
36
arch/x86/cpu/apollolake/pch.c
Normal file
36
arch/x86/cpu/apollolake/pch.c
Normal file
@ -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,
|
||||
};
|
216
arch/x86/cpu/apollolake/pmc.c
Normal file
216
arch/x86/cpu/apollolake/pmc.c
Normal file
@ -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),
|
||||
};
|
94
arch/x86/cpu/apollolake/punit.c
Normal file
94
arch/x86/cpu/apollolake/punit.c
Normal file
@ -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,
|
||||
};
|
178
arch/x86/cpu/apollolake/spl.c
Normal file
178
arch/x86/cpu/apollolake/spl.c
Normal file
@ -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
|
23
arch/x86/cpu/apollolake/systemagent.c
Normal file
23
arch/x86/cpu/apollolake/systemagent.c
Normal file
@ -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);
|
||||
}
|
133
arch/x86/cpu/apollolake/uart.c
Normal file
133
arch/x86/cpu/apollolake/uart.c
Normal file
@ -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,
|
||||
};
|
@ -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;
|
||||
|
||||
|
@ -24,5 +24,6 @@ config SYS_COREBOOT
|
||||
imply CMD_CBFS
|
||||
imply FS_CBFS
|
||||
imply CBMEM_CONSOLE
|
||||
imply X86_TSC_READ_BASE
|
||||
|
||||
endif
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
448
arch/x86/cpu/intel_common/car2.S
Normal file
448
arch/x86/cpu/intel_common/car2.S
Normal file
@ -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
|
87
arch/x86/cpu/intel_common/car2_uninit.S
Normal file
87
arch/x86/cpu/intel_common/car2_uninit.S
Normal file
@ -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
|
73
arch/x86/cpu/intel_common/fast_spi.c
Normal file
73
arch/x86/cpu/intel_common/fast_spi.c
Normal file
@ -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;
|
||||
}
|
44
arch/x86/cpu/intel_common/lpss.c
Normal file
44
arch/x86/cpu/intel_common/lpss.c
Normal file
@ -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);
|
||||
}
|
@ -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",
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
73
arch/x86/cpu/qfw_cpu.c
Normal file
73
arch/x86/cpu/qfw_cpu.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -17,3 +17,4 @@ config SYS_SLIMBOOTLOADER
|
||||
imply USB_EHCI_HCD
|
||||
imply USB_XHCI_HCD
|
||||
imply E1000
|
||||
imply X86_TSC_READ_BASE
|
||||
|
@ -17,7 +17,10 @@ SECTIONS
|
||||
|
||||
. = IMAGE_TEXT_BASE; /* Location of bootcode in flash */
|
||||
__text_start = .;
|
||||
.text : { *(.text*); }
|
||||
.text : {
|
||||
__image_copy_start = .;
|
||||
*(.text*);
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
dtb-y += bayleybay.dtb \
|
||||
cherryhill.dtb \
|
||||
chromebook_coral.dtb \
|
||||
chromebook_link.dtb \
|
||||
chromebox_panther.dtb \
|
||||
chromebook_samus.dtb \
|
||||
|
831
arch/x86/dts/chromebook_coral.dts
Normal file
831
arch/x86/dts/chromebook_coral.dts
Normal file
@ -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 */
|
||||
>;
|
||||
};
|
@ -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>;
|
||||
#else
|
||||
offset = <CONFIG_SYS_TEXT_BASE>;
|
||||
#endif
|
||||
offset = <CONFIG_X86_OFFSET_U_BOOT>;
|
||||
};
|
||||
#else
|
||||
# ifdef CONFIG_SPL
|
||||
u-boot {
|
||||
offset = <CONFIG_SYS_TEXT_BASE>;
|
||||
};
|
||||
# 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
|
||||
|
20
arch/x86/include/asm/arch-apollolake/cpu.h
Normal file
20
arch/x86/include/asm/arch-apollolake/cpu.h
Normal file
@ -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 */
|
14
arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
Normal file
14
arch/x86/include/asm/arch-apollolake/fsp/fsp_configs.h
Normal file
@ -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
|
123
arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
Normal file
123
arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h
Normal file
@ -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
|
292
arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
Normal file
292
arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h
Normal file
@ -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
|
11
arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h
Normal file
11
arch/x86/include/asm/arch-apollolake/fsp/fsp_vpd.h
Normal file
@ -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
|
485
arch/x86/include/asm/arch-apollolake/gpio.h
Normal file
485
arch/x86/include/asm/arch-apollolake/gpio.h
Normal file
@ -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_ */
|
29
arch/x86/include/asm/arch-apollolake/iomap.h
Normal file
29
arch/x86/include/asm/arch-apollolake/iomap.h
Normal file
@ -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
|
43
arch/x86/include/asm/arch-apollolake/itss.h
Normal file
43
arch/x86/include/asm/arch-apollolake/itss.h
Normal file
@ -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 */
|
82
arch/x86/include/asm/arch-apollolake/lpc.h
Normal file
82
arch/x86/include/asm/arch-apollolake/lpc.h
Normal file
@ -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
|
9
arch/x86/include/asm/arch-apollolake/pch.h
Normal file
9
arch/x86/include/asm/arch-apollolake/pch.h
Normal file
@ -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 */
|
19
arch/x86/include/asm/arch-apollolake/pm.h
Normal file
19
arch/x86/include/asm/arch-apollolake/pm.h
Normal file
@ -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
|
37
arch/x86/include/asm/arch-apollolake/systemagent.h
Normal file
37
arch/x86/include/asm/arch-apollolake/systemagent.h
Normal file
@ -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
|
20
arch/x86/include/asm/arch-apollolake/uart.h
Normal file
20
arch/x86/include/asm/arch-apollolake/uart.h
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
68
arch/x86/include/asm/fast_spi.h
Normal file
68
arch/x86/include/asm/fast_spi.h
Normal file
@ -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 */
|
24
arch/x86/include/asm/fsp/fsp_api.h
Normal file
24
arch/x86/include/asm/fsp/fsp_api.h
Normal file
@ -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
|
@ -143,13 +143,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
|
||||
*
|
||||
|
@ -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
|
||||
|
63
arch/x86/include/asm/fsp2/fsp_api.h
Normal file
63
arch/x86/include/asm/fsp2/fsp_api.h
Normal file
@ -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
|
97
arch/x86/include/asm/fsp2/fsp_internal.h
Normal file
97
arch/x86/include/asm/fsp2/fsp_internal.h
Normal file
@ -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
|
@ -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
|
||||
|
306
arch/x86/include/asm/intel_pinctrl.h
Normal file
306
arch/x86/include/asm/intel_pinctrl.h
Normal file
@ -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
|
373
arch/x86/include/asm/intel_pinctrl_defs.h
Normal file
373
arch/x86/include/asm/intel_pinctrl_defs.h
Normal file
@ -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_ */
|
36
arch/x86/include/asm/lpss.h
Normal file
36
arch/x86/include/asm/lpss.h
Normal file
@ -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
|
@ -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;
|
||||
|
||||
/**
|
||||
@ -40,21 +48,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
|
||||
*
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
enum {
|
||||
BOOT_DEVICE_SPI_MMAP = 10,
|
||||
BOOT_DEVICE_FAST_SPI,
|
||||
BOOT_DEVICE_CROS_VBOOT,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
10
arch/x86/lib/fsp2/Makefile
Normal file
10
arch/x86/lib/fsp2/Makefile
Normal file
@ -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
|
13
arch/x86/lib/fsp2/fsp_common.c
Normal file
13
arch/x86/lib/fsp2/fsp_common.c
Normal file
@ -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;
|
||||
}
|
78
arch/x86/lib/fsp2/fsp_dram.c
Normal file
78
arch/x86/lib/fsp2/fsp_dram.c
Normal file
@ -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;
|
||||
}
|
191
arch/x86/lib/fsp2/fsp_init.c
Normal file
191
arch/x86/lib/fsp2/fsp_init.c
Normal file
@ -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
|
97
arch/x86/lib/fsp2/fsp_meminit.c
Normal file
97
arch/x86/lib/fsp2/fsp_meminit.c
Normal file
@ -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;
|
||||
}
|
54
arch/x86/lib/fsp2/fsp_silicon_init.c
Normal file
54
arch/x86/lib/fsp2/fsp_silicon_init.c
Normal file
@ -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;
|
||||
}
|
131
arch/x86/lib/fsp2/fsp_support.c
Normal file
131
arch/x86/lib/fsp2/fsp_support.c
Normal file
@ -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;
|
||||
}
|
@ -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,82 +180,136 @@ 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;
|
||||
/*
|
||||
* 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];
|
||||
}
|
||||
|
||||
if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2)) {
|
||||
debug("%s: Cannot find memory map\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
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 (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;
|
||||
}
|
||||
|
||||
static int mrccache_save_type(enum mrc_type_t type)
|
||||
{
|
||||
struct mrc_data_container *cache;
|
||||
struct mrc_output *mrc;
|
||||
struct mrc_region entry;
|
||||
struct udevice *sf;
|
||||
int ret;
|
||||
|
||||
mrc = &gd->arch.mrc[type];
|
||||
if (!mrc->len)
|
||||
return 0;
|
||||
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)
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
@ -239,47 +317,21 @@ int mrccache_get_region(struct udevice **devp, struct mrc_region *entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mrccache_save(void)
|
||||
{
|
||||
struct mrc_data_container *data;
|
||||
struct mrc_region entry;
|
||||
struct udevice *sf;
|
||||
int ret;
|
||||
|
||||
if (!gd->arch.mrc_output_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);
|
||||
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) {
|
||||
debug("MRC data is the same as last time, skipping save\n");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
err_entry:
|
||||
if (ret)
|
||||
debug("%s: Failed: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mrccache_spl_save(void)
|
||||
{
|
||||
void *data;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user