diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-05-12 18:23:27 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-07-16 17:24:48 +0200 |
commit | 1d14b3e926c15027f9272f1e80b8913fef8cf25d (patch) | |
tree | b3d89ad4bb1b0ea5ac05d1d7dc6cbf26ec93e6c3 /src | |
parent | b000513741d330947bb832a5835378e35bdfb394 (diff) | |
download | coreboot-1d14b3e926c15027f9272f1e80b8913fef8cf25d.tar.xz |
soc/intel: Add Skylake SOC support
Add the files to support the Skylake SOC.
Matches chromium tree at 927026db
BRANCH=none
BUG=None
TEST=Build and run on a Skylake platform
Change-Id: I80248f7e47eaf13b52e3c7ff951eb1976edbaa15
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10341
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src')
118 files changed, 5614 insertions, 10263 deletions
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 0864e57cc9..24fd961951 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -8,36 +8,41 @@ if SOC_INTEL_SKYLAKE config CPU_SPECIFIC_OPTIONS def_bool y select ARCH_BOOTBLOCK_X86_32 - select ARCH_VERSTAGE_X86_32 - select ARCH_ROMSTAGE_X86_32 select ARCH_RAMSTAGE_X86_32 - select ALT_CBFS_LOAD_PAYLOAD + select ARCH_ROMSTAGE_X86_32 + select ARCH_VERSTAGE_X86_32 select ALWAYS_LOAD_OPROM select BACKUP_DEFAULT_SMM_REGION - select CACHE_MRC_BIN select CACHE_MRC_SETTINGS - select MRC_SETTINGS_PROTECT select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select CACHE_ROM select CAR_MIGRATION select COLLECT_TIMESTAMPS select CPU_INTEL_FIRMWARE_INTERFACE_TABLE - select SUPPORT_CPU_UCODE_IN_CBFS + select CPU_MICROCODE_IN_CBFS + select HAS_PRECBMEM_TIMESTAMP_REGION + select HAVE_HARD_RESET select HAVE_MONOTONIC_TIMER select HAVE_SMI_HANDLER - select HAVE_HARD_RESET - select HAVE_USBDEBUG select IOAPIC select MMCONF_SUPPORT select MMCONF_SUPPORT_DEFAULT - select RELOCATABLE_MODULES - select RELOCATABLE_RAMSTAGE - select REG_SCRIPT select PARALLEL_MP select PCIEXP_ASPM select PCIEXP_COMMON_CLOCK select PCIEXP_CLK_PM - select PCIEXP_L1_SUB_STATE + # External devices not working on glados + #select PCIEXP_L1_SUB_STATE + select PLATFORM_USES_FSP1_1 + select REG_SCRIPT + select RELOCATABLE_MODULES + select RELOCATABLE_RAMSTAGE + select SOC_INTEL_COMMON + select SOC_INTEL_COMMON_FSP_RAM_INIT + select SOC_INTEL_COMMON_FSP_ROMSTAGE + select SOC_INTEL_COMMON_RESET + select SOC_INTEL_COMMON_STACK + select SOC_INTEL_COMMON_STAGE_CACHE select SMM_MODULES select SMM_TSEG select SMP @@ -47,8 +52,7 @@ config CPU_SPECIFIC_OPTIONS select TSC_CONSTANT_RATE select TSC_SYNC_MFENCE select UDELAY_TSC - select PER_DEVICE_ACPI_TABLES - select SOC_INTEL_COMMON + select USE_GENERIC_FSP_CAR_INC config BOOTBLOCK_CPU_INIT string @@ -58,94 +62,17 @@ config BOOTBLOCK_NORTHBRIDGE_INIT string default "soc/intel/skylake/bootblock/systemagent.c" -config BOOTBLOCK_SOUTHBRIDGE_INIT +config BOOTBLOCK_RESETS string - default "soc/intel/skylake/bootblock/pch.c" + default "soc/intel/common/reset.c" - -config MMCONF_BASE_ADDRESS - hex - default 0xf0000000 - -config SERIAL_CPU_INIT - bool - default n - -config SMM_TSEG_SIZE - hex - default 0x800000 - -config IED_REGION_SIZE - hex - default 0x400000 - -config SMM_RESERVED_SIZE - hex - default 0x100000 - -config VGA_BIOS_ID +config BOOTBLOCK_SOUTHBRIDGE_INIT string - default "8086,0406" - -config CACHE_MRC_SIZE_KB - int - default 512 - -config DCACHE_RAM_BASE - hex - default 0xff7c0000 - -config DCACHE_RAM_SIZE - hex - default 0x10000 - help - The size of the cache-as-ram region required during bootblock - and/or romstage. Note DCACHE_RAM_SIZE and DCACHE_RAM_MRC_VAR_SIZE - must add up to a power of 2. - -config DCACHE_RAM_MRC_VAR_SIZE - hex - default 0x30000 - help - The amount of cache-as-ram region required by the reference code. - -config DCACHE_RAM_ROMSTAGE_STACK_SIZE - hex - default 0x2000 - help - The amount of anticipated stack usage from the data cache - during pre-ram rom stage execution. - -config HAVE_MRC - bool "Add a Memory Reference Code binary" - help - Select this option to add a Memory Reference Code binary to - the resulting coreboot image. - - Note: Without this binary coreboot will not work - -if HAVE_MRC - -config MRC_FILE - string "Intel Memory Reference Code path and filename" - depends on HAVE_MRC - default "mrc.bin" - help - The filename of the file to use as Memory Reference Code binary. - -config MRC_BIN_ADDRESS - hex - default 0xfffa0000 - -config CACHE_MRC_SETTINGS - bool "Save cached MRC settings" - default y - -endif # HAVE_MRC + default "soc/intel/skylake/bootblock/pch.c" config CBFS_SIZE hex "Size of CBFS filesystem in ROM" - default 0x100000 + default 0x200000 help The firmware image has to store more than just coreboot, including: - a firmware descriptor @@ -154,72 +81,25 @@ config CBFS_SIZE This option allows to limit the size of the CBFS portion in the firmware image. -config PRE_GRAPHICS_DELAY - int "Graphics initialization delay in ms" - default 0 - help - On some systems, coreboot boots so fast that connected monitors - (mostly TVs) won't be able to wake up fast enough to talk to the - VBIOS. On those systems we need to wait for a bit before executing - the VBIOS. - -config RESET_ON_INVALID_RAMSTAGE_CACHE - bool "Reset the system on S3 wake when ramstage cache invalid." - default n - depends on RELOCATABLE_RAMSTAGE - help - The romstage code caches the loaded ramstage program in SMM space. - On S3 wake the romstage will copy over a fresh ramstage that was - cached in the SMM space. This option determines the action to take - when the ramstage cache is invalid. If selected the system will - reset otherwise the ramstage will be reloaded from cbfs. - -config INTEL_PCH_UART_CONSOLE - bool "Use Serial IO UART for console" - default n - select HAVE_UART_MEMORY_MAPPED - select CONSOLE_SERIAL8250MEM - depends on !CONFIG_DRIVERS_OXFORD_OXPCIE - -config INTEL_PCH_UART_CONSOLE_NUMBER - hex "Serial IO UART number to use for console" - default "0x0" - depends on INTEL_PCH_UART_CONSOLE - -config TTYS0_BASE - hex - default 0xd6000000 - depends on INTEL_PCH_UART_CONSOLE - -config EHCI_BAR - hex - default 0xd8000000 +config CPU_ADDR_BITS + int + default 36 -config EHCI_DEBUG_OFFSET - hex - default 0xa0 +config DCACHE_RAM_BASE + hex "Base address of cache-as-RAM" + default 0xfef00000 -config SERIRQ_CONTINUOUS_MODE - bool - default y - help - If you set this option to y, the serial IRQ machine will be - operated in continuous mode. -config HAVE_ME_BIN - bool "Add Intel Management Engine firmware" - default y +config DCACHE_RAM_SIZE + hex "Length in bytes of cache-as-RAM" + default 0x4000 help - The Intel processor in the selected system requires a special firmware - for an integrated controller called Management Engine (ME). The ME - firmware might be provided in coreboot's 3rdparty/blobs repository. If - not and if you don't have the firmware elsewhere, you can still - build coreboot without it. In this case however, you'll have to make - sure that you don't overwrite your ME firmware on your flash ROM. + The size of the cache-as-ram region required during bootblock + and/or romstage. -config ME_BIN_PATH - string "Path to management engine firmware" - depends on HAVE_ME_BIN - default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin" +config EXTRA_MICROCODE_INCLUDE_PATH + string "Include path for extra microcode patches." + help + The path to any extra microcode patches from other sources. config HAVE_IFD_BIN bool "Use Intel Firmware Descriptor from existing binary" @@ -242,6 +122,30 @@ config BUILD_WITH_FAKE_IFD [1] http://www.flashrom.org/pipermail/flashrom/2013-June/011083.html +config HAVE_ME_BIN + bool "Add Intel Management Engine firmware" + default y + help + The Intel processor in the selected system requires a special firmware + for an integrated controller called Management Engine (ME). The ME + firmware might be provided in coreboot's 3rdparty/blobs repository. If + not and if you don't have the firmware elsewhere, you can still + build coreboot without it. In this case however, you'll have to make + sure that you don't overwrite your ME firmware on your flash ROM. + +config HEAP_SIZE + hex + default 0x80000 + +config IED_REGION_SIZE + hex + default 0x400000 + +config IFD_BIN_PATH + string "Path to intel firmware descriptor" + depends on !BUILD_WITH_FAKE_IFD + default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin" + config IFD_BIOS_SECTION depends on BUILD_WITH_FAKE_IFD string @@ -257,22 +161,72 @@ config IFD_PLATFORM_SECTION string default "" -config IFD_BIN_PATH - string "Path to intel firmware descriptor" - depends on !BUILD_WITH_FAKE_IFD - default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin" +config INTEL_PCH_UART_CONSOLE + bool "Use Serial IO UART for console" + default n + select HAVE_UART_MEMORY_MAPPED + select CONSOLE_SERIAL8250MEM + depends on !CONFIG_DRIVERS_OXFORD_OXPCIE -config LOCK_MANAGEMENT_ENGINE - bool "Lock Management Engine section" +config INTEL_PCH_UART_CONSOLE_NUMBER + hex "Serial IO UART number to use for console" + default "0x0" + depends on INTEL_PCH_UART_CONSOLE + +config ME_BIN_PATH + string "Path to management engine firmware" + depends on HAVE_ME_BIN + default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/me.bin" + +config MICROCODE_INCLUDE_PATH + string + default "src/soc/intel/skylake/microcode" + +config MMCONF_BASE_ADDRESS + hex "MMIO Base Address" + default 0xe0000000 + +config MONOTONIC_TIMER_MSR + def_bool y + select HAVE_MONOTONIC_TIMER + help + Provide a monotonic timer using the 24MHz MSR counter. + +config PRE_GRAPHICS_DELAY + int "Graphics initialization delay in ms" + default 0 + help + On some systems, coreboot boots so fast that connected monitors + (mostly TVs) won't be able to wake up fast enough to talk to the + VBIOS. On those systems we need to wait for a bit before executing + the VBIOS. + +config SERIAL_CPU_INIT + bool default n + +config SERIRQ_CONTINUOUS_MODE + bool + default y help - The Intel Management Engine supports preventing write accesses - from the host to the Management Engine section in the firmware - descriptor. If the ME section is locked, it can only be overwritten - with an external SPI flash programmer. You will want this if you - want to increase security of your ROM image once you are sure - that the ME firmware is no longer going to change. - - If unsure, say N. + If you set this option to y, the serial IRQ machine will be + operated in continuous mode. + +config SMM_RESERVED_SIZE + hex + default 0x200000 + +config SMM_TSEG_SIZE + hex + default 0x800000 + +config TTYS0_BASE + hex + default 0xfe034000 + depends on INTEL_PCH_UART_CONSOLE + +config VGA_BIOS_ID + string + default "8086,0406" endif diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index dafceb7e22..af299c3c74 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -3,81 +3,78 @@ ifeq ($(CONFIG_SOC_INTEL_SKYLAKE),y) subdirs-y += bootblock subdirs-y += microcode subdirs-y += romstage +subdirs-y += ../common +subdirs-y += ../../../cpu/intel/microcode +subdirs-y += ../../../cpu/intel/turbo subdirs-y += ../../../cpu/x86/lapic subdirs-y += ../../../cpu/x86/mtrr subdirs-y += ../../../cpu/x86/smm subdirs-y += ../../../cpu/x86/tsc -subdirs-y += ../../../cpu/intel/microcode -subdirs-y += ../../../cpu/intel/turbo -ramstage-y += acpi.c -ramstage-y += adsp.c +romstage-y += gpio.c +romstage-y += memmap.c +romstage-y += pch.c +romstage-y += pcr.c +romstage-y += pei_data.c +romstage-y += pmutil.c +romstage-y += smbus_common.c +romstage-y += tsc_freq.c + +ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += cpu_info.c -smm-y += cpu_info.c -ramstage-$(CONFIG_ELOG) += elog.c +ramstage-y += elog.c ramstage-y += finalize.c +ramstage-y += flash_controller.c ramstage-y += gpio.c -romstage-y += gpio.c -smm-y += gpio.c -ramstage-y += hda.c ramstage-y += igd.c -ramstage-y += iobp.c -romstage-y += iobp.c ramstage-y += lpc.c -ramstage-y += me.c -ramstage-y += me_status.c -romstage-y += me_status.c ramstage-y += memmap.c -romstage-y += memmap.c -ramstage-y += minihd.c ramstage-y += monotonic_timer.c -smm-y += monotonic_timer.c ramstage-y += pch.c -romstage-y += pch.c ramstage-y += pcie.c +ramstage-y += pcr.c ramstage-y += pei_data.c -romstage-y += pei_data.c +ramstage-y += pmc.c ramstage-y += pmutil.c -romstage-y += pmutil.c -smm-y += pmutil.c ramstage-y += ramstage.c -ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c -ramstage-y += reset.c -romstage-y += reset.c -ramstage-y += sata.c -ramstage-y += serialio.c ramstage-y += smbus.c ramstage-y += smbus_common.c -romstage-y += smbus_common.c ramstage-y += smi.c -smm-y += smihandler.c ramstage-y += smmrelocate.c -ramstage-y += spi.c -smm-$(CONFIG_SPI_FLASH_SMM) += spi.c -ramstage-y += stage_cache.c -romstage-y += stage_cache.c ramstage-y += systemagent.c ramstage-y += tsc_freq.c -romstage-y += tsc_freq.c -smm-y += tsc_freq.c -ramstage-y += ehci.c +ramstage-y += uart.c ramstage-y += xhci.c -smm-y += xhci.c -ifeq ($(CONFIG_USBDEBUG),y) -ramstage-y += usbdebug.c -romstage-y += usbdebug.c -smm-y += usbdebug.c -endif +smm-y += cpu_info.c +smm-y += gpio.c +smm-y += monotonic_timer.c +smm-y += pcr.c +smm-y += pch.c +smm-y += pmutil.c +smm-y += smihandler.c +smm-$(CONFIG_SPI_FLASH_SMM) += flash_controller.c +smm-y += tsc_freq.c + +CPPFLAGS_common += -I$(src)/arch/x86/include/ +CPPFLAGS_common += -I$(src)/soc/intel/skylake +CPPFLAGS_common += -I$(src)/soc/intel/skylake/include -CPPFLAGS_common += -Isrc/soc/intel/broadwell/include +CPPFLAGS_common += -I3rdparty/blobs/mainboard/$(CONFIG_MAINBOARD_DIR) + +CPPFLAGS_common += -I$(src)/drivers/intel/fsp1_1 +CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp1_1 +CPPFLAGS_common += -I$(src)/vendorcode/intel/edk2/uefi_2.4 +CPPFLAGS_common += -I$(src)/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include +CPPFLAGS_common += -I$(src)/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include/Ia32 +CPPFLAGS_common += -I$(CONFIG_FSP_INCLUDE_PATH) # Run an intermediate step when producing coreboot.rom # that adds additional components to the final firmware # image outside of CBFS -INTERMEDIATE := broadwell_add_me +INTERMEDIATE := pch_add_me ifeq ($(CONFIG_BUILD_WITH_FAKE_IFD),y) IFD_BIN_PATH := $(objgenerated)/ifdfake.bin @@ -88,7 +85,7 @@ else IFD_BIN_PATH := $(CONFIG_IFD_BIN_PATH) endif -broadwell_add_me: $(obj)/coreboot.pre $(IFDTOOL) $(IFDFAKE) +pch_add_me: $(obj)/coreboot.pre $(IFDTOOL) $(IFDFAKE) ifeq ($(CONFIG_BUILD_WITH_FAKE_IFD),y) printf "\n** WARNING **\n" printf "Coreboot will be built with a fake Intel Firmware Descriptor (IFD).\n" @@ -106,29 +103,8 @@ ifeq ($(CONFIG_HAVE_ME_BIN),y) -i ME:$(CONFIG_ME_BIN_PATH) \ $(obj)/coreboot.pre mv $(obj)/coreboot.pre.new $(obj)/coreboot.pre -ifeq ($(CONFIG_LOCK_MANAGEMENT_ENGINE),y) - printf " IFDTOOL Locking Management Engine\n" - $(objutil)/ifdtool/ifdtool -l $(obj)/coreboot.pre - mv $(obj)/coreboot.pre.new $(obj)/coreboot.pre -else - printf " IFDTOOL Unlocking Management Engine\n" - $(objutil)/ifdtool/ifdtool -u $(obj)/coreboot.pre - mv $(obj)/coreboot.pre.new $(obj)/coreboot.pre endif -endif - -PHONY += broadwell_add_me - -# If an MRC file is an ELF file determine the entry address and first loadable -# section offset in the file. Subtract the offset from the entry address to -# determine the final location. -mrcelfoffset = $(shell $(READELF_x86_32) -S -W $(CONFIG_MRC_FILE) | sed -e 's/\[ /[0/' | awk '$$3 ~ /PROGBITS/ { print "0x"$$5; exit }' ) -mrcelfentry = $(shell $(READELF_x86_32) -h -W $(CONFIG_MRC_FILE) | grep 'Entry point address' | awk '{print $$NF }') -# Add memory reference code blob. -cbfs-files-$(CONFIG_HAVE_MRC) += mrc.bin -mrc.bin-file := $(call strip_quotes,$(CONFIG_MRC_FILE)) -mrc.bin-position := $(if $(findstring elf,$(CONFIG_MRC_FILE)),$(shell printf "0x%x" $$(( $(mrcelfentry) - $(mrcelfoffset) )) ),$(CONFIG_MRC_BIN_ADDRESS)) -mrc.bin-type := mrc +PHONY += pch_add_me endif diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index f038e87e5a..1b193c7308 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -3,6 +3,7 @@ * * Copyright (C) 2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/acpi.h> @@ -23,9 +24,10 @@ #include <arch/io.h> #include <arch/smp/mpspec.h> #include <cbmem.h> +#include <chip.h> #include <console/console.h> +#include <cpu/cpu.h> #include <cpu/x86/smm.h> -#include <console/console.h> #include <types.h> #include <string.h> #include <arch/cpu.h> @@ -41,36 +43,33 @@ #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/intel/broadwell/chip.h> /* - * List of supported C-states in this processor. Only the ULT parts support C8, - * C9, and C10. + * List of suported C-states in this processor. */ enum { - C_STATE_C0, /* 0 */ - C_STATE_C1, /* 1 */ - C_STATE_C1E, /* 2 */ - C_STATE_C3, /* 3 */ - C_STATE_C6_SHORT_LAT, /* 4 */ - C_STATE_C6_LONG_LAT, /* 5 */ - C_STATE_C7_SHORT_LAT, /* 6 */ - C_STATE_C7_LONG_LAT, /* 7 */ - C_STATE_C7S_SHORT_LAT, /* 8 */ - C_STATE_C7S_LONG_LAT, /* 9 */ - C_STATE_C8, /* 10 */ - C_STATE_C9, /* 11 */ - C_STATE_C10, /* 12 */ + C_STATE_C0, /* 0 */ + C_STATE_C1, /* 1 */ + C_STATE_C1E, /* 2 */ + C_STATE_C3, /* 3 */ + C_STATE_C6_SHORT_LAT, /* 4 */ + C_STATE_C6_LONG_LAT, /* 5 */ + C_STATE_C7_SHORT_LAT, /* 6 */ + C_STATE_C7_LONG_LAT, /* 7 */ + C_STATE_C7S_SHORT_LAT, /* 8 */ + C_STATE_C7S_LONG_LAT, /* 9 */ + C_STATE_C8, /* 10 */ + C_STATE_C9, /* 11 */ + C_STATE_C10, /* 12 */ NUM_C_STATES }; - -#define MWAIT_RES(state, sub_state) \ - { \ - .addrl = (((state) << 4) | (sub_state)), \ - .space_id = ACPI_ADDRESS_SPACE_FIXED, \ - .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \ - .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \ - .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \ +#define MWAIT_RES(state, sub_state) \ + { \ + .addrl = (((state) << 4) | (sub_state)), \ + .space_id = ACPI_ADDRESS_SPACE_FIXED, \ + .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \ + .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \ + .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \ } static acpi_cstate_t cstate_map[NUM_C_STATES] = { @@ -78,75 +77,78 @@ static acpi_cstate_t cstate_map[NUM_C_STATES] = { [C_STATE_C1] = { .latency = 0, .power = 1000, - .resource = MWAIT_RES(0,0), + .resource = MWAIT_RES(0, 0), }, [C_STATE_C1E] = { .latency = 0, .power = 1000, - .resource = MWAIT_RES(0,1), + .resource = MWAIT_RES(0, 1), }, [C_STATE_C3] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(0), - .power = 900, + .power = 500, .resource = MWAIT_RES(1, 0), }, [C_STATE_C6_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 800, + .power = 350, .resource = MWAIT_RES(2, 0), }, [C_STATE_C6_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 800, + .power = 350, .resource = MWAIT_RES(2, 1), }, [C_STATE_C7_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 0), }, [C_STATE_C7_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 1), }, [C_STATE_C7S_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 2), }, [C_STATE_C7S_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 3), }, [C_STATE_C8] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(3), - .power = 600, + .power = 200, .resource = MWAIT_RES(4, 0), }, [C_STATE_C9] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(4), - .power = 500, + .power = 200, .resource = MWAIT_RES(5, 0), }, [C_STATE_C10] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(5), - .power = 400, + .power = 200, .resource = MWAIT_RES(6, 0), }, }; -static int cstate_set_s0ix[3] = { +static int cstate_set_s0ix[] = { C_STATE_C1E, C_STATE_C7S_LONG_LAT, C_STATE_C10 }; -static int cstate_set_non_s0ix[3] = { +static int cstate_set_non_s0ix[] = { C_STATE_C1E, C_STATE_C3, - C_STATE_C7S_LONG_LAT + C_STATE_C7S_LONG_LAT, + C_STATE_C8, + C_STATE_C9, + C_STATE_C10 }; static int get_cores_per_package(void) @@ -173,15 +175,15 @@ void acpi_init_gnvs(global_nvs_t *gnvs) /* CPU core count */ gnvs->pcnt = dev_count_cpu(); -#if CONFIG_CONSOLE_CBMEM +#if IS_ENABLED(CONFIG_CONSOLE_CBMEM) /* Update the mem console pointer. */ gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE); #endif -#if CONFIG_CHROMEOS +#if IS_ENABLED(CONFIG_CHROMEOS) /* Initialize Verified Boot data */ chromeos_init_vboot(&(gnvs->chromeos)); -#if CONFIG_EC_GOOGLE_CHROMEEC +#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) gnvs->chromeos.vbt2 = google_ec_running_ro() ? ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; #endif @@ -189,37 +191,6 @@ void acpi_init_gnvs(global_nvs_t *gnvs) #endif } -void acpi_create_intel_hpet(acpi_hpet_t * hpet) -{ - acpi_header_t *header = &(hpet->header); - acpi_addr_t *addr = &(hpet->addr); - - memset((void *) hpet, 0, sizeof(acpi_hpet_t)); - - /* fill out header fields */ - memcpy(header->signature, "HPET", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_hpet_t); - header->revision = 1; - - /* fill out HPET address */ - addr->space_id = 0; /* Memory */ - addr->bit_width = 64; - addr->bit_offset = 0; - addr->addrl = (unsigned long long)HPET_BASE_ADDRESS & 0xffffffff; - addr->addrh = (unsigned long long)HPET_BASE_ADDRESS >> 32; - - hpet->id = 0x8086a201; /* Intel */ - hpet->number = 0x00; - hpet->min_tick = 0x0080; - - header->checksum = - acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); -} - unsigned long acpi_fill_mcfg(unsigned long current) { current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, @@ -336,82 +307,25 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } -static acpi_tstate_t tss_table_fine[] = { - { 100, 1000, 0, 0x00, 0 }, - { 94, 940, 0, 0x1f, 0 }, - { 88, 880, 0, 0x1e, 0 }, - { 82, 820, 0, 0x1d, 0 }, - { 75, 760, 0, 0x1c, 0 }, - { 69, 700, 0, 0x1b, 0 }, - { 63, 640, 0, 0x1a, 0 }, - { 57, 580, 0, 0x19, 0 }, - { 50, 520, 0, 0x18, 0 }, - { 44, 460, 0, 0x17, 0 }, - { 38, 400, 0, 0x16, 0 }, - { 32, 340, 0, 0x15, 0 }, - { 25, 280, 0, 0x14, 0 }, - { 19, 220, 0, 0x13, 0 }, - { 13, 160, 0, 0x12, 0 }, -}; - -static acpi_tstate_t tss_table_coarse[] = { - { 100, 1000, 0, 0x00, 0 }, - { 88, 875, 0, 0x1f, 0 }, - { 75, 750, 0, 0x1e, 0 }, - { 63, 625, 0, 0x1d, 0 }, - { 50, 500, 0, 0x1c, 0 }, - { 38, 375, 0, 0x1b, 0 }, - { 25, 250, 0, 0x1a, 0 }, - { 13, 125, 0, 0x19, 0 }, -}; - -static int generate_T_state_entries(int core, int cores_per_package) +static void generate_c_state_entries(int s0ix_enable, int max_cstate) { - int len; - - /* Indicate SW_ALL coordination for T-states */ - len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL); - - /* Indicate FFixedHW so OS will use MSR */ - len += acpigen_write_empty_PTC(); - - /* Set a T-state limit that can be modified in NVS */ - len += acpigen_write_TPC("\\TLVL"); - - /* - * CPUID.(EAX=6):EAX[5] indicates support - * for extended throttle levels. - */ - if (cpuid_eax(6) & (1 << 5)) - len += acpigen_write_TSS_package( - ARRAY_SIZE(tss_table_fine), tss_table_fine); - else - len += acpigen_write_TSS_package( - ARRAY_SIZE(tss_table_coarse), tss_table_coarse); - - return len; -} -static int generate_C_state_entries(void) -{ - device_t dev = SA_DEV_ROOT; - config_t *config = dev->chip_info; - acpi_cstate_t map[3]; + acpi_cstate_t map[max_cstate]; int *set; int i; - if (config->s0ix_enable) + if (s0ix_enable) set = cstate_set_s0ix; else set = cstate_set_non_s0ix; - for (i = 0; i < 3; i++) { + for (i = 0; i < max_cstate; i++) { memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); map[i].ctype = i + 1; } /* Generate C-state tables */ - return acpigen_write_CST_package(map, ARRAY_SIZE(map)); + acpigen_write_CST_package(map, ARRAY_SIZE(map)); } static int calculate_power(int tdp, int p1_ratio, int ratio) @@ -435,7 +349,7 @@ static int calculate_power(int tdp, int p1_ratio, int ratio) return (int)power; } -static void generate_P_state_entries(int core, int cores_per_package) +static void generate_p_state_entries(int core, int cores_per_package) { int ratio_min, ratio_max, ratio_turbo, ratio_step; int coord_type, power_max, power_unit, num_entries; @@ -484,10 +398,10 @@ static void generate_P_state_entries(int core, int cores_per_package) /* Determine ratio points */ ratio_step = PSS_RATIO_STEP; - num_entries = (ratio_max - ratio_min) / ratio_step; - while (num_entries > PSS_MAX_ENTRIES-1) { - ratio_step <<= 1; - num_entries >>= 1; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; + if (num_entries > PSS_MAX_ENTRIES) { + ratio_step += 1; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; } /* P[T] is Turbo state if enabled */ @@ -500,12 +414,12 @@ static void generate_P_state_entries(int core, int cores_per_package) /* Add entry for Turbo ratio */ acpigen_write_PSS_package( - clock_max + 1, /*MHz*/ - power_max, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio_turbo << 8, /*control*/ - ratio_turbo << 8); /*status*/ + clock_max + 1, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_turbo << 8, /* control */ + ratio_turbo << 8); /* status */ } else { /* _PSS package count without Turbo */ acpigen_write_package(num_entries + 1); @@ -513,12 +427,12 @@ static void generate_P_state_entries(int core, int cores_per_package) /* First regular entry is max non-turbo ratio */ acpigen_write_PSS_package( - clock_max, /*MHz*/ - power_max, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio_max << 8, /*control*/ - ratio_max << 8); /*status*/ + clock_max, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_max << 8, /* control */ + ratio_max << 8); /* status */ /* Generate the remaining entries */ for (ratio = ratio_min + ((num_entries - 1) * ratio_step); @@ -529,50 +443,55 @@ static void generate_P_state_entries(int core, int cores_per_package) clock = ratio * CPU_BCLK; acpigen_write_PSS_package( - clock, /*MHz*/ - power, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio << 8, /*control*/ - ratio << 8); /*status*/ + clock, /* MHz */ + power, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio << 8, /* control */ + ratio << 8); /* status */ } /* Fix package length */ acpigen_pop_len(); } -void generate_cpu_entries(void) +void generate_cpu_entries(device_t device) { - int coreID, cpuID, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6; + int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6; int totalcores = dev_count_cpu(); int cores_per_package = get_cores_per_package(); int numcpus = totalcores/cores_per_package; + device_t dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + int is_s0ix_enable = config->s0ix_enable; + int max_c_state; + + if (is_s0ix_enable) + max_c_state = ARRAY_SIZE(cstate_set_s0ix); + else + max_c_state = ARRAY_SIZE(cstate_set_non_s0ix); printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n", numcpus, cores_per_package); - for (cpuID=1; cpuID <=numcpus; cpuID++) { - for (coreID=1; coreID<=cores_per_package; coreID++) { - if (coreID>1) { + for (cpu_id = 0; cpu_id < numcpus; cpu_id++) { + for (core_id = 0; core_id < cores_per_package; core_id++) { + if (core_id > 0) { pcontrol_blk = 0; plen = 0; } /* Generate processor \_PR.CPUx */ acpigen_write_processor( - (cpuID-1)*cores_per_package+coreID-1, + cpu_id*cores_per_package+core_id, pcontrol_blk, plen); - - /* Generate P-state tables */ - generate_P_state_entries( - coreID-1, cores_per_package); - /* Generate C-state tables */ - generate_C_state_entries(); + generate_c_state_entries(is_s0ix_enable, + max_c_state); - /* Generate T-state tables */ - generate_T_state_entries( - cpuID-1, cores_per_package); + /* Generate P-state tables */ + generate_p_state_entries(core_id, + cores_per_package); acpigen_pop_len(); } @@ -600,3 +519,71 @@ unsigned long acpi_madt_irq_overrides(unsigned long current) return current; } + +#define ALIGN_CURRENT current = (ALIGN(current, 16)) + +unsigned long southcluster_write_acpi_tables(device_t device, + unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_header_t *ssdt2; + + current = acpi_write_hpet(device, current, rsdp); + ALIGN_CURRENT; + +#if CONFIG_GOP_SUPPORT + igd_opregion_t *opregion; + + printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n"); + opregion = (igd_opregion_t *)current; + init_igd_opregion(opregion); + current += sizeof(igd_opregion_t); + ALIGN_CURRENT; +#endif + + ssdt2 = (acpi_header_t *)current; + memset(ssdt2, 0, sizeof(acpi_header_t)); + acpi_create_serialio_ssdt(ssdt2); + if (ssdt2->length) { + current += ssdt2->length; + acpi_add_table(rsdp, ssdt2); + printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n",ssdt2, + ssdt2->length); + ALIGN_CURRENT; + } else { + ssdt2 = NULL; + printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n"); + } + + printk(BIOS_DEBUG, "current = %lx\n", current); + + return current; +} + +void southcluster_inject_dsdt(device_t device) +{ + global_nvs_t *gnvs; + + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (!gnvs) { + gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof (*gnvs)); + if (gnvs) + memset(gnvs, 0, sizeof(*gnvs)); + } + + if (gnvs) { + acpi_create_gnvs(gnvs); + acpi_save_gnvs((unsigned long)gnvs); + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); + + /* Add it to DSDT. */ + acpigen_write_scope("\\"); + acpigen_write_name_dword("NVSA", (u32) gnvs); + acpigen_pop_len(); + } +} + +__attribute__((weak)) void acpi_create_serialio_ssdt(acpi_header_t *ssdt) +{ +} diff --git a/src/soc/intel/skylake/acpi/adsp.asl b/src/soc/intel/skylake/acpi/adsp.asl deleted file mode 100644 index cb10d9a9ad..0000000000 --- a/src/soc/intel/skylake/acpi/adsp.asl +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -Device (ADSP) -{ - Method (_HID, 0, Serialized) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3438") - } - - // LynxPoint-LP - Return ("INT33C8") - } - Name (_UID, 1) - Name (_DDN, "Intel Smart Sound Technology") - - Name (RBUF, ResourceTemplate () - { - Memory32Fixed (ReadWrite, 0x00000000, 0x00100000, BAR0) - Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR1) - Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {3} - }) - - Method (_CRS, 0, NotSerialized) - { - // Update BAR address and length if set in NVS - If (LNotEqual (\S8B0, Zero)) { - CreateDwordField (^RBUF, ^BAR0._BAS, B8A0) - CreateDwordField (^RBUF, ^BAR1._BAS, B8A1) - Store (\S8B0, B8A0) - Store (\S8B1, B8A1) - } - - Return (RBUF) - } - - Method (_STA, 0, NotSerialized) - { - If (LEqual (\S8EN, 0)) { - Return (0x0) - } Else { - Return (0xF) - } - } - - Device (I2S0) - { - Name (_ADR, 0) - } - - Device (I2S1) - { - Name (_ADR, 1) - } -} diff --git a/src/soc/intel/skylake/acpi/cpu.asl b/src/soc/intel/skylake/acpi/cpu.asl index 2921ceae5e..5856033862 100644 --- a/src/soc/intel/skylake/acpi/cpu.asl +++ b/src/soc/intel/skylake/acpi/cpu.asl @@ -2,7 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* These devices are created at runtime */ diff --git a/src/soc/intel/skylake/acpi/ctdp.asl b/src/soc/intel/skylake/acpi/ctdp.asl index a2a8fb4d2c..1668b4cfaa 100644 --- a/src/soc/intel/skylake/acpi/ctdp.asl +++ b/src/soc/intel/skylake/acpi/ctdp.asl @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ Scope (\_SB.PCI0.MCHC) @@ -30,40 +31,43 @@ Scope (\_SB.PCI0.MCHC) Add (MCH_BASE_ADDRESS, 0x5000), 0x1000) Field (MCHB, DWordAcc, Lock, Preserve) { - Offset (0x930), /* PACKAGE_POWER_SKU */ + Offset (0x930), /* PACKAGE_POWER_SKU */ CTDN, 15, /* CTDP Nominal PL1 */ - Offset (0x938), /* PACKAGE_POWER_SKU_UNIT */ + Offset (0x938), /* PACKAGE_POWER_SKU_UNIT */ PUNI, 4, /* Power Units */ , 4, EUNI, 5, /* Energy Units */ , 3, TUNI, 4, /* Time Units */ - Offset (0x958), /* PLATFORM_INFO */ - , 40, + Offset (0x958), /* PLATFORM_INFO */ + , 32, + LPMS, 1, /* LPM Support */ + CTNL, 2, /* Config TDP Number level */ + , 5, LFM_, 8, /* Maximum Efficiency Ratio (LFM) */ - Offset (0x9a0), /* TURBO_POWER_LIMIT1 */ + Offset (0x9a0), /* TURBO_POWER_LIMIT1 */ PL1V, 15, /* Power Limit 1 Value */ PL1E, 1, /* Power Limit 1 Enable */ PL1C, 1, /* Power Limit 1 Clamp */ PL1T, 7, /* Power Limit 1 Time */ - Offset (0x9a4), /* TURBO_POWER_LIMIT2 */ + Offset (0x9a4), /* TURBO_POWER_LIMIT2 */ PL2V, 15, /* Power Limit 2 Value */ PL2E, 1, /* Power Limit 2 Enable */ PL2C, 1, /* Power Limit 2 Clamp */ PL2T, 7, /* Power Limit 2 Time */ - Offset (0xf3c), /* CONFIG_TDP_NOMINAL */ + Offset (0xf3c), /* CONFIG_TDP_NOMINAL */ TARN, 8, /* CTDP Nominal Turbo Activation Ratio */ - Offset (0xf40), /* CONFIG_TDP_LEVEL1 */ + Offset (0xf40), /* CONFIG_TDP_LEVEL1 */ CTDD, 15, /* CTDP Down PL1 */ , 1, TARD, 8, /* CTDP Down Turbo Activation Ratio */ - Offset (0xf48), /* MSR_CONFIG_TDP_LEVEL2 */ + Offset (0xf48), /* MSR_CONFIG_TDP_LEVEL2 */ CTDU, 15, /* CTDP Up PL1 */ , 1, TARU, 8, /* CTDP Up Turbo Activation Ratio */ - Offset (0xf50), /* CONFIG_TDP_CONTROL */ + Offset (0xf50), /* CONFIG_TDP_CONTROL */ CTCS, 2, /* CTDP Select */ - Offset (0xf54), /* TURBO_ACTIVATION_RATIO */ + Offset (0xf54), /* TURBO_ACTIVATION_RATIO */ TARS, 8, /* Turbo Activation Ratio Select */ } @@ -85,7 +89,7 @@ Scope (\_SB.PCI0.MCHC) While (LLess (Local0, Local1)) { /* Store _PSS entry Control value to Local2 */ ShiftRight (DeRefOf (Index (DeRefOf (Index - (\_PR.CP00._PSS, Local0)), 4)), 8, Local2) + (\_PR.CP00._PSS, Local0)), 4)), 8, Local2) If (LEqual (Local2, Arg0)) { Return (Subtract (Local0, 1)) } @@ -98,8 +102,6 @@ Scope (\_SB.PCI0.MCHC) /* Calculate PL2 based on chip type */ Method (CPL2, 1, NotSerialized) { - /* Haswell ULT PL2 = 25W */ - /* FIXME: update for broadwell */ Return (Multiply (25, 8)) } diff --git a/src/soc/intel/skylake/acpi/device_nvs.asl b/src/soc/intel/skylake/acpi/device_nvs.asl index 1d2aa78edb..e84d25ae9b 100644 --- a/src/soc/intel/skylake/acpi/device_nvs.asl +++ b/src/soc/intel/skylake/acpi/device_nvs.asl @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,41 +15,46 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* Device Enabled in ACPI Mode */ -S0EN, 8, // DMA Enable -S1EN, 8, // I2C0 Enable -S2EN, 8, // I2C1 Enable -S3EN, 8, // SPI0 Enable -S4EN, 8, // SPI1 Enable -S5EN, 8, // UART0 Enable -S6EN, 8, // UART1 Enable -S7EN, 8, // SDIO Enable -S8EN, 8, // ADSP Enable +S0EN, 8, // I2C0 Enable +S1EN, 8, // I2C1 Enable +S2EN, 8, // I2C2 Enable +S3EN, 8, // I2C3 Enable +S4EN, 8, // I2C4 Enable +S5EN, 8, // I2C5 Enable +S6EN, 8, // SPI0 Enable +S7EN, 8, // SPI1 Enable +S8EN, 8, // UART0 Enable +S9EN, 8, // UART1 Enable +SAEN, 8, // UART2 Enable /* BAR 0 */ - -S0B0, 32, // DMA BAR0 -S1B0, 32, // I2C0 BAR0 -S2B0, 32, // I2C1 BAR0 -S3B0, 32, // SPI0 BAR0 -S4B0, 32, // SPI1 BAR0 -S5B0, 32, // UART0 BAR0 -S6B0, 32, // UART1 BAR0 -S7B0, 32, // SDIO BAR0 -S8B0, 32, // ADSP BAR0 +S0B0, 32, // I2C0 BAR0 +S1B0, 32, // I2C1 BAR0 +S2B0, 32, // I2C2 BAR0 +S3B0, 32, // I2C3 BAR0 +S4B0, 32, // I2C4 BAR0 +S5B0, 32, // I2C5 BAR0 +S6B0, 32, // SPI0 BAR0 +S7B0, 32, // SPI1 BAR0 +S8B0, 32, // UART0 BAR0 +S9B0, 32, // UART1 BAR0 +SAB0, 32, // UART2 BAR0 /* BAR 1 */ +S0B1, 32, // I2C0 BAR1 +S1B1, 32, // I2C1 BAR1 +S2B1, 32, // I2C2 BAR1 +S3B1, 32, // I2C3 BAR1 +S4B1, 32, // I2C4 BAR1 +S5B1, 32, // I2C5 BAR1 +S6B1, 32, // SPI0 BAR1 +S7B1, 32, // SPI1 BAR1 +S8B1, 32, // UART0 BAR1 +S9B1, 32, // UART1 BAR1 +SAB1, 32, // UART2 BAR1 -S0B1, 32, // DMA BAR1 -S1B1, 32, // I2C0 BAR1 -S2B1, 32, // I2C1 BAR1 -S3B1, 32, // SPI0 BAR1 -S4B1, 32, // SPI1 BAR1 -S5B1, 32, // UART0 BAR1 -S6B1, 32, // UART1 BAR1 -S7B1, 32, // SDIO BAR1 -S8B1, 32, // ADSP BAR1 diff --git a/src/soc/intel/skylake/acpi/ehci.asl b/src/soc/intel/skylake/acpi/ehci.asl deleted file mode 100644 index a2e704fccf..0000000000 --- a/src/soc/intel/skylake/acpi/ehci.asl +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// EHCI Controller 0:1d.0 - -Device (EHCI) -{ - Name(_ADR, 0x001d0000) - Name (_PRW, Package(){ 0x6d, 3 }) - - // Leave USB ports on for to allow Wake from USB - - Method(_S3D,0) // Highest D State in S3 State - { - Return (2) - } - - Method(_S4D,0) // Highest D State in S4 State - { - Return (2) - } - - Device (HUB7) - { - Name (_ADR, 0x00000000) - - // How many are there? - Device (PRT1) { Name (_ADR, 1) } // USB Port 0 - Device (PRT2) { Name (_ADR, 2) } // USB Port 1 - Device (PRT3) { Name (_ADR, 3) } // USB Port 2 - Device (PRT4) { Name (_ADR, 4) } // USB Port 3 - Device (PRT5) { Name (_ADR, 5) } // USB Port 4 - Device (PRT6) { Name (_ADR, 6) } // USB Port 5 - } -} diff --git a/src/soc/intel/skylake/acpi/globalnvs.asl b/src/soc/intel/skylake/acpi/globalnvs.asl index 223d21a676..3df40cd946 100644 --- a/src/soc/intel/skylake/acpi/globalnvs.asl +++ b/src/soc/intel/skylake/acpi/globalnvs.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* Global Variables */ @@ -29,8 +30,7 @@ Name (\PICM, 0) // IOAPIC/8259 * we have to fix it up in coreboot's ACPI creation phase. */ -External(NVSA) -OperationRegion (GNVS, SystemMemory, NVSA, 0x2000) +OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0x2000) Field (GNVS, ByteAcc, NoLock, Preserve) { /* Miscellaneous */ @@ -62,6 +62,18 @@ Field (GNVS, ByteAcc, NoLock, Preserve) CBMC, 32, // 0x1c - 0x1f - Coreboot Memory Console PM1I, 64, // 0x20 - 0x27 - PM1 wake status bit GPEI, 64, // 0x28 - 0x2f - GPE wake status bit + RPA1, 32, // 0x30 - 0x33 - Root port address 1 + RPA2, 32, // 0x34 - 0x37 - Root port address 2 + RPA3, 32, // 0x38 - 0x3b - Root port address 3 + RPA4, 32, // 0x3c - 0x3f - Root port address 4 + RPA5, 32, // 0x40 - 0x43 - Root port address 5 + RPA6, 32, // 0x44 - 0x47 - Root port address 6 + RPA7, 32, // 0x48 - 0x4b - Root port address 7 + RPA8, 32, // 0x4c - 0x4f - Root port address 8 + RPA9, 32, // 0x50 - 0x53 - Root port address 9 + RPAA, 32, // 0x54 - 0x57 - Root port address 10 + RPAB, 32, // 0x58 - 0x5b - Root port address 11 + RPAC, 32, // 0x5c - 0x5f - Root port address 12 /* ChromeOS specific */ Offset (0x100), @@ -72,18 +84,6 @@ Field (GNVS, ByteAcc, NoLock, Preserve) #include "device_nvs.asl" } -/* Set flag to enable USB charging in S3 */ -Method (S3UE) -{ - Store (One, \S3U0) -} - -/* Set flag to disable USB charging in S3 */ -Method (S3UD) -{ - Store (Zero, \S3U0) -} - /* Set flag to enable USB charging in S5 */ Method (S5UE) { @@ -95,15 +95,3 @@ Method (S5UD) { Store (Zero, \S5U0) } - -/* Set flag to enable 3G module in S3 */ -Method (S3GE) -{ - Store (One, \S33G) -} - -/* Set flag to disable 3G module in S3 */ -Method (S3GD) -{ - Store (Zero, \S33G) -} diff --git a/src/soc/intel/skylake/acpi/gpio.asl b/src/soc/intel/skylake/acpi/gpio.asl index c6d8753975..69ee721393 100644 --- a/src/soc/intel/skylake/acpi/gpio.asl +++ b/src/soc/intel/skylake/acpi/gpio.asl @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ Device (GPIO) @@ -22,13 +23,8 @@ Device (GPIO) // GPIO Controller Method (_HID) { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3437") - } - - // LynxPoint-LP - Return ("INT33C7") + //Sunrisepoint-LP PCH + Return ("INT344B") } Name (_UID, 1) diff --git a/src/soc/intel/skylake/acpi/irqlinks.asl b/src/soc/intel/skylake/acpi/irqlinks.asl index ba550e2a46..1f6e62352c 100644 --- a/src/soc/intel/skylake/acpi/irqlinks.asl +++ b/src/soc/intel/skylake/acpi/irqlinks.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ Device (LNKA) @@ -26,14 +27,14 @@ Device (LNKA) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTA) + Or (\_SB.PARC, 0x80, \_SB.PARC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 10, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -49,7 +50,7 @@ Device (LNKA) Store (Zero, IRQ0) // Set the bit from PRTA - ShiftLeft (1, And (PRTA, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PARC, 0x0f), IRQ0) Return (RTLA) } @@ -63,13 +64,13 @@ Device (LNKA) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTA) + Store (Local0, \_SB.PARC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTA, 0x80)) { + If(And (\_SB.PARC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -85,14 +86,14 @@ Device (LNKB) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTB) + Or (\_SB.PBRC, 0x80, \_SB.PBRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 11, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -108,7 +109,7 @@ Device (LNKB) Store (Zero, IRQ0) // Set the bit from PRTB - ShiftLeft (1, And (PRTB, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PBRC, 0x0f), IRQ0) Return (RTLB) } @@ -122,13 +123,13 @@ Device (LNKB) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTB) + Store (Local0, \_SB.PBRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTB, 0x80)) { + If(And (\_SB.PBRC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -144,14 +145,14 @@ Device (LNKC) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTC) + Or (\_SB.PCRC, 0x80, \_SB.PCRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 10, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -167,7 +168,7 @@ Device (LNKC) Store (Zero, IRQ0) // Set the bit from PRTC - ShiftLeft (1, And (PRTC, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PCRC, 0x0f), IRQ0) Return (RTLC) } @@ -181,13 +182,13 @@ Device (LNKC) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTC) + Store (Local0, \_SB.PCRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTC, 0x80)) { + If(And (\_SB.PCRC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -203,14 +204,14 @@ Device (LNKD) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTD) + Or (\_SB.PDRC, 0x80, \_SB.PDRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 11, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -226,7 +227,7 @@ Device (LNKD) Store (Zero, IRQ0) // Set the bit from PRTD - ShiftLeft (1, And (PRTD, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PDRC, 0x0f), IRQ0) Return (RTLD) } @@ -240,13 +241,13 @@ Device (LNKD) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTD) + Store (Local0, \_SB.PDRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTD, 0x80)) { + If(And (\_SB.PDRC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -262,14 +263,14 @@ Device (LNKE) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTE) + Or (\_SB.PERC, 0x80, \_SB.PERC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 10, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -285,7 +286,7 @@ Device (LNKE) Store (Zero, IRQ0) // Set the bit from PRTE - ShiftLeft (1, And (PRTE, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PERC, 0x0f), IRQ0) Return (RTLE) } @@ -299,13 +300,13 @@ Device (LNKE) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTE) + Store (Local0, \_SB.PERC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTE, 0x80)) { + If(And (\_SB.PERC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -321,14 +322,14 @@ Device (LNKF) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTF) + Or (\_SB.PFRC, 0x80, \_SB.PFRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 11, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -344,7 +345,7 @@ Device (LNKF) Store (Zero, IRQ0) // Set the bit from PRTF - ShiftLeft (1, And (PRTF, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PFRC, 0x0f), IRQ0) Return (RTLF) } @@ -358,13 +359,13 @@ Device (LNKF) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTF) + Store (Local0, \_SB.PFRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTF, 0x80)) { + If(And (\_SB.PFRC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -380,14 +381,14 @@ Device (LNKG) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTG) + Or (\_SB.PGRC, 0x80, \_SB.PGRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 10, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -403,7 +404,7 @@ Device (LNKG) Store (Zero, IRQ0) // Set the bit from PRTG - ShiftLeft (1, And (PRTG, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PGRC, 0x0f), IRQ0) Return (RTLG) } @@ -417,13 +418,13 @@ Device (LNKG) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTG) + Store (Local0, \_SB.PGRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTG, 0x80)) { + If(And (\_SB.PGRC, 0x80)) { Return (0x9) } Else { Return (0xb) @@ -439,14 +440,14 @@ Device (LNKH) // Disable method Method (_DIS, 0, Serialized) { - Store (0x80, PRTH) + Or (\_SB.PHRC, 0x80, \_SB.PHRC) } // Possible Resource Settings for this Link Name (_PRS, ResourceTemplate() { IRQ (Level, ActiveLow, Shared) - { 3, 4, 5, 6, 7, 11, 12, 14, 15 } + { 3, 4, 5, 6, 10, 12, 14, 15 } }) // Current Resource Settings for this link @@ -462,7 +463,7 @@ Device (LNKH) Store (Zero, IRQ0) // Set the bit from PRTH - ShiftLeft (1, And (PRTH, 0x0f), IRQ0) + ShiftLeft (1, And (\_SB.PHRC, 0x0f), IRQ0) Return (RTLH) } @@ -476,13 +477,13 @@ Device (LNKH) FindSetRightBit (IRQ0, Local0) Decrement(Local0) - Store (Local0, PRTH) + Store (Local0, \_SB.PHRC) } // Status Method (_STA, 0, Serialized) { - If(And (PRTH, 0x80)) { + If(And (\_SB.PHRC, 0x80)) { Return (0x9) } Else { Return (0xb) diff --git a/src/soc/intel/skylake/acpi/itss.asl b/src/soc/intel/skylake/acpi/itss.asl new file mode 100644 index 0000000000..8ba9513abd --- /dev/null +++ b/src/soc/intel/skylake/acpi/itss.asl @@ -0,0 +1,96 @@ +/* + * This file is part of the coreboot project. + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* ITSS */ +/* Define the needed ITSS registers used by ASL on Interrupt */ + +Scope (\_SB) +{ + OperationRegion (ITSS, SystemMemory, 0xfdc43100, 0x8) + Field (ITSS, ByteAcc, NoLock, Preserve) + { + PARC, 8, + PBRC, 8, + PCRC, 8, + PDRC, 8, + PERC, 8, + PFRC, 8, + PGRC, 8, + PHRC, 8, + } + + /* + * Pin# = group_pad# + group# * 24. + * For instance, GPP_A_6 would be pin#6, + * GPP_D_23 would be 23+(3*24), pin#95. + */ + Name (GPPG, Package (0x02) + { + Package (0x08) + { + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x08, + 0x0C + }, + + Package (0x0A) + { + 0x18, + 0x18, + 0x18, + 0x18, + 0x0D, + 0x18, + 0x18, + 0x18, + 0x0B, + 0x0C + } + }) + + Method (GNMB, 1, Serialized) + { + Return (And (Arg0, 0xFFFF)) + } + + Method (GGRP, 1, Serialized) + { + ShiftRight (And (Arg0, 0x00FF0000), 0x10, Local0) + Return (Local0) + } + + /* Convert GPIO PAD name to GPIO number */ + Method (INUM, 1, NotSerialized) + { + Store (One, Local0) + Store (GNMB (Arg0), Local1) + Store (GGRP (Arg0), Local2) + Store (Zero, Local3) + + While (LLess (Local3, Local2)) + { + Add (DerefOf (Index (DerefOf (Index + (GPPG, Local0)), Local3)), + Local1, Local1) + Increment (Local3) + } + + Return (Add (0x18, Mod (Local1, 0x60))) + } +} diff --git a/src/soc/intel/skylake/acpi/lpc.asl b/src/soc/intel/skylake/acpi/lpc.asl index 2b574f756d..8332980730 100644 --- a/src/soc/intel/skylake/acpi/lpc.asl +++ b/src/soc/intel/skylake/acpi/lpc.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,9 +16,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <soc/iomap.h> + // Intel LPC Bus Device - 0:1f.0 Device (LPCB) @@ -33,16 +36,7 @@ Device (LPCB) PMBS, 16, // PMBASE Offset (0x48), GPBS, 16, // GPIOBASE - Offset (0x60), // Interrupt Routing Registers - PRTA, 8, - PRTB, 8, - PRTC, 8, - PRTD, 8, - Offset (0x68), - PRTE, 8, - PRTF, 8, - PRTG, 8, - PRTH, 8, + Offset (0x80), // IO Decode Ranges IOD0, 8, @@ -74,48 +68,22 @@ Device (LPCB) Device (HPET) { Name (_HID, EISAID("PNP0103")) - Name (_CID, 0x010CD041) - Name (BUF0, ResourceTemplate() { - Memory32Fixed(ReadOnly, 0xfed00000, 0x400, FED0) + Memory32Fixed(ReadOnly, HPET_BASE_ADDRESS, 0x400, FED0) }) Method (_STA, 0) // Device Status { - If (HPTE) { - // Note: Ancient versions of Windows don't want - // to see the HPET in order to work right - If (LGreaterEqual(OSYS, 2001)) { - Return (0xf) // Enable and show device - } Else { - Return (0xb) // Enable and don't show device - } - } - - Return (0x0) // Not enabled, don't show. + Return (0xf) } - Method (_CRS, 0, Serialized) // Current resources { - If (HPTE) { - CreateDWordField (BUF0, - \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0) - - If (Lequal(HPAS, 1)) { - Store(0xfed01000, HPT0) - } - - If (Lequal(HPAS, 2)) { - Store(0xfed02000, HPT0) - } - - If (Lequal(HPAS, 3)) { - Store(0xfed03000, HPT0) - } - } + CreateDWordField (BUF0, ^FED0._BAS, HPT0) + /* TODO: Base address configured need to pass as GNVS */ + Store(HPET_BASE_ADDRESS, HPT0) - Return (BUF0) + Return(BUF0) } } diff --git a/src/soc/intel/skylake/acpi/pch.asl b/src/soc/intel/skylake/acpi/pch.asl index 998133d9d9..2621eb287d 100644 --- a/src/soc/intel/skylake/acpi/pch.asl +++ b/src/soc/intel/skylake/acpi/pch.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,78 +16,47 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <soc/iomap.h> Scope (\) { - // IO-Trap at 0x800. This is the ACPI->SMI communication interface. + /* IO-Trap at 0x800. + * This is the ACPI->SMI communication interface. + */ OperationRegion (IO_T, SystemIO, 0x800, 0x10) Field (IO_T, ByteAcc, NoLock, Preserve) { Offset (0x8), - TRP0, 8 // IO-Trap at 0x808 - } - - // Root Complex Register Block - OperationRegion (RCRB, SystemMemory, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE) - Field (RCRB, DWordAcc, Lock, Preserve) - { - Offset (0x3404), // High Performance Timer Configuration - HPAS, 2, // Address Select - , 5, - HPTE, 1, // Address Enable - } - - /* - * Check PCH type - * Return 1 if PCH is WildcatPoint - * Return 0 if PCH is LynxPoint - */ - Method (ISWP) - { - And (\_SB.PCI0.LPCB.PDID, 0xfff0, Local0) - If (LEqual (Local0, 0x9cc0)) { - Return (1) - } Else { - Return (0) - } + TRP0, 8 /* IO-Trap at 0x808 */ } } -// High Definition Audio (Azalia) 0:1b.0 -#include "hda.asl" - -// ADSP/SST 0:13.0 -#include "adsp.asl" - -// PCI Express Ports 0:1c.x +/* PCI Express Ports 0:1c.x */ #include "pcie.asl" -// USB EHCI 0:1d.0 -#include "ehci.asl" - -// USB XHCI 0:14.0 +/* USB XHCI 0:14.0 */ #include "xhci.asl" -// LPC Bridge 0:1f.0 +/* LPC Bridge 0:1f.0 */ #include "lpc.asl" -// SATA 0:1f.2 -#include "sata.asl" - -// SMBus 0:1f.3 +/* SMBus 0:1f.3 */ #include "smbus.asl" -// Serial IO +/* Serial IO */ #include "serialio.asl" +/* Interrupt Routing */ +#include "itss.asl" +#include "irqlinks.asl" + Method (_OSC, 4) { /* Check for proper GUID */ - If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) + If (LEqual (Arg0, ToUUID ("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) { /* Let OS control everything */ Return (Arg3) diff --git a/src/soc/intel/skylake/acpi/pci_irqs.asl b/src/soc/intel/skylake/acpi/pci_irqs.asl index 0c23e10a51..c43e42dbb6 100644 --- a/src/soc/intel/skylake/acpi/pci_irqs.asl +++ b/src/soc/intel/skylake/acpi/pci_irqs.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,74 +16,127 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ Method(_PRT) { If (PICM) { Return (Package() { - // Onboard graphics (IGD) 0:2.0 - Package() { 0x0002ffff, 0, 0, 16 }, - // Mini-HD Audio 0:3.0 - Package() { 0x0003ffff, 0, 0, 16 }, - // High Definition Audio 0:1b.0 - Package() { 0x001bffff, 0, 0, 22 }, - // PCIe Root Ports 0:1c.x - Package() { 0x001cffff, 0, 0, 16 }, - Package() { 0x001cffff, 1, 0, 17 }, - Package() { 0x001cffff, 2, 0, 18 }, - Package() { 0x001cffff, 3, 0, 19 }, - // EHCI 0:1d.0 - Package() { 0x001dffff, 0, 0, 19 }, - // Audio DSP (Smart Sound) 0:13.0 - Package() { 0x0013ffff, 0, 0, 23 }, - // XHCI 0:14.0 - Package() { 0x0014ffff, 0, 0, 18 }, - // LPC devices 0:1f.0 - Package() { 0x001fffff, 0, 0, 22 }, - Package() { 0x001fffff, 1, 0, 18 }, - Package() { 0x001fffff, 2, 0, 17 }, - Package() { 0x001fffff, 3, 0, 16 }, - // Serial IO 0:15.0 - Package() { 0x0015ffff, 0, 0, 20 }, - Package() { 0x0015ffff, 1, 0, 21 }, - Package() { 0x0015ffff, 2, 0, 21 }, - Package() { 0x0015ffff, 3, 0, 21 }, - // SDIO 0:17.0 - Package() { 0x0017ffff, 0, 0, 23 }, + /* PCI Bridge */ + /* D31: cAVS, SMBus, GbE, Nothpeak */ + Package(){0x001FFFFF, 0, 0, 16 }, + Package(){0x001FFFFF, 1, 0, 17 }, + Package(){0x001FFFFF, 2, 0, 18 }, + Package(){0x001FFFFF, 3, 0, 19 }, + /* D30: SerialIo and SCS */ + Package(){0x001EFFFF, 0, 0, 20 }, + Package(){0x001EFFFF, 1, 0, 21 }, + Package(){0x001EFFFF, 2, 0, 22 }, + Package(){0x001EFFFF, 3, 0, 23 }, + /* D29: PCI Express Port 9-16 */ + Package(){0x001DFFFF, 0, 0, 16 }, + Package(){0x001DFFFF, 1, 0, 17 }, + Package(){0x001DFFFF, 2, 0, 18 }, + Package(){0x001DFFFF, 3, 0, 19 }, + /* D28: PCI Express Port 1-8 */ + Package(){0x001CFFFF, 0, 0, 16 }, + Package(){0x001CFFFF, 1, 0, 17 }, + Package(){0x001CFFFF, 2, 0, 18 }, + Package(){0x001CFFFF, 3, 0, 19 }, + /* D27: PCI Express Port 17-20 */ + Package(){0x001BFFFF, 0, 0, 16 }, + Package(){0x001BFFFF, 1, 0, 17 }, + Package(){0x001BFFFF, 2, 0, 18 }, + Package(){0x001BFFFF, 3, 0, 19 }, + /* D25: SerialIo */ + Package(){0x0019FFFF, 0, 0, 32 }, + Package(){0x0019FFFF, 1, 0, 33 }, + Package(){0x0019FFFF, 2, 0, 34 }, + /* D22: CSME (HECI, IDE-R, Keyboard and Text redirection */ + Package(){0x0016FFFF, 0, 0, 16 }, + Package(){0x0016FFFF, 1, 0, 17 }, + Package(){0x0016FFFF, 2, 0, 18 }, + Package(){0x0016FFFF, 3, 0, 19 }, + /* D21: SerialIo */ + Package(){0x0015FFFF, 0, 0, 16 }, + Package(){0x0015FFFF, 1, 0, 17 }, + Package(){0x0015FFFF, 2, 0, 18 }, + Package(){0x0015FFFF, 3, 0, 19 }, + /* D20: xHCI, OTG, + * Thermal Subsystem, Camera IO Host Controller + */ + Package(){0x0014FFFF, 0, 0, 16 }, + Package(){0x0014FFFF, 1, 0, 17 }, + Package(){0x0014FFFF, 2, 0, 18 }, + Package(){0x0014FFFF, 3, 0, 19 }, + /* D19: Integrated Sensor Hub */ + Package(){0x0013FFFF, 0, 0, 20 }, + + /* Host Bridge */ + /* P.E.G. Root Port D1F0 */ + Package(){0x0001FFFF, 0, 0, 16 }, + Package(){0x0001FFFF, 1, 0, 17 }, + Package(){0x0001FFFF, 2, 0, 18 }, + Package(){0x0001FFFF, 3, 0, 19 }, + /* P.E.G. Root Port D1F1 */ + /* P.E.G. Root Port D1F2 */ + /* SA IGFX Device */ + Package(){0x0002FFFF, 0, 0, 16 }, + /* SA Thermal Device */ + Package(){0x0004FFFF, 0, 0, 16 }, + /* SA SkyCam Device */ + Package(){0x0005FFFF, 0, 0, 16 }, + /* SA GMM Device */ + Package(){0x0008FFFF, 0, 0, 16 }, }) } Else { Return (Package() { - // Onboard graphics (IGD) 0:2.0 - Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, - // Mini-HD Audio 0:3.0 - Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, - // High Definition Audio 0:1b.0 - Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKG, 0 }, - // PCIe Root Ports 0:1c.x - Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, - Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x001cffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x001cffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, - // EHCI 0:1d.0 - Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKD, 0 }, - // Audio DSP (Smart Sound) 0:13.0 - Package() { 0x0013ffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, - // XHCI 0:14.0 - Package() { 0x0014ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 }, - // LPC device 0:1f.0 - Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKG, 0 }, - Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x001fffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }, - // Serial IO 0:15.0 - Package() { 0x0015ffff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, - Package() { 0x0015ffff, 1, \_SB.PCI0.LPCB.LNKF, 0 }, - Package() { 0x0015ffff, 2, \_SB.PCI0.LPCB.LNKF, 0 }, - Package() { 0x0015ffff, 3, \_SB.PCI0.LPCB.LNKF, 0 }, - // SDIO 0:17.0 - Package() { 0x0017ffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, + /* D31 */ + Package() { 0x001fffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x001fffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x001fffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x001fffff, 3, \_SB.PCI0.LNKD, 0 }, + /* D29 */ + Package() { 0x001dffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x001dffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x001dffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x001dffff, 3, \_SB.PCI0.LNKD, 0 }, + /* D28 */ + Package() { 0x001cffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x001cffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x001cffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x001cffff, 3, \_SB.PCI0.LNKD, 0 }, + /* D27 */ + Package() { 0x001bffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x001bffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x001bffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x001bffff, 3, \_SB.PCI0.LNKD, 0 }, + /* D23 */ + Package() { 0x0017ffff, 0, \_SB.PCI0.LNKA, 0 }, + /* D22 */ + Package() { 0x0016ffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0016ffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0016ffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0016ffff, 3, \_SB.PCI0.LNKD, 0 }, + /* D20 */ + Package() { 0x0014ffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0014ffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0014ffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0014ffff, 3, \_SB.PCI0.LNKD, 0 }, + /* Host bridge */ + Package() { 0x0001ffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0001ffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0001ffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0001ffff, 3, \_SB.PCI0.LNKD, 0 }, + /* SA IGFX Device */ + Package() { 0x0002ffff, 0, \_SB.PCI0.LNKA, 0 }, + /* SA Thermal Device */ + Package() { 0x0004ffff, 0, \_SB.PCI0.LNKA, 0 }, + /* SA Skycam Device */ + Package() { 0x0005ffff, 0, \_SB.PCI0.LNKA, 0 }, + /* SA GMM Device */ + Package() { 0x0008ffff, 0, \_SB.PCI0.LNKA, 0 }, }) } } diff --git a/src/soc/intel/skylake/acpi/pcie.asl b/src/soc/intel/skylake/acpi/pcie.asl index a48bdde0e3..7ab78e0b09 100644 --- a/src/soc/intel/skylake/acpi/pcie.asl +++ b/src/soc/intel/skylake/acpi/pcie.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* Intel PCH PCIe support */ @@ -29,10 +30,10 @@ Method (IRQM, 1, Serialized) { Package() { 0x0000ffff, 2, 0, 18 }, Package() { 0x0000ffff, 3, 0, 19 } }) Name (IQAP, Package() { - Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, - Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 } }) + Package() { 0x0000ffff, 0, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LNKD, 0 } }) /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */ Name (IQBA, Package() { @@ -41,10 +42,10 @@ Method (IRQM, 1, Serialized) { Package() { 0x0000ffff, 2, 0, 19 }, Package() { 0x0000ffff, 3, 0, 16 } }) Name (IQBP, Package() { - Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 }, - Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 } }) + Package() { 0x0000ffff, 0, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LNKD, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LNKA, 0 } }) /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */ Name (IQCA, Package() { @@ -53,10 +54,10 @@ Method (IRQM, 1, Serialized) { Package() { 0x0000ffff, 2, 0, 16 }, Package() { 0x0000ffff, 3, 0, 17 } }) Name (IQCP, Package() { - Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 }, - Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 }, - Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 } }) + Package() { 0x0000ffff, 0, \_SB.PCI0.LNKC, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LNKD, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LNKB, 0 } }) /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */ Name (IQDA, Package() { @@ -65,10 +66,10 @@ Method (IRQM, 1, Serialized) { Package() { 0x0000ffff, 2, 0, 17 }, Package() { 0x0000ffff, 3, 0, 18 } }) Name (IQDP, Package() { - Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 }, - Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 }, - Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 } }) + Package() { 0x0000ffff, 0, \_SB.PCI0.LNKD, 0 }, + Package() { 0x0000ffff, 1, \_SB.PCI0.LNKA, 0 }, + Package() { 0x0000ffff, 2, \_SB.PCI0.LNKB, 0 }, + Package() { 0x0000ffff, 3, \_SB.PCI0.LNKC, 0 } }) Switch (ToInteger (Arg0)) { /* PCIe Root Port 1 and 5 */ @@ -121,11 +122,9 @@ Device (RP01) { Name (_ADR, 0x001c0000) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA1)) } } @@ -133,11 +132,9 @@ Device (RP02) { Name (_ADR, 0x001c0001) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA2)) } } @@ -145,11 +142,9 @@ Device (RP03) { Name (_ADR, 0x001c0002) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA3)) } } @@ -157,11 +152,9 @@ Device (RP04) { Name (_ADR, 0x001c0003) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA4)) } } @@ -169,11 +162,9 @@ Device (RP05) { Name (_ADR, 0x001c0004) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA5)) } } @@ -181,11 +172,9 @@ Device (RP06) { Name (_ADR, 0x001c0005) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA6)) } } @@ -193,11 +182,9 @@ Device (RP07) { Name (_ADR, 0x001c0006) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA7)) } } @@ -205,10 +192,48 @@ Device (RP08) { Name (_ADR, 0x001c0007) - #include "pcie_port.asl" - Method (_PRT) { - Return (IRQM (RPPN)) + Return (IRQM (RPA8)) } } +Device (RP09) +{ + Name (_ADR, 0x001D0000) + + Method (_PRT) + { + Return (IRQM (RPA9)) + } +} + +Device (RP10) +{ + Name (_ADR, 0x001D0001) + + Method (_PRT) + { + Return (IRQM (RPAA)) + } +} + +Device (RP11) +{ + Name (_ADR, 0x001D0002) + + Method (_PRT) + { + Return (IRQM (RPAB)) + } +} + +Device (RP12) +{ + Name (_ADR, 0x001D0003) + + Method (_PRT) + { + Return (IRQM (RPAC)) + } +} + diff --git a/src/soc/intel/skylake/acpi/pcie_port.asl b/src/soc/intel/skylake/acpi/pcie_port.asl deleted file mode 100644 index 32267461b7..0000000000 --- a/src/soc/intel/skylake/acpi/pcie_port.asl +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Included in each PCIe Root Port device */ - -OperationRegion (RPCS, PCI_Config, 0x00, 0xFF) -Field (RPCS, AnyAcc, NoLock, Preserve) -{ - Offset (0x4c), // Link Capabilities - , 24, - RPPN, 8, // Root Port Number -} diff --git a/src/soc/intel/skylake/acpi/platform.asl b/src/soc/intel/skylake/acpi/platform.asl index f63168a745..2bbe97be80 100644 --- a/src/soc/intel/skylake/acpi/platform.asl +++ b/src/soc/intel/skylake/acpi/platform.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* The APM port can be used for generating software SMIs */ @@ -43,7 +44,8 @@ Method (TRAP, 1, Serialized) Return (SMIF) // Return value of SMI handler } -/* The _PIC method is called by the OS to choose between interrupt +/* + * The _PIC method is called by the OS to choose between interrupt * routing via the i8259 interrupt controller or the APIC. * * _PIC is called with a parameter of 0 for i8259 configuration and diff --git a/src/soc/intel/skylake/acpi/sata.asl b/src/soc/intel/skylake/acpi/sata.asl deleted file mode 100644 index 0af2a3f3f5..0000000000 --- a/src/soc/intel/skylake/acpi/sata.asl +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// Intel SATA Controller 0:1f.2 -Device (SATA) -{ - Name (_ADR, 0x001f0002) -} diff --git a/src/soc/intel/skylake/acpi/serialio.asl b/src/soc/intel/skylake/acpi/serialio.asl index 7ffc671a74..203dbef7c5 100644 --- a/src/soc/intel/skylake/acpi/serialio.asl +++ b/src/soc/intel/skylake/acpi/serialio.asl @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,20 +15,22 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <soc/irq.h> // Intel Serial IO Devices in ACPI Mode -// Serial IO Device BAR0 and BAR1 is 4KB +/* Serial IO Device BAR0 and BAR1 is 4KB */ #define SIO_BAR_LEN 0x1000 -// Put SerialIO device in D0 state -// Arg0 - BAR1 of device -// Arg1 - Set if device is in ACPI mode +/* Put SerialIO device in D0 state */ +/* Arg0 - BAR1 of device */ +/* Arg1 - Set if device is in ACPI mode */ + Method (LPD0, 2, Serialized) { - // PCI mode devices will be handled by OS PCI bus driver + /* PCI mode devices will be handled by OS PCI bus driver */ If (LEqual (Arg1, 0)) { Return } @@ -39,146 +42,80 @@ Method (LPD0, 2, Serialized) } And (SPCS, 0xFFFFFFFC, SPCS) - Store (SPCS, Local0) // Read back after writing + /* Read back after writing */ + Store (SPCS, Local0) } -// Put SerialIO device in D3 state -// Arg0 - BAR1 of device -// Arg1 - Set if device is in ACPI mode +/* Put SerialIO device in D3 state */ +/* Arg0 - BAR1 of device */ +/* Arg1 - Set if device is in ACPI mode */ + Method (LPD3, 2, Serialized) { - // PCI mode devices will be handled by OS PCI bus driver + /* PCI mode devices will be handled by OS PCI bus driver */ If (LEqual (Arg1, 0)) { Return } - OperationRegion (SPRT, SystemMemory, Add (Arg0, 0x84), 4) Field (SPRT, DWordAcc, NoLock, Preserve) { SPCS, 32 } - Or (SPCS, 0x3, SPCS) Store (SPCS, Local0) // Read back after writing } -// Serial IO Resource Consumption for BAR1 +/* Serial IO Resource Consumption for BAR1 */ Device (SIOR) { Name (_HID, EISAID("PNP0C02")) - Name (_UID, 4) - - Name (RBUF, ResourceTemplate() - { - // Serial IO BAR1 (PCI config space) resources - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D0) // SDMA - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D1) // I2C0 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D2) // I2C1 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D3) // SPI0 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D4) // SPI1 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D5) // UART0 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D6) // UART1 - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, B1D7) // SDIO - }) - - // Update BAR1 address and length if set in NVS - Method (_CRS, 0, NotSerialized) + Name (_UID, 5) + Method(ADDB,3,Serialized) { + Name (BUFF, ResourceTemplate() { - // SDMA - If (LNotEqual (\S0B1, Zero)) { - CreateDwordField (^RBUF, ^B1D0._BAS, B0AD) - CreateDwordField (^RBUF, ^B1D0._LEN, B0LN) - Store (\S0B1, B0AD) - Store (SIO_BAR_LEN, B0LN) - } - - // I2C0 - If (LNotEqual (\S1B1, Zero)) { - CreateDwordField (^RBUF, ^B1D1._BAS, B1AD) - CreateDwordField (^RBUF, ^B1D1._LEN, B1LN) - Store (\S1B1, B1AD) - Store (SIO_BAR_LEN, B1LN) - } - - // I2C1 - If (LNotEqual (\S2B1, Zero)) { - CreateDwordField (^RBUF, ^B1D2._BAS, B2AD) - CreateDwordField (^RBUF, ^B1D2._LEN, B2LN) - Store (\S2B1, B2AD) - Store (SIO_BAR_LEN, B2LN) - } - - // SPI0 - If (LNotEqual (\S3B1, Zero)) { - CreateDwordField (^RBUF, ^B1D3._BAS, B3AD) - CreateDwordField (^RBUF, ^B1D3._LEN, B3LN) - Store (\S3B1, B3AD) - Store (SIO_BAR_LEN, B3LN) - } - - // SPI1 - If (LNotEqual (\S4B1, Zero)) { - CreateDwordField (^RBUF, ^B1D4._BAS, B4AD) - CreateDwordField (^RBUF, ^B1D4._LEN, B4LN) - Store (\S4B1, B4AD) - Store (SIO_BAR_LEN, B4LN) - } - - // UART0 - If (LNotEqual (\S5B1, Zero)) { - CreateDwordField (^RBUF, ^B1D5._BAS, B5AD) - CreateDwordField (^RBUF, ^B1D5._LEN, B5LN) - Store (\S5B1, B5AD) - Store (SIO_BAR_LEN, B5LN) - } - - // UART1 - If (LNotEqual (\S6B1, Zero)) { - CreateDwordField (^RBUF, ^B1D6._BAS, B6AD) - CreateDwordField (^RBUF, ^B1D6._LEN, B6LN) - Store (\S6B1, B6AD) - Store (SIO_BAR_LEN, B6LN) - } - - // SDIO - If (LNotEqual (\S7B1, Zero)) { - CreateDwordField (^RBUF, ^B1D7._BAS, B7AD) - CreateDwordField (^RBUF, ^B1D7._LEN, B7LN) - Store (\S7B1, B7AD) - Store (SIO_BAR_LEN, B7LN) - } - - Return (RBUF) + Memory32Fixed (ReadWrite, 0x00000000, 0x1000, BUF) + }) + CreateDWordField(BUFF,BUF._BAS,ADDR) + CreateDWordField(BUFF,BUF._LEN,LENG) + Store(ResourceTemplate(){}, Local0) + //Return (RBUF) } } -Device (SDMA) +Device (I2C0) { - // Serial IO DMA Controller - Name (_HID, "INTL9C60") + /* Serial IO I2C0 Controller */ + Name (_HID,"INT3442") Name (_UID, 1) Name (_ADR, 0x00150000) + Name (SSCN, Package () { 432, 507, 30 }) + Name (FMCN, Package () { 72, 160, 30 }) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {7} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C0_IRQ } }) + /* DMA channels are only used if Serial IO DMA controller is enabled */ + Name (DBUF, ResourceTemplate () + { + FixedDMA (0x18, 4, Width32Bit, DMA1) // Tx + FixedDMA (0x19, 5, Width32Bit, DMA2) // Rx + }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS + /* Update BAR0 address and length if set in NVS */ If (LNotEqual (\S0B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) Store (\S0B0, B0AD) Store (SIO_BAR_LEN, B0LN) } - Return (RBUF) } - Method (_STA, 0, NotSerialized) { If (LEqual (\S0EN, 0)) { @@ -187,59 +124,56 @@ Device (SDMA) Return (0xF) } } -} -Device (I2C0) -{ - // Serial IO I2C0 Controller - Method (_HID) + Method (_PS0, 0, Serialized) { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3432") - } + ^^LPD0 (\S0B1, \S0EN) + } - // LynxPoint-LP - Return ("INT33C2") + Method (_PS3, 0, Serialized) + { + ^^LPD3 (\S0B1, \S0EN) } + +} + +Device (I2C1) +{ + /* Serial IO I2C1 Controller */ + Name (_HID,"INT3443") Name (_UID, 1) Name (_ADR, 0x00150001) + Name (SSCN, Package () { 528, 640, 30 }) + Name (FMCN, Package () { 128, 160, 30 }) + Name (FPCN, Package () { 48, 64, 30}) - Name (SSCN, Package () { 432, 507, 30 }) - Name (FMCN, Package () { 72, 160, 30 }) - - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {7} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C1_IRQ } }) - // DMA channels are only used if Serial IO DMA controller is enabled + /* DMA channels are only used if + * Serial IO DMA controller is enabled + */ Name (DBUF, ResourceTemplate () { - FixedDMA (0x18, 4, Width32Bit, DMA1) // Tx - FixedDMA (0x19, 5, Width32Bit, DMA2) // Rx + FixedDMA (0x1A, 6, Width32Bit, DMA1) // Tx + FixedDMA (0x1B, 7, Width32Bit, DMA2) // Rx }) - Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS + /* Update BAR0 address and length if set in NVS */ If (LNotEqual (\S1B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) Store (\S1B0, B0AD) Store (SIO_BAR_LEN, B0LN) } - - // Check if Serial IO DMA Controller is enabled - If (LNotEqual (\_SB.PCI0.SDMA._STA, Zero)) { - Return (ConcatenateResTemplate (RBUF, DBUF)) - } Else { - Return (RBUF) - } + Return (RBUF) } - Method (_STA, 0, NotSerialized) { If (LEqual (\S1EN, 0)) { @@ -260,42 +194,36 @@ Device (I2C0) } } -Device (I2C1) -{ - // Serial IO I2C1 Controller - Method (_HID) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3433") - } - // LynxPoint-LP - Return ("INT33C3") - } +Device (I2C2) +{ + /* Serial IO I2C1 Controller */ + Name (_HID,"INT3444") Name (_UID, 1) Name (_ADR, 0x00150002) - Name (SSCN, Package () { 432, 507, 30 }) Name (FMCN, Package () { 72, 160, 30 }) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {7} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C2_IRQ } }) - // DMA channels are only used if Serial IO DMA controller is enabled + /* DMA channels are only used if + * Serial IO DMA controller is enabled + */ Name (DBUF, ResourceTemplate () { - FixedDMA (0x1A, 6, Width32Bit, DMA1) // Tx - FixedDMA (0x1B, 7, Width32Bit, DMA2) // Rx + FixedDMA (0x1A, 6, Width32Bit, DMA1) + FixedDMA (0x1B, 7, Width32Bit, DMA2) }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS + /* Update BAR0 address and length if set in NVS */ If (LNotEqual (\S2B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) @@ -303,12 +231,8 @@ Device (I2C1) Store (SIO_BAR_LEN, B0LN) } - // Check if Serial IO DMA Controller is enabled - If (LNotEqual (\_SB.PCI0.SDMA._STA, Zero)) { - Return (ConcatenateResTemplate (RBUF, DBUF)) - } Else { - Return (RBUF) - } + /* Check if Serial IO DMA Controller is enabled */ + Return (RBUF) } Method (_STA, 0, NotSerialized) @@ -331,32 +255,35 @@ Device (I2C1) } } -Device (SPI0) +Device (I2C3) { - // Serial IO SPI0 Controller - Method (_HID) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3430") - } - - // LynxPoint-LP - Return ("INT33C0") - } + /* Serial IO I2C3 Controller */ + Name (_HID,"INT3445") Name (_UID, 1) Name (_ADR, 0x00150003) + Name (SSCN, Package () { 432, 507, 30 }) + Name (FMCN, Package () { 72, 160, 30 }) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {7} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C3_IRQ } + }) + + /* DMA channels are only used if + * Serial IO DMA controller is enabled + */ + Name (DBUF, ResourceTemplate () + { + FixedDMA (0x1A, 6, Width32Bit, DMA1) + FixedDMA (0x1B, 7, Width32Bit, DMA2) }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS + /* Update BAR0 address and length if set in NVS */ If (LNotEqual (\S3B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) @@ -364,6 +291,7 @@ Device (SPI0) Store (SIO_BAR_LEN, B0LN) } + /* Check if Serial IO DMA Controller is enabled */ Return (RBUF) } @@ -385,56 +313,48 @@ Device (SPI0) { ^^LPD3 (\S3B1, \S3EN) } + } -Device (SPI1) +Device (I2C4) { - // Serial IO SPI1 Controller - Method (_HID) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3431") - } - - // LynxPoint-LP - Return ("INT33C1") - } + /* Serial IO I2C4 Controller */ + Name (_HID,"INT3446") Name (_UID, 1) - Name (_ADR, 0x00150004) + Name (_ADR, 0x00190002) + Name (SSCN, Package () { 432, 507, 30 }) + Name (FMCN, Package () { 72, 160, 30 }) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {7} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C4_IRQ } }) - // DMA channels are only used if Serial IO DMA controller is enabled + /* DMA channels are only used if + * Serial IO DMA controller is enabled + */ Name (DBUF, ResourceTemplate () { - FixedDMA (0x10, 0, Width32Bit, DMA1) // Tx - FixedDMA (0x11, 1, Width32Bit, DMA2) // Rx + FixedDMA (0x1A, 6, Width32Bit, DMA1) + FixedDMA (0x1B, 7, Width32Bit, DMA2) }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS - If (LNotEqual (\S4B0, Zero)) { + /* Update BAR0 address and length if set in NVS*/ + If (LNotEqual (\S4B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) Store (\S4B0, B0AD) Store (SIO_BAR_LEN, B0LN) } - // Check if Serial IO DMA Controller is enabled - If (LNotEqual (\_SB.PCI0.SDMA._STA, Zero)) { - Return (ConcatenateResTemplate (RBUF, DBUF)) - } Else { - Return (RBUF) - } + /* Check if Serial IO DMA Controller is enabled */ + Return (RBUF) } - Method (_STA, 0, NotSerialized) { If (LEqual (\S4EN, 0)) { @@ -455,52 +375,43 @@ Device (SPI1) } } -Device (UAR0) +Device (I2C5) { - // Serial IO UART0 Controller - Method (_HID) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3434") - } - - // LynxPoint-LP - Return ("INT33C4") - } + /* Serial IO I2C1 Controller */ + Name (_HID,"INT3447") Name (_UID, 1) - Name (_ADR, 0x00150005) + Name (_ADR, 0x00190002) + Name (SSCN, Package () { 432, 507, 30 }) + Name (FMCN, Package () { 72, 160, 30 }) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { - Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {13} + Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_I2C5_IRQ } }) - // DMA channels are only used if Serial IO DMA controller is enabled + /* DMA channels are only used if + * Serial IO DMA controller is enabled + */ Name (DBUF, ResourceTemplate () { - FixedDMA (0x16, 2, Width32Bit, DMA1) // Tx - FixedDMA (0x17, 3, Width32Bit, DMA2) // Rx + FixedDMA (0x1A, 6, Width32Bit, DMA1) + FixedDMA (0x1B, 7, Width32Bit, DMA2) }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS - If (LNotEqual (\S5B0, Zero)) { - CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) - CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) - Store (\S5B0, B0AD) - Store (SIO_BAR_LEN, B0LN) - } + /* Update BAR0 address and length if set in NVS */ + CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) + CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) + Store (0xFE02A000, B0AD) + Store (SIO_BAR_LEN, B0LN) - // Check if Serial IO DMA Controller is enabled - If (LNotEqual (\_SB.PCI0.SDMA._STA, Zero)) { - Return (ConcatenateResTemplate (RBUF, DBUF)) - } Else { - Return (RBUF) - } + + /* Check if Serial IO DMA Controller is enabled */ + Return (RBUF) } Method (_STA, 0, NotSerialized) @@ -523,32 +434,24 @@ Device (UAR0) } } -Device (UAR1) +Device (SPI0) { - // Serial IO UART1 Controller - Method (_HID) - { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3435") - } - - // LynxPoint-LP - Return ("INT33C5") - } + /* Serial IO PI0 Controller */ + Name (_HID,"INT3440") Name (_UID, 1) - Name (_ADR, 0x00150006) + Name (_ADR, 0x001E0002) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {13} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_SPI0_IRQ } }) Method (_CRS, 0, NotSerialized) { - // Update BAR0 address and length if set in NVS + /* Update BAR0 address and length if set in NVS */ If (LNotEqual (\S6B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) @@ -567,7 +470,6 @@ Device (UAR1) Return (0xF) } } - Method (_PS0, 0, Serialized) { ^^LPD0 (\S6B1, \S6EN) @@ -579,37 +481,129 @@ Device (UAR1) } } -Device (SDIO) +Device (SPI1) { - // Serial IO SDIO Controller - Method (_HID) + /* Serial IO SPI1 Controller */ + Name (_HID,"INT3441") + Name (_UID, 1) + Name (_ADR, 0x001E0003) + + /* BAR0 is assigned during PCI enumeration and saved into NVS */ + Name (RBUF, ResourceTemplate () + { + Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_SPI1_IRQ } + }) + + /* DMA channels are only used if Serial IO DMA controller is enabled */ + Name (DBUF, ResourceTemplate () + { + FixedDMA (0x10, 0, Width32Bit, DMA1) /* Tx */ + FixedDMA (0x11, 1, Width32Bit, DMA2) /* Rx */ + }) + Method (_CRS, 0, NotSerialized) { - If (\ISWP ()) { - // WildcatPoint - Return ("INT3436") + /* Update BAR0 address and length if set in NVS */ + If (LNotEqual (\S7B0, Zero)) { + CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) + CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) + Store (\S7B0, B0AD) + Store (SIO_BAR_LEN, B0LN) } - // LynxPoint-LP - Return ("INT33C6") + Return (RBUF) + } + Method (_STA, 0, NotSerialized) + { + If (LEqual (\S7EN, 0)) { + Return (0x0) + } Else { + Return (0xF) + } + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (\S7B1, \S7EN) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (\S7B1, \S7EN) + } +} + +Device (UAR0) +{ + /* Serial IO UART0 Controller */ + Name (_HID,"INT3448") + Name (_UID, 1) + Name (_ADR, 0x001E0000) + + /* BAR0 is assigned during PCI enumeration and saved into NVS */ + Name (RBUF, ResourceTemplate () + { + Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_UART0_IRQ } + }) + + Method (_CRS, 0, NotSerialized) + { + /* Update BAR0 address and length if set in NVS */ + If (LNotEqual (\S8B0, Zero)) { + CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) + CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) + Store (\S8B0, B0AD) + Store (SIO_BAR_LEN, B0LN) + } + + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + If (LEqual (\S8EN, 0)) { + Return (0x0) + } Else { + Return (0xF) + } + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (\S8B1, \S8EN) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (\S8B1, \S8EN) } - Name (_CID, "PNP0D40") +} + +Device (UAR1) +{ + /* Serial IO UART1 Controller */ + Name (_HID,"INT3449") Name (_UID, 1) - Name (_ADR, 0x00170000) + Name (_ADR, 0x001E0001) - // BAR0 is assigned during PCI enumeration and saved into NVS + /* BAR0 is assigned during PCI enumeration and saved into NVS */ Name (RBUF, ResourceTemplate () { Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) {5} + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_UART1_IRQ } }) Method (_CRS, 0, NotSerialized) { // Update BAR0 address and length if set in NVS - If (LNotEqual (\S7B0, Zero)) { + If (LNotEqual (\S9B0, Zero)) { CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) - Store (\S7B0, B0AD) + Store (\S9B0, B0AD) Store (SIO_BAR_LEN, B0LN) } @@ -618,10 +612,97 @@ Device (SDIO) Method (_STA, 0, NotSerialized) { - If (LEqual (\S7EN, 0)) { + If (LEqual (\S9EN, 0)) { Return (0x0) } Else { Return (0xF) } } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (\S9B1, \S9EN) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (\S9B1, \S9EN) + } } + +Device (UAR2) +{ + /* Serial IO UART1 Controller */ + Name (_HID,"INT344A") + Name (_UID, 1) + Name (_ADR, 0x00190000) + + /* BAR0 is assigned during PCI enumeration and saved into NVS */ + Name (RBUF, ResourceTemplate () + { + Memory32Fixed (ReadWrite, 0x00000000, 0x00000000, BAR0) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared, , , ) + { LPSS_UART2_IRQ } + }) + + Method (_CRS, 0, NotSerialized) + { + /* Update BAR0 address and length if set in NVS */ + If (LNotEqual (\SAB0, Zero)) { + CreateDwordField (^RBUF, ^BAR0._BAS, B0AD) + CreateDwordField (^RBUF, ^BAR0._LEN, B0LN) + Store (\SAB0, B0AD) + Store (SIO_BAR_LEN, B0LN) + } + + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + If (LEqual (\SAEN, 0)) { + Return (0x0) + } Else { + Return (0xF) + } + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (\SAB1, \SAEN) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (\SAB1, \SAEN) + } +} + + +Device (PEMC) +{ + Name (_ADR, 0x001E0004) + Device (CARD) + { + Name (_ADR, 0x00000008) + Method (_RMV, 0x0, NotSerialized) + { + Return (0) + } + } +} + +/* SD controller */ +Device (PSDC) +{ + Name (_ADR, 0x001E0006) + Device (CARD) + { + Name (_ADR, 0x00000008) + Method (_RMV, 0x0, NotSerialized) + { + Return (1) + } + } +} + diff --git a/src/soc/intel/skylake/acpi/sleepstates.asl b/src/soc/intel/skylake/acpi/sleepstates.asl index 6fea862d86..dda7d14029 100644 --- a/src/soc/intel/skylake/acpi/sleepstates.asl +++ b/src/soc/intel/skylake/acpi/sleepstates.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ Name (\_S0, Package () { 0x0, 0x0, 0x0, 0x0 }) diff --git a/src/soc/intel/skylake/acpi/smbus.asl b/src/soc/intel/skylake/acpi/smbus.asl index 15bcfde69a..31a5114792 100644 --- a/src/soc/intel/skylake/acpi/smbus.asl +++ b/src/soc/intel/skylake/acpi/smbus.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,14 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ // Intel SMBus Controller 0:1f.3 Device (SBUS) { - Name (_ADR, 0x001f0003) + Name (_ADR, 0x001f0004) #ifdef ENABLE_SMBUS_METHODS OperationRegion (SMBP, PCI_Config, 0x00, 0x100) diff --git a/src/soc/intel/skylake/acpi/systemagent.asl b/src/soc/intel/skylake/acpi/systemagent.asl index c2049ea2e3..b8fec94e9e 100644 --- a/src/soc/intel/skylake/acpi/systemagent.asl +++ b/src/soc/intel/skylake/acpi/systemagent.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,11 +16,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <soc/iomap.h> +#define BASE_32GB 0x800000000 +#define SIZE_16GB 0x400000000 + Name (_HID, EISAID ("PNP0A08")) // PCIe Name (_CID, EISAID ("PNP0A03")) // PCI @@ -33,12 +37,86 @@ Device (MCHC) OperationRegion (MCHP, PCI_Config, 0x00, 0x100) Field (MCHP, DWordAcc, NoLock, Preserve) { + Offset(0x40), // EPBAR (0:0:0:40) + EPEN, 1, // Enable + , 11, + EPBR, 20, // EPBAR [31:12] + + Offset(0x48), // MCHBAR (0:0:0:48) + MHEN, 1, // Enable + , 14, + MHBR, 17, // MCHBAR [31:15] + + Offset(0x54), // DEVEN (0:0:0:54) + D0EN, 1, // DEV0 Enable + D1F2, 1, // DEV1 FUN2 Enable + D1F1, 1, // DEV1 FUN1 Enable + D1F0, 1, // DEV1 FUN0 Enable + + Offset(0x60), // PCIEXBAR (0:0:0:60) + PXEN, 1, // Enable + PXSZ, 2, // PCI Express Size + , 23, + PXBR, 6, // PCI Express BAR [31:26] + + Offset(0x68), // DMIBAR (0:0:0:68) + DIEN, 1, // Enable + , 11, + DIBR, 20, // DMIBAR [31:12] + Offset (0x70), // ME Base Address - MEBA, 64, + MEBA, 64, + + Offset(0x80), // PAM0 Register (0:0:0:80) + PMLK, 1, // PAM Lock bit. + , 3, + PM0H, 2, // PAM 0, High Nibble + , 2, + + Offset(0x81), // PAM1 Register (0:0:0:81) + PM1L, 2, // PAM1, Low Nibble + , 2, + PM1H, 2, // PAM1, High Nibble + , 2, + + Offset(0x82), // PAM2 Register (0:0:0:82) + PM2L, 2, // PAM2, Low Nibble + , 2, + PM2H, 2, // PAM2, High Nibble + , 2, + + Offset(0x83), // PAM3 Register (0:0:0:83) + PM3L, 2, // PAM3, Low Nibble + , 2, + PM3H, 2, // PAM3, High Nibble + , 2, + + Offset(0x84), // PAM4 Register (0:0:0:84) + PM4L, 2, // PAM4, Low Nibble + , 2, + PM4H, 2, // PAM4, High Nibble + , 2, + + Offset(0x85), // PAM5 Register (0:0:0:85) + PM5L, 2, // PAM5, Low Nibble + , 2, + PM5H, 2, // PAM5, High Nibble + , 2, + + Offset(0x86), // PAM6 Register (0:0:0:86) + PM6L, 2, // PAM6, Low Nibble + , 2, + PM6H, 2, // PAM6, High Nibble + , 2, + Offset (0xa0), // Top of Used Memory - TOM, 64, + TOM, 64, + + Offset (0xa8), // Top of Upper Used Memory + TUUD, 64, + Offset (0xbc), // Top of Low Used Memory - TLUD, 32, + TLUD, 32, } } @@ -48,161 +126,311 @@ Method (_CRS, 0, Serialized) { Name (MCRS, ResourceTemplate() { - // Bus Numbers + /* Bus Numbers */ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, PB00) - // IO Region 0 + /* IO Region 0 */ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00) - // PCI Config Space + /* PCI Config Space */ Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008) - // IO Region 1 + /* IO Region 1 */ DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300,,, PI01) - // VGA memory (0xa0000-0xbffff) + /* VGA memory (0xa0000-0xbffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000a0000, 0x000bffff, 0x00000000, 0x00020000,,, ASEG) - // OPROM reserved (0xc0000-0xc3fff) + /* OPROM reserved (0xc0000-0xc3fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000c0000, 0x000c3fff, 0x00000000, 0x00004000,,, OPR0) - // OPROM reserved (0xc4000-0xc7fff) + /* OPROM reserved (0xc4000-0xc7fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000c4000, 0x000c7fff, 0x00000000, 0x00004000,,, OPR1) - // OPROM reserved (0xc8000-0xcbfff) + /* OPROM reserved (0xc8000-0xcbfff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000c8000, 0x000cbfff, 0x00000000, 0x00004000,,, OPR2) - // OPROM reserved (0xcc000-0xcffff) + /* OPROM reserved (0xcc000-0xcffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000cc000, 0x000cffff, 0x00000000, 0x00004000,,, OPR3) - // OPROM reserved (0xd0000-0xd3fff) + /* OPROM reserved (0xd0000-0xd3fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000, 0x00004000,,, OPR4) - // OPROM reserved (0xd4000-0xd7fff) + /* OPROM reserved (0xd4000-0xd7fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000, 0x00004000,,, OPR5) - // OPROM reserved (0xd8000-0xdbfff) + /* OPROM reserved (0xd8000-0xdbfff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000, 0x00004000,,, OPR6) - // OPROM reserved (0xdc000-0xdffff) + /* OPROM reserved (0xdc000-0xdffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000dc000, 0x000dffff, 0x00000000, 0x00004000,,, OPR7) - // BIOS Extension (0xe0000-0xe3fff) + /* BIOS Extension (0xe0000-0xe3fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000, 0x00004000,,, ESG0) - // BIOS Extension (0xe4000-0xe7fff) + /* BIOS Extension (0xe4000-0xe7fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000, 0x00004000,,, ESG1) - // BIOS Extension (0xe8000-0xebfff) + /* BIOS Extension (0xe8000-0xebfff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000, 0x00004000,,, ESG2) - // BIOS Extension (0xec000-0xeffff) + /* BIOS Extension (0xec000-0xeffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000ec000, 0x000effff, 0x00000000, 0x00004000,,, ESG3) - // System BIOS (0xf0000-0xfffff) + /* System BIOS (0xf0000-0xfffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0x000f0000, 0x000fffff, 0x00000000, 0x00010000,,, FSEG) - // PCI Memory Region (Top of memory-CONFIG_MMCONF_BASE_ADDRESS) + /* PCI Memory Region (TOLUD - 0xdfffffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x00000000, 0xdfffffff, 0x00000000, + 0xE0000000,,, PM01) + + /* PCI Memory Region (TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE)) */ + QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x10000, 0x1ffff, 0x00000000, + 0x10000,,, PM02) + + /* PCH reserved resource (0xfd000000-0xfe7fffff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000,,, PM01) + 0x00000000, 0xfd000000, 0xfe7fffff, 0x00000000, + 0x1800000,,, PM03) - // TPM Area (0xfed40000-0xfed44fff) + /* TPM Area (0xfed40000-0xfed44fff) */ DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, 0xfed40000, 0xfed44fff, 0x00000000, 0x00005000,,, TPMR) }) - // Find PCI resource area in MCRS - CreateDwordField(MCRS, PM01._MIN, PMIN) - CreateDwordField(MCRS, PM01._MAX, PMAX) - CreateDwordField(MCRS, PM01._LEN, PLEN) + /* Find PCI resource area in MCRS */ + CreateDwordField (MCRS, PM01._MIN, PMIN) + CreateDwordField (MCRS, PM01._MAX, PMAX) + CreateDwordField (MCRS, PM01._LEN, PLEN) - // Fix up PCI memory region - // Start with Top of Lower Usable DRAM + /* + * Fix up PCI memory region + * Start with Top of Lower Usable DRAM + */ Store (^MCHC.TLUD, Local0) Store (^MCHC.MEBA, Local1) - // Check if ME base is equal + /* Check if ME base is equal */ If (LEqual (Local0, Local1)) { - // Use Top Of Memory instead + /* Use Top Of Memory instead */ Store (^MCHC.TOM, Local0) } Store (Local0, PMIN) - Store (Subtract(CONFIG_MMCONF_BASE_ADDRESS, 1), PMAX) - Add(Subtract(PMAX, PMIN), 1, PLEN) + Add (Subtract (PMAX, PMIN), 1, PLEN) + + /* Patch PM02 range based on Memory Size */ + CreateQwordField (MCRS, PM02._MIN, MMIN) + CreateQwordField (MCRS, PM02._MAX, MMAX) + CreateQwordField (MCRS, PM02._LEN, MLEN) + + Store (^MCHC.TUUD, Local0) + + If (LLessEqual (Local0, BASE_32GB)) + { + Store (BASE_32GB, MMIN) + Store (SIZE_16GB, MLEN) + } + else + { + Store (0, MMIN) + Store (0, MLEN) + } + Subtract (Add (MMIN, MLEN), 1, MMAX) Return (MCRS) } +Name (EP_B, 0) /* to store EP BAR */ +Name (MH_B, 0) /* to store MCH BAR */ +Name (PC_B, 0) /* to store PCIe BAR */ +Name (PC_L, 0) /* to store PCIe BAR Length */ +Name (DM_B, 0) /* to store DMI BAR */ + +/* Get MCH BAR */ +Method (GMHB,0,Serialized) +{ + if (LEqual (MH_B,0)) + { + ShiftLeft (\_SB.PCI0.MCHC.MHBR, 15, MH_B) + } + Return (MH_B) +} + +/* Get EP BAR */ +Method (GEPB,0,Serialized) +{ + if (LEqual (EP_B,0)) + { + ShiftLeft (\_SB.PCI0.MCHC.EPBR, 12, EP_B) + } + Return (EP_B) +} + +/* Get PCIe BAR */ +Method (GPCB,0,Serialized) +{ + if (LEqual (PC_B,0)) + { + ShiftLeft (\_SB.PCI0.MCHC.PXBR, 26, PC_B) + } + Return (PC_B) +} + +/* Get PCIe Length */ +Method (GPCL,0,Serialized) +{ + if (LEqual (PC_L,0)) + { + ShiftRight (0x10000000, \_SB.PCI0.MCHC.PXSZ, PC_L) + } + Return (PC_L) +} + +/* Get DMI BAR */ +Method (GDMB,0,Serialized) +{ + if (LEqual (DM_B,0)) + { + ShiftLeft (\_SB.PCI0.MCHC.DIBR, 12, DM_B) + } + Return (DM_B) +} + /* PCI Device Resource Consumption */ Device (PDRC) { Name (_HID, EISAID("PNP0C02")) Name (_UID, 1) - Name (PDRS, ResourceTemplate() { - Memory32Fixed (ReadWrite, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE) - Memory32Fixed (ReadWrite, MCH_BASE_ADDRESS, MCH_BASE_SIZE) - Memory32Fixed (ReadWrite, DMI_BASE_ADDRESS, DMI_BASE_SIZE) - Memory32Fixed (ReadWrite, EP_BASE_ADDRESS, EP_BASE_SIZE) - Memory32Fixed (ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE) - Memory32Fixed (ReadWrite, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE) - Memory32Fixed (ReadWrite, GDXC_BASE_ADDRESS, GDXC_BASE_SIZE) + Name (BUF0,ResourceTemplate() + { + /* MCH BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.48h + */ + Memory32Fixed (ReadWrite, 0, 0x08000, MCHB) + + /* DMI BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.68h + */ + Memory32Fixed (ReadWrite, 0, 0x01000, DMIB) + + /* EP BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.40h + */ + Memory32Fixed (ReadWrite, 0, 0x01000, EGPB) + + /* PCI Express BAR _BAS and _LEN will be updated in + * _CRS below according to B0:D0:F0:Reg.60h + */ + Memory32Fixed (ReadWrite, 0, 0, PCIX) + + /* MISC ICH TTT base address reserved for the + * TxT module use. + */ + Memory32Fixed (ReadWrite, 0xFED20000, 0x20000) + + /* VTD engine memory range. + * Check if the hard code meets the real configuration. + */ + Memory32Fixed (ReadOnly, 0xFED90000, 0x00004000) + + /* MISC ICH. Check if the hard code meets the + * real configuration. + */ + Memory32Fixed (ReadWrite, 0xFED45000, 0x4B000, TPMM) + + /* FLASH range */ + Memory32Fixed (ReadOnly, 0xFF000000, 0x1000000, FIOH) /* 16MB */ + + /* Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF) */ + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000, LIOH) + + /* Reserve HPET address decode range */ + Memory32Fixed (ReadWrite, 0, 0, HPET) + + /* Debug Base Address + * Base Address for ACPI debug output memory buffer + */ + Memory32Fixed (ReadWrite, 0, 0, DBAD) }) // Current Resource Settings Method (_CRS, 0, Serialized) { - Return (PDRS) + CreateDwordField (BUF0, ^MCHB._BAS, MBR0) + Store (\_SB.PCI0.GMHB(), MBR0) + + CreateDwordField (BUF0, ^DMIB._BAS, DBR0) + Store (\_SB.PCI0.GDMB(), DBR0) + + CreateDwordField (BUF0, ^EGPB._BAS, EBR0) + Store (\_SB.PCI0.GEPB(), EBR0) + + CreateDwordField (BUF0, ^PCIX._BAS, XBR0) + Store (\_SB.PCI0.GPCB(), XBR0) + + CreateDwordField (BUF0, ^PCIX._LEN, XSZ0) + Store (\_SB.PCI0.GPCL(), XSZ0) + + CreateDwordField (BUF0, ^HPET._BAS, HBAS) + CreateDwordField (BUF0, ^HPET._LEN, HLEN) + Store (0xfed00000, HBAS) + Store (0x400, HLEN) + + Return (BUF0) } } diff --git a/src/soc/intel/skylake/acpi/xhci.asl b/src/soc/intel/skylake/acpi/xhci.asl index c41275ccd2..f0ee414b52 100644 --- a/src/soc/intel/skylake/acpi/xhci.asl +++ b/src/soc/intel/skylake/acpi/xhci.asl @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,17 +16,17 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -// XHCI Controller 0:14.0 +/* XHCI Controller 0:14.0 */ Device (XHCI) { Name (_ADR, 0x00140000) - Name (PLSD, 5) // Port Link State - RxDetect - Name (PLSP, 7) // Port Link State - Polling + Name (PLSD, 5) /* Port Link State - RxDetect */ + Name (PLSP, 7) /* Port Link State - Polling */ OperationRegion (XPRT, PCI_Config, 0x00, 0x100) Field (XPRT, AnyAcc, NoLock, Preserve) @@ -34,68 +35,74 @@ Device (XHCI) DVID, 16, Offset (0x10), , 16, - XMEM, 16, // MEM_BASE - Offset (0x40), - , 11, - SWAI, 1, - , 20, - Offset (0x44), - , 12, - SAIP, 2, - , 18, + XMEM, 16, /* MEM_BASE */ Offset (0x74), D0D3, 2, , 6, - PMEE, 1, // PME_EN + PMEE, 1, /* PME_EN */ , 6, - PMES, 1, // PME_STS + PMES, 1, /* PME_STS */ + Offset (0xA8), + , 13, + MW13, 1, + MW14, 1, + , 17, Offset (0xb0), , 13, MB13, 1, MB14, 1, + , 17, Offset (0xd0), - PR2R, 32, // USB2PR - PR2M, 32, // USB2PRM - PR3R, 32, // USB3PR - PR3M, 32, // USB3PRM + PR2, 32, /* USB2PR */ + PR2M, 32, /* USB2PRM */ + PR3, 32, /* USB3PR */ + PR3M, 32, /* USB3PRM */ + } + + Method (USRA,0){ + Return(11) } - // Clear status bits + Method (SSPA,0){ + Return (13) + } + + /* Clear status bits */ Method (LPCL, 0, Serialized) { OperationRegion (XREG, SystemMemory, - ShiftLeft (^XMEM, 16), 0x600) + ShiftLeft (^XMEM, 16), 0x600) Field (XREG, DWordAcc, Lock, Preserve) { - Offset (0x510), // PORTSCNUSB3[0] + Offset (0x510), /* PORTSCNUSB3[0]*/ PSC0, 32, - Offset (0x520), // PORTSCNUSB3[1] + Offset (0x520), /* PORTSCNUSB3[1]*/ PSC1, 32, - Offset (0x530), // PORTSCNUSB3[2] + Offset (0x530), /* PORTSCNUSB3[2]*/ PSC2, 32, - Offset (0x540), // PORTSCNUSB3[3] + Offset (0x540), /* PORTSCNUSB3[3]*/ PSC3, 32, } - // Port Enabled/Disabled (Bit 1) + /* Port Enabled/Disabled (Bit 1)*/ Name (PEDB, ShiftLeft (1, 1)) - // Change Status (Bits 23:17) + /* Change Status (Bits 23:17)*/ Name (CHST, ShiftLeft (0x7f, 17)) - // Port 0 + /* Port 0 */ And (PSC0, Not (PEDB), Local0) Or (Local0, CHST, PSC0) - // Port 1 + /* Port 1 */ And (PSC1, Not (PEDB), Local0) Or (Local0, CHST, PSC1) - // Port 2 + /* Port 2 */ And (PSC2, Not (PEDB), Local0) Or (Local0, CHST, PSC2) - // Port 3 + /* Port 3 */ And (PSC3, Not (PEDB), Local0) Or (Local0, CHST, PSC3) } @@ -148,7 +155,7 @@ Device (XHCI) WPR4, 1, // [31] Warm Port Reset } - // Wait for all powered ports to finish polling + /* Wait for all powered ports to finish polling*/ Store (10, Local0) While (LOr (LOr (LAnd (LEqual (PPR1, 1), LEqual (PLS1, PLSP)), LAnd (LEqual (PPR2, 1), LEqual (PLS2, PLSP))), @@ -162,13 +169,13 @@ Device (XHCI) Stall (10) } - // For each USB3 Port: - // If port is disconnected (PLS=5 PP=1 CSC=0) - // 1) Issue warm reset (WPR=1) - // 2) Poll for warm reset complete (WRC=0) - // 3) Write 1 to port status to clear + /* For each USB3 Port:*/ + /* If port is disconnected (PLS=5 PP=1 CSC=0)*/ + /* 1) Issue warm reset (WPR=1)*/ + /* 2) Poll for warm reset complete (WRC=0)*/ + /* 3) Write 1 to port status to clear*/ - // Local# indicate if port is reset + /* Local# indicate if port is reset*/ Store (0, Local1) Store (0, Local2) Store (0, Local3) @@ -176,26 +183,26 @@ Device (XHCI) If (LAnd (LEqual (PLS1, PLSD), LAnd (LEqual (CSC1, 0), LEqual (PPR1, 1)))) { - Store (1, WPR1) // Issue warm reset + Store (1, WPR1) /* Issue warm reset*/ Store (1, Local1) } If (LAnd (LEqual (PLS2, PLSD), LAnd (LEqual (CSC2, 0), LEqual (PPR2, 1)))) { - Store (1, WPR2) // Issue warm reset + Store (1, WPR2) /* Issue warm reset*/ Store (1, Local2) } If (LAnd (LEqual (PLS3, PLSD), LAnd (LEqual (CSC3, 0), LEqual (PPR3, 1)))) { - Store (1, WPR3) // Issue warm reset + Store (1, WPR3) /* Issue warm reset*/ Store (1, Local3) } If (LAnd (LEqual (PLS4, PLSD), LAnd (LEqual (CSC4, 0), LEqual (PPR4, 1)))) { - Store (1, WPR4) // Issue warm reset + Store (1, WPR4) /* Issue warm reset*/ Store (1, Local4) } - // Poll for warm reset complete on all ports that were reset + /* Poll for warm reset complete on all ports that were reset*/ Store (10, Local0) While (LOr (LOr (LAnd (LEqual (Local1, 1), LEqual (WRC1, 0)), LAnd (LEqual (Local2, 1), LEqual (WRC2, 0))), @@ -209,7 +216,7 @@ Device (XHCI) Stall (10) } - // Clear status bits in all ports + /* Clear status bits in all ports */ LPCL () } @@ -220,152 +227,95 @@ Device (XHCI) Method (_PS0, 0, Serialized) { - If (LEqual (^DVID, 0xFFFF)) { - Return () - } - If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) { - Return () - } - - OperationRegion (XREG, SystemMemory, - Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200) - Field (XREG, DWordAcc, Lock, Preserve) - { - Offset (0x0e0), // AUX Reset Control 1 - , 15, - AX15, 1, - Offset (0x154), // AUX Domain PM Control Register 2 - , 31, - CLK2, 1, - Offset (0x16c), // AUX Clock Control - , 2, - CLK0, 1, - , 11, - CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable - } - - // If device is in D3, set back to D0 - Store (^D0D3, Local0) - if (LEqual (Local0, 3)) { - Store (0, ^D0D3) - } - - if (LNot (\ISWP())) { - // Clear PCI 0xB0[14:13] - Store (0, ^MB13) - Store (0, ^MB14) - - // Clear MMIO 0x816C[14,2] - Store (0, CLK0) - Store (0, CLK1) - - // Set MMIO 0x8154[31] - Store (1, CLK2) - - // Handle per-port reset if needed - LPS0 () - - // Set MMIO 0x80e0[15] - Store (1, AX15) - - // Clear PCI CFG offset 0x40[11] - Store (0, ^SWAI) - - // Clear PCI CFG offset 0x44[13:12] - Store (0, ^SAIP) - } - - Return () } - Method (_PS3, 0, Serialized) { - If (LEqual (^DVID, 0xFFFF)) { - Return () - } - If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) { - Return () - } - - OperationRegion (XREG, SystemMemory, - Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200) - Field (XREG, DWordAcc, Lock, Preserve) - { - Offset (0x0e0), // AUX Reset Control 1 - , 15, - AX15, 1, - Offset (0x154), // AUX Domain PM Control Register 2 - , 31, - CLK2, 1, - Offset (0x16c), // AUX Clock Control - , 2, - CLK0, 1, - , 11, - CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable - } - - Store (1, ^PMES) // Clear PME Status - Store (1, ^PMEE) // Enable PME - - // If device is in D3, set back to D0 - Store (^D0D3, Local0) - if (LEqual (Local0, 3)) { - Store (0, ^D0D3) - } - - if (LNot (\ISWP())) { - // Set PCI 0xB0[14:13] - Store (1, ^MB13) - Store (1, ^MB14) - - // Set MMIO 0x816C[14,2] - Store (1, CLK0) - Store (1, CLK1) - - // Clear MMIO 0x8154[31] - Store (0, CLK2) - - // Clear MMIO 0x80e0[15] - Store (0, AX15) - - // Set PCI CFG offset 0x40[11] - Store (1, ^SWAI) - - // Set PCI CFG offset 0x44[13:12] - Store (1, ^SAIP) - } - - // Put device in D3 - Store (3, ^D0D3) - - Return () } Name (_PRW, Package(){ 0x6d, 3 }) - // Leave USB ports on for to allow Wake from USB + /* Leave USB ports on for to allow Wake from USB */ - Method(_S3D,0) // Highest D State in S3 State + Method (_S3D,0) /* Highest D State in S3 State*/ { Return (3) } - Method(_S4D,0) // Highest D State in S4 State + Method (_S4D,0) /* Highest D State in S4 State*/ { Return (3) } - - Device (HUB7) + Device (HS01) { - Name (_ADR, 0x00000000) - - // How many are there? - Device (PRT1) { Name (_ADR, 1) } // USB Port 0 - Device (PRT2) { Name (_ADR, 2) } // USB Port 1 - Device (PRT3) { Name (_ADR, 3) } // USB Port 2 - Device (PRT4) { Name (_ADR, 4) } // USB Port 3 - Device (PRT5) { Name (_ADR, 5) } // USB Port 4 - Device (PRT6) { Name (_ADR, 6) } // USB Port 5 + Name(_ADR, 0x01) + } + Device (HS02) + { + Name(_ADR, 0x02) + } + Device (HS03) + { + Name(_ADR, 0x03) + } + Device (HS04) + { + Name(_ADR, 0x04) + } + Device (HS05) + { + Name(_ADR, 0x05) + } + Device (HS06) + { + Name(_ADR, 0x06) + } + Device (HS07) + { + Name(_ADR, 0x07) + } + Device (HS08) + { + Name(_ADR, 0x08) + } + Device (HS09) + { + Name(_ADR, 0x09) + } + Device (HS10) + { + Name(_ADR, 0x10) + } + Device (USR1) + { + Method(_ADR) { Return (Add(USRA(),0)) } + } + Device (USR2) + { + Method(_ADR) { Return (Add(USRA(),1)) } + } + Device (SS01) + { + Method(_ADR) { Return (Add(SSPA(),0)) } + } + Device (SS02) + { + Method(_ADR) { Return (Add(SSPA(),1)) } + } + Device (SS03) + { + Method(_ADR) { Return (Add(SSPA(),2)) } + } + Device (SS04) + { + Method(_ADR) { Return (Add(SSPA(),3)) } + } + Device (SS05) + { + Method(_ADR) { Return (Add(SSPA(),4)) } + } + Device (SS06) + { + Method(_ADR) { Return (Add(SSPA(),5)) } } } diff --git a/src/soc/intel/skylake/adsp.c b/src/soc/intel/skylake/adsp.c deleted file mode 100644 index 1a7cca7975..0000000000 --- a/src/soc/intel/skylake/adsp.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cbmem.h> -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> -#include <arch/io.h> -#include <delay.h> -#include <soc/adsp.h> -#include <soc/device_nvs.h> -#include <soc/iobp.h> -#include <soc/nvs.h> -#include <soc/pch.h> -#include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/intel/broadwell/chip.h> - -static void adsp_init(struct device *dev) -{ - config_t *config = dev->chip_info; - struct resource *bar0, *bar1; - u32 tmp32; - - /* Ensure memory and bus master are enabled */ - tmp32 = pci_read_config32(dev, PCI_COMMAND); - tmp32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(dev, PCI_COMMAND, tmp32); - - /* Find BAR0 and BAR1 */ - bar0 = find_resource(dev, PCI_BASE_ADDRESS_0); - if (!bar0) - return; - bar1 = find_resource(dev, PCI_BASE_ADDRESS_1); - if (!bar1) - return; - - /* - * Set LTR value in DSP shim LTR control register to 3ms - * SNOOP_REQ[13]=1b SNOOP_SCALE[12:10]=100b (1ms) SNOOP_VAL[9:0]=3h - */ - tmp32 = pch_is_wpt() ? ADSP_SHIM_BASE_WPT : ADSP_SHIM_BASE_LPT; - write32(res2mmio(bar0, tmp32 + ADSP_SHIM_LTRC, 0), - ADSP_SHIM_LTRC_VALUE); - - /* Program VDRTCTL2 D19:F0:A8[31:0] = 0x00000fff */ - pci_write_config32(dev, ADSP_PCI_VDRTCTL2, ADSP_VDRTCTL2_VALUE); - - /* Program ADSP IOBP VDLDAT1 to 0x040100 */ - pch_iobp_write(ADSP_IOBP_VDLDAT1, ADSP_VDLDAT1_VALUE); - - /* Set D3 Power Gating Enable in D19:F0:A0 based on PCH type */ - tmp32 = pci_read_config32(dev, ADSP_PCI_VDRTCTL0); - if (pch_is_wpt()) { - if (config->adsp_d3_pg_enable) { - tmp32 &= ~ADSP_VDRTCTL0_D3PGD_WPT; - if (config->adsp_sram_pg_enable) - tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_WPT; - else - tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_WPT; - } else { - tmp32 |= ADSP_VDRTCTL0_D3PGD_WPT; - } - } else { - if (config->adsp_d3_pg_enable) { - tmp32 &= ~ADSP_VDRTCTL0_D3PGD_LPT; - if (config->adsp_sram_pg_enable) - tmp32 &= ~ADSP_VDRTCTL0_D3SRAMPGD_LPT; - else - tmp32 |= ADSP_VDRTCTL0_D3SRAMPGD_LPT; - } else { - tmp32 |= ADSP_VDRTCTL0_D3PGD_LPT; - } - } - pci_write_config32(dev, ADSP_PCI_VDRTCTL0, tmp32); - - /* Set PSF Snoop to SA, RCBA+0x3350[10]=1b */ - RCBA32_OR(0x3350, (1 << 10)); - - /* Set DSP IOBP PMCTL 0x1e0=0x3f */ - pch_iobp_write(ADSP_IOBP_PMCTL, ADSP_PMCTL_VALUE); - - if (config->sio_acpi_mode) { - /* Configure for ACPI mode */ - global_nvs_t *gnvs; - - printk(BIOS_INFO, "ADSP: Enable ACPI Mode IRQ3\n"); - - /* Find ACPI NVS to update BARs */ - gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS); - if (!gnvs) { - printk(BIOS_ERR, "Unable to locate Global NVS\n"); - return; - } - - /* Save BAR0 and BAR1 to ACPI NVS */ - gnvs->dev.bar0[SIO_NVS_ADSP] = (u32)bar0->base; - gnvs->dev.bar1[SIO_NVS_ADSP] = (u32)bar1->base; - gnvs->dev.enable[SIO_NVS_ADSP] = 1; - - /* Set PCI Config Disable Bit */ - pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~0, ADSP_PCICFGCTL_PCICD); - - /* Set interrupt de-assert/assert opcode override to IRQ3 */ - pch_iobp_write(ADSP_IOBP_VDLDAT2, ADSP_IOBP_ACPI_IRQ3); - - /* Enable IRQ3 in RCBA */ - RCBA32_OR(ACPIIRQEN, ADSP_ACPI_IRQEN); - - /* Set ACPI Interrupt Enable Bit */ - pch_iobp_update(ADSP_IOBP_PCICFGCTL, ~ADSP_PCICFGCTL_SPCBAD, - ADSP_PCICFGCTL_ACPIIE); - - /* Put ADSP in D3hot */ - tmp32 = read32(res2mmio(bar1, PCH_PCS, 0)); - tmp32 |= PCH_PCS_PS_D3HOT; - write32(res2mmio(bar1, PCH_PCS, 0), tmp32); - } else { - printk(BIOS_INFO, "ADSP: Enable PCI Mode IRQ23\n"); - - /* Configure for PCI mode */ - pci_write_config32(dev, PCI_INTERRUPT_LINE, ADSP_PCI_IRQ); - - /* Clear ACPI Interrupt Enable Bit */ - pch_iobp_update(ADSP_IOBP_PCICFGCTL, - ~(ADSP_PCICFGCTL_SPCBAD | ADSP_PCICFGCTL_ACPIIE), 0); - } -} - -static struct device_operations adsp_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .init = &adsp_init, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c36, /* LynxPoint */ - 0x9cb6, /* WildcatPoint */ - 0 -}; - -static const struct pci_driver pch_adsp __pci_driver = { - .ops = &adsp_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; - diff --git a/src/soc/intel/skylake/bootblock/Makefile.inc b/src/soc/intel/skylake/bootblock/Makefile.inc index 2ca5a4569f..a31f588f58 100644 --- a/src/soc/intel/skylake/bootblock/Makefile.inc +++ b/src/soc/intel/skylake/bootblock/Makefile.inc @@ -1 +1 @@ -chipset_bootblock_inc += $(src)/soc/intel/broadwell/bootblock/timestamp.inc +chipset_bootblock_inc += $(src)/soc/intel/skylake/bootblock/timestamp.inc diff --git a/src/soc/intel/skylake/bootblock/cpu.c b/src/soc/intel/skylake/bootblock/cpu.c index 3a47d13f0a..d4506e592a 100644 --- a/src/soc/intel/skylake/bootblock/cpu.c +++ b/src/soc/intel/skylake/bootblock/cpu.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <stdint.h> @@ -22,11 +23,18 @@ #include <cpu/x86/cache.h> #include <cpu/x86/msr.h> #include <cpu/x86/mtrr.h> +#include <device/pci_def.h> #include <arch/io.h> -#include <halt.h> #include <cpu/intel/microcode/microcode.c> -#include <soc/rcba.h> +#include <reset.h> #include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/spi.h> + +/* Soft Reset Data Register Bit 12 = MAX Boot Frequency */ +#define SPI_STRAP_MAX_FREQ (1<<12) +/* Soft Reset Data Register Bit 6-11 = Flex Ratio */ +#define FLEX_RATIO_BIT 6 static void set_var_mtrr( unsigned reg, unsigned base, unsigned size, unsigned type) @@ -47,7 +55,6 @@ static void enable_rom_caching(void) msr_t msr; disable_cache(); - /* Why only top 4MiB ? */ set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT); enable_cache(); @@ -68,10 +75,59 @@ static void bootblock_mdelay(int ms) } while ((current.lo - start.lo) < target); } +static void set_pch_cpu_strap(u8 flex_ratio) +{ + device_t dev = PCH_DEV_SPI; + uint8_t *spibar = (void *)TEMP_SPI_BAR; + u32 ssl, ssms, soft_reset_data; + u8 pcireg; + + /* Assign Resources to SPI Controller */ + /* Clear BIT 1-2 SPI Command Register */ + pcireg = pci_read_config8(dev, PCI_COMMAND); + pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config8(dev, PCI_COMMAND, pcireg); + + /* Program Temporary BAR for SPI */ + pci_write_config32(dev, PCH_SPI_BASE_ADDRESS, TEMP_SPI_BAR); + + /* Enable Bus Master and MMIO Space */ + pcireg = pci_read_config8(dev, PCI_COMMAND); + pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config8(dev, PCI_COMMAND, pcireg); + + /* Set Strap Lock Disable*/ + ssl = read32(spibar + SPIBAR_RESET_LOCK); + ssl |= SPIBAR_RESET_LOCK_DISABLE; + write32(spibar + SPIBAR_RESET_LOCK, ssl); + + /* Soft Reset Data Register Bit 12 = MAX Boot Frequency + * Bit 6-11 = Flex Ratio + * Soft Reset Data register located at SPIBAR0 offset 0xF8[0:15]. + */ + soft_reset_data = SPI_STRAP_MAX_FREQ; + soft_reset_data |= (flex_ratio << FLEX_RATIO_BIT); + write32(spibar + SPIBAR_RESET_DATA, soft_reset_data); + + /* Set Strap Mux Select set to '1' */ + ssms = read32(spibar + SPIBAR_RESET_CTRL); + ssms |= SPIBAR_RESET_CTRL_SSMC; + write32(spibar + SPIBAR_RESET_CTRL, ssms); + + /* Set Strap Lock Enable*/ + ssl = read32(spibar + SPIBAR_RESET_LOCK); + ssl |= SPIBAR_RESET_LOCK_ENABLE; + write32(spibar + SPIBAR_RESET_LOCK, ssl); + + /* Disable SPI Controller MMIO space */ + pcireg = pci_read_config8(dev, PCI_COMMAND); + pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config8(dev, PCI_COMMAND, pcireg); +} + static void set_flex_ratio_to_tdp_nominal(void) { msr_t flex_ratio, msr; - u32 soft_reset; u8 nominal_ratio; /* Check for Flex Ratio support */ @@ -98,23 +154,14 @@ static void set_flex_ratio_to_tdp_nominal(void) flex_ratio.lo |= FLEX_RATIO_LOCK; wrmsr(MSR_FLEX_RATIO, flex_ratio); - /* Set flex ratio in soft reset data register bits 11:6. - * RCBA region is enabled in southbridge bootblock */ - soft_reset = RCBA32(SOFT_RESET_DATA); - soft_reset &= ~(0x3f << 6); - soft_reset |= (nominal_ratio & 0x3f) << 6; - RCBA32(SOFT_RESET_DATA) = soft_reset; - - /* Set soft reset control to use register value */ - RCBA32_OR(SOFT_RESET_CTRL, 1); + /* Set PCH Soft Reset Data Register with new Flex Ratio */ + set_pch_cpu_strap(nominal_ratio); /* Delay before reset to avoid potential TPM lockout */ bootblock_mdelay(30); - /* Issue warm reset, will be "CPU only" due to soft reset data */ - outb(0x0, 0xcf9); - outb(0x6, 0xcf9); - halt(); + /* Issue soft reset, will be "CPU only" due to soft reset data */ + soft_reset(); } static void check_for_clean_reset(void) @@ -122,14 +169,13 @@ static void check_for_clean_reset(void) msr_t msr; msr = rdmsr(MTRRdefType_MSR); - /* Use the MTRR default type MSR as a proxy for detecting INIT#. + /* + * 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. */ - if (msr.lo & (MTRRdefTypeEn | MTRRdefTypeFixEn)) { - outb(0x0, 0xcf9); - outb(0x6, 0xcf9); - halt(); - } + * an indication of the CPU not being properly reset. + */ + if (msr.lo & (MTRRdefTypeEn | MTRRdefTypeFixEn)) + soft_reset(); } static void bootblock_cpu_init(void) diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c index 2fa722097c..9f256e3a95 100644 --- a/src/soc/intel/skylake/bootblock/pch.c +++ b/src/soc/intel/skylake/bootblock/pch.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,14 +15,12 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ - #include <arch/io.h> #include <soc/iomap.h> #include <soc/lpc.h> #include <soc/pci_devs.h> -#include <soc/rcba.h> #include <soc/spi.h> /* @@ -29,51 +28,13 @@ */ static void enable_spi_prefetch(void) { - u8 reg8 = pci_read_config8(PCH_DEV_LPC, 0xdc); + u8 reg8 = pci_read_config8(PCH_DEV_SPI, 0xdc); reg8 &= ~(3 << 2); reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ - pci_write_config8(PCH_DEV_LPC, 0xdc, reg8); -} - - -static void map_rcba(void) -{ - pci_write_config32(PCH_DEV_LPC, RCBA, RCBA_BASE_ADDRESS | 1); -} - -static void enable_port80_on_lpc(void) -{ - /* Enable port 80 POST on LPC. The chipset does this by default, - * but it doesn't appear to hurt anything. */ - u32 gcs = RCBA32(GCS); - gcs = gcs & ~0x4; - RCBA32(GCS) = gcs; -} - -static void set_spi_speed(void) -{ - u32 fdod; - u8 ssfc; - - /* Observe SPI Descriptor Component Section 0 */ - SPIBAR32(SPIBAR_FDOC) = 0x1000; - - /* Extract the Write/Erase SPI Frequency from descriptor */ - fdod = SPIBAR32(SPIBAR_FDOD); - fdod >>= 24; - fdod &= 7; - - /* Set Software Sequence frequency to match */ - ssfc = SPIBAR8(SPIBAR_SSFC + 2); - ssfc &= ~7; - ssfc |= fdod; - SPIBAR8(SPIBAR_SSFC + 2) = ssfc; + pci_write_config8(PCH_DEV_SPI, 0xdc, reg8); } static void bootblock_southbridge_init(void) { - map_rcba(); enable_spi_prefetch(); - enable_port80_on_lpc(); - set_spi_speed(); } diff --git a/src/soc/intel/skylake/bootblock/systemagent.c b/src/soc/intel/skylake/bootblock/systemagent.c index 15e7fc88b4..6f029f0053 100644 --- a/src/soc/intel/skylake/bootblock/systemagent.c +++ b/src/soc/intel/skylake/bootblock/systemagent.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> @@ -32,7 +33,7 @@ static void bootblock_northbridge_init(void) * MCFG. This code also assumes that bootblock_northbridge_init() is * the first thing called in the non-asm boot block code. The final * assumption is that no assembly code is using the - * CONFIG_MMCONF_SUPPORT_DEFAULT option to do PCI config accesses. + * CONFIG_MMCONF_SUPPORT_DEFAULT option to do PCI config acceses. * * The PCIEXBAR is assumed to live in the memory mapped IO space under * 4GiB. diff --git a/src/soc/intel/skylake/bootblock/timestamp.inc b/src/soc/intel/skylake/bootblock/timestamp.inc index f565775ed8..e5041326ee 100644 --- a/src/soc/intel/skylake/bootblock/timestamp.inc +++ b/src/soc/intel/skylake/bootblock/timestamp.inc @@ -1,6 +1,8 @@ -/* Store the initial timestamp for booting in mmx registers. This works +/* + * Store the initial timestamp for booting in mmx registers. This works * because the bootblock isn't being compiled with MMX support so mm0 and - * mm1 will be preserved into romstage. */ + * mm1 will be preserved into romstage. + */ .code32 .global stash_timestamp diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 00261522ce..f1a104c879 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,15 +15,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <chip.h> #include <console/console.h> #include <device/device.h> #include <device/pci.h> +#include <fsp_util.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> -#include <soc/intel/broadwell/chip.h> static void pci_domain_set_resources(device_t dev) { @@ -36,14 +38,20 @@ static struct device_operations pci_domain_ops = { .ops_pci_bus = &pci_bus_default_ops, }; +static void chip_final(device_t dev) +{ + /* Notify FSP done device setup */ + printk(BIOS_DEBUG, + "Calling FspNotify(EnumInitPhaseAfterPciEnumeration)\n"); + fsp_notify(EnumInitPhaseAfterPciEnumeration); +} + static struct device_operations cpu_bus_ops = { - .read_resources = DEVICE_NOOP, - .set_resources = DEVICE_NOOP, - .enable_resources = DEVICE_NOOP, - .init = &broadwell_init_cpus, + .init = &soc_init_cpus, + .final = &chip_final, }; -static void broadwell_enable(device_t dev) +static void soc_enable(device_t dev) { /* Set the operations if it is a special bus type */ if (dev->path.type == DEVICE_PATH_DOMAIN) { @@ -52,19 +60,48 @@ static void broadwell_enable(device_t dev) dev->ops = &cpu_bus_ops; } else if (dev->path.type == DEVICE_PATH_PCI) { /* Handle PCH device enable */ - if (PCI_SLOT(dev->path.pci.devfn) > SA_DEV_SLOT_MINIHD && + if (PCI_SLOT(dev->path.pci.devfn) > SA_DEV_SLOT_IGD && (dev->ops == NULL || dev->ops->enable == NULL)) { - broadwell_pch_enable_dev(dev); + pch_enable_dev(dev); } } } -struct chip_operations soc_intel_broadwell_ops = { - CHIP_NAME("Intel Broadwell") - .enable_dev = &broadwell_enable, - .init = &broadwell_init_pre_device, +struct chip_operations soc_intel_skylake_ops = { + CHIP_NAME("Intel Skylake") + .enable_dev = &soc_enable, + .init = &soc_init_pre_device, }; +/* UPD parameters to be initialized before SiliconInit */ +void soc_silicon_init_params(SILICON_INIT_UPD *params) +{ + const struct device *dev; + const struct soc_intel_skylake_config *config; + + /* Set the parameters for SiliconInit */ + dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); + if (!dev || !dev->chip_info) + return; + config = dev->chip_info; + + params->Device4Enable = config->Device4Enable; +} + +void soc_display_silicon_init_params(const SILICON_INIT_UPD *original, + SILICON_INIT_UPD *params) +{ + /* Display the parameters for SiliconInit */ + printk(BIOS_SPEW, "UPD values for SiliconInit:\n"); + + soc_display_upd_value("GpioTablePtr", 4, + (uint32_t)original->GpioTablePtr, + (uint32_t)params->GpioTablePtr); + soc_display_upd_value("Device4Enable", 1, + original->Device4Enable, + params->Device4Enable); +} + static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device) { if (!vendor || !device) @@ -75,6 +112,6 @@ static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device) (device << 16) | vendor); } -struct pci_operations broadwell_pci_ops = { +struct pci_operations soc_pci_ops = { .set_subsystem = &pci_set_subsystem }; diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 77c517d5ec..15e211e209 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2008 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,13 +16,17 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _SOC_INTEL_BROADWELL_CHIP_H_ -#define _SOC_INTEL_BROADWELL_CHIP_H_ +#include <stdint.h> +#include <soc/pci_devs.h> +#include <soc/serialio.h> -struct soc_intel_broadwell_config { +#ifndef _SOC_CHIP_H_ +#define _SOC_CHIP_H_ + +struct soc_intel_skylake_config { /* * Interrupt Routing configuration * If bit7 is 1, the interrupt is disabled. @@ -42,29 +47,9 @@ struct soc_intel_broadwell_config { uint32_t gpe0_en_4; /* GPIO SMI configuration */ + uint32_t ec_smi_gpio; uint32_t alt_gp_smi_en; - /* IDE configuration */ - uint8_t sata_port_map; - uint32_t sata_port0_gen3_tx; - uint32_t sata_port1_gen3_tx; - uint32_t sata_port0_gen3_dtle; - uint32_t sata_port1_gen3_dtle; - - /* - * SATA DEVSLP Mux - * 0 = port 0 DEVSLP on DEVSLP0/GPIO33 - * 1 = port 3 DEVSLP on DEVSLP0/GPIO33 - */ - uint8_t sata_devslp_mux; - - /* - * DEVSLP Disable - * 0: DEVSLP is enabled - * 1: DEVSLP is disabled - */ - uint8_t sata_devslp_disable; - /* Generic IO decode ranges */ uint32_t gen1_dec; uint32_t gen2_dec; @@ -77,13 +62,6 @@ struct soc_intel_broadwell_config { /* Force root port ASPM configuration with port bitmap */ uint8_t pcie_port_force_aspm; - /* Put SerialIO devices into ACPI mode instead of a PCI device */ - uint8_t sio_acpi_mode; - - /* I2C voltage select: 0=3.3V 1=1.8V */ - uint8_t sio_i2c0_voltage; - uint8_t sio_i2c1_voltage; - /* Enable ADSP power gating features */ uint8_t adsp_d3_pg_enable; uint8_t adsp_sram_pg_enable; @@ -130,37 +108,125 @@ struct soc_intel_broadwell_config { /* Enable S0iX support */ int s0ix_enable; + /* Deep SX enable for both AC and DC */ + int deep_s3_enable; + int deep_s5_enable; + + /* TCC activation offset */ + int tcc_offset; + /* - * Minimum voltage for C6/C7 state: - * 0x67 = 1.6V (full swing) - * ... - * 0x79 = 1.7V - * ... - * 0x83 = 1.8V (no swing) + * The following fields come from fsp_vpd.h. + * These are configuration values that are passed to FSP during + * MemoryInit. */ - int vr_cpu_min_vid; + u64 PlatformMemorySize; + u8 SmramMask; + u8 MrcFastBoot; + u32 IedSize; + u32 TsegSize; + u16 MmioSize; + + /* Probeless Trace function */ + u8 ProbelessTrace; + + /* Lan */ + u8 EnableLan; + + /* SATA related */ + u8 EnableSata; + u8 SataMode; + u8 SataSalpSupport; + u8 SataPortsEnable[8]; + u8 SataPortsDevSlp[8]; + + /* Audio related */ + u8 EnableAzalia; + u8 DspEnable; + u8 IoBufferOwnership; + + /* Trace Hub function */ + u8 EnableTraceHub; + + /* Pcie Root Ports */ + u8 PcieRpEnable[20]; + u8 PcieRpClkReqSupport[20]; + u8 PcieRpClkReqNumber[20]; + + /* USB related */ + u8 PortUsb20Enable[16]; + u8 PortUsb30Enable[10]; + u8 XdciEnable; + u8 SsicPortEnable; + + /* SMBus */ + u8 SmbusEnable; /* - * Set slow VR ramp rate on C-state exit: - * 0 = Fast VR ramp rate / 2 - * 1 = Fast VR ramp rate / 4 - * 2 = Fast VR ramp rate / 8 - * 3 = Fast VR ramp rate / 16 + * SerialIO device mode selection: + * + * Device index: + * PchSerialIoIndexI2C0 + * PchSerialIoIndexI2C1 + * PchSerialIoIndexI2C2 + * PchSerialIoIndexI2C3 + * PchSerialIoIndexI2C4 + * PchSerialIoIndexI2C5 + * PchSerialIoIndexI2C6 + * PchSerialIoIndexSpi0 + * PchSerialIoIndexSpi1 + * PchSerialIoIndexUart0 + * PchSerialIoIndexUart1 + * PchSerialIoIndexUart2 + * + * Mode select: + * PchSerialIoDisabled + * PchSerialIoAcpi + * PchSerialIoPci + * PchSerialIoAcpiHidden + * PchSerialIoLegacyUart */ - int vr_slow_ramp_rate_set; + u8 SerialIoDevMode[PchSerialIoIndexMax]; - /* Enable slow VR ramp rate */ - int vr_slow_ramp_rate_enable; + /* Camera */ + u8 Cio2Enable; - /* Deep SX enable */ - int deep_sx_enable_ac; - int deep_sx_enable_dc; + /* eMMC and SD */ + u8 ScsEmmcEnabled; + u8 ScsEmmcHs400Enabled; + u8 ScsSdCardEnabled; - /* TCC activation offset */ - int tcc_offset; + /* Integrated Sensor */ + u8 IshEnable; + + /* SPI related */ + u8 ShowSpiController; + + u8 PttSwitch; + u8 HeciTimeouts; + u8 HsioMessaging; + u8 Heci3Enabled; + + /* Gfx related */ + u8 IgdDvmt50PreAlloc; + u8 PrimaryDisplay; + u8 InternalGfx; + u8 ApertureSize; + u8 SkipExtGfxScan; + u8 ScanExtGfxForLegacyOpRom; + + /* + * The following fields come from fsp_vpd.h + * These are configuration values that are passed to FSP during + * SiliconInit. + */ + u32 LogoPtr; + u32 LogoSize; + u32 GraphicsConfigPtr; + u8 Device4Enable; }; -typedef struct soc_intel_broadwell_config config_t; +typedef struct soc_intel_skylake_config config_t; extern struct chip_operations soc_ops; diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 984ff7658a..cd88c10e76 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <console/console.h> @@ -23,6 +24,7 @@ #include <device/pci.h> #include <string.h> #include <arch/acpi.h> +#include <chip.h> #include <cpu/cpu.h> #include <cpu/x86/mtrr.h> #include <cpu/x86/msr.h> @@ -40,10 +42,8 @@ #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> -#include <soc/rcba.h> #include <soc/smm.h> #include <soc/systemagent.h> -#include <soc/intel/broadwell/chip.h> /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { @@ -103,9 +103,11 @@ static const u8 power_limit_time_msr_to_sec[] = { [0x11] = 128, }; -/* The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate +/* + * The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate * the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly - * when a core is woken up. */ + * when a core is woken up. + */ static int pcode_ready(void) { int wait_count; @@ -159,57 +161,18 @@ static void calibrate_24mhz_bclk(void) MCHBAR32(BIOS_MAILBOX_DATA)); } -static u32 pcode_mailbox_read(u32 command) -{ - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); - return 0; - } - - /* Send command and start transaction */ - MCHBAR32(BIOS_MAILBOX_INTERFACE) = command | MAILBOX_RUN_BUSY; - - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); - return 0; - } - - /* Read mailbox */ - return MCHBAR32(BIOS_MAILBOX_DATA); -} - -static int pcode_mailbox_write(u32 command, u32 data) -{ - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); - return -1; - } - - MCHBAR32(BIOS_MAILBOX_DATA) = data; - - /* Send command and start transaction */ - MCHBAR32(BIOS_MAILBOX_INTERFACE) = command | MAILBOX_RUN_BUSY; - - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); - return -1; - } - - return 0; -} - static void initialize_vr_config(void) { - device_t dev = SA_DEV_ROOT; - config_t *conf = dev->chip_info; msr_t msr; printk(BIOS_DEBUG, "Initializing VR config.\n"); /* Configure VR_CURRENT_CONFIG. */ msr = rdmsr(MSR_VR_CURRENT_CONFIG); - /* Preserve bits 63 and 62. Bit 62 is PSI4 enable, but it is only valid - * on ULT systems. */ + /* + * Preserve bits 63 and 62. Bit 62 is PSI4 enable, but it is only valid + * on ULT systems. + */ msr.hi &= 0xc0000000; msr.hi |= (0x01 << (52 - 32)); /* PSI3 threshold - 1A. */ msr.hi |= (0x05 << (42 - 32)); /* PSI2 threshold - 5A. */ @@ -225,88 +188,31 @@ static void initialize_vr_config(void) msr.hi |= (0x200 << (40 - 32)); /* 1.0 */ /* Set IOUT_OFFSET to 0. */ msr.hi &= ~0xff; + /* Set exit ramp rate to fast. */ + msr.hi |= (1 << (50 - 32)); /* Set entry ramp rate to slow. */ msr.hi &= ~(1 << (51 - 32)); /* Enable decay mode on C-state entry. */ msr.hi |= (1 << (52 - 32)); - /* Set the slow ramp rate */ + /* Set the slow ramp rate to be fast ramp rate / 4 */ msr.hi &= ~(0x3 << (53 - 32)); - /* Configure the C-state exit ramp rate. */ - if (conf->vr_slow_ramp_rate_enable) { - /* Configured slow ramp rate. */ - msr.hi |= ((conf->vr_slow_ramp_rate_set & 0x3) << (53 - 32)); - /* Set exit ramp rate to slow. */ - msr.hi &= ~(1 << (50 - 32)); - } else { - /* Fast ramp rate / 4. */ - msr.hi |= (0x01 << (53 - 32)); - /* Set exit ramp rate to fast. */ - msr.hi |= (1 << (50 - 32)); - } + msr.hi |= (0x01 << (53 - 32)); /* Set MIN_VID (31:24) to allow CPU to have full control. */ msr.lo &= ~0xff000000; - msr.lo |= (conf->vr_cpu_min_vid & 0xff) << 24; wrmsr(MSR_VR_MISC_CONFIG, msr); /* Configure VR_MISC_CONFIG2 MSR. */ msr = rdmsr(MSR_VR_MISC_CONFIG2); msr.lo &= ~0xffff; - /* Allow CPU to control minimum voltage completely (15:8) and - * set the fast ramp voltage in 10mV steps. */ - if (cpu_family_model() == BROADWELL_FAMILY_ULT) + /* + * Allow CPU to control minimum voltage completely (15:8) and + * set the fast ramp voltage in 10mV steps. + */ + if (cpu_family_model() == SKYLAKE_FAMILY_ULT) msr.lo |= 0x006a; /* 1.56V */ else msr.lo |= 0x006f; /* 1.60V */ wrmsr(MSR_VR_MISC_CONFIG2, msr); - - /* Set C9/C10 VCC Min */ - pcode_mailbox_write(MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE, 0x1f1f); -} - -static void configure_pch_power_sharing(void) -{ - u32 pch_power, pch_power_ext, pmsync, pmsync2; - int i; - - /* Read PCH Power levels from PCODE */ - pch_power = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER); - pch_power_ext = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT); - - printk(BIOS_INFO, "PCH Power: PCODE Levels 0x%08x 0x%08x\n", - pch_power, pch_power_ext); - - pmsync = RCBA32(PMSYNC_CONFIG); - pmsync2 = RCBA32(PMSYNC_CONFIG2); - - /* Program PMSYNC_TPR_CONFIG PCH power limit values - * pmsync[0:4] = mailbox[0:5] - * pmsync[8:12] = mailbox[6:11] - * pmsync[16:20] = mailbox[12:17] - */ - for (i = 0; i < 3; i++) { - u32 level = pch_power & 0x3f; - pch_power >>= 6; - pmsync &= ~(0x1f << (i * 8)); - pmsync |= (level & 0x1f) << (i * 8); - } - RCBA32(PMSYNC_CONFIG) = pmsync; - - /* Program PMSYNC_TPR_CONFIG2 Extended PCH power limit values - * pmsync2[0:4] = mailbox[23:18] - * pmsync2[8:12] = mailbox_ext[6:11] - * pmsync2[16:20] = mailbox_ext[12:17] - * pmsync2[24:28] = mailbox_ext[18:22] - */ - pmsync2 &= ~0x1f; - pmsync2 |= pch_power & 0x1f; - - for (i = 1; i < 4; i++) { - u32 level = pch_power_ext & 0x3f; - pch_power_ext >>= 6; - pmsync2 &= ~(0x1f << (i * 8)); - pmsync2 |= (level & 0x1f) << (i * 8); - } - RCBA32(PMSYNC_CONFIG2) = pmsync2; } int cpu_config_tdp_levels(void) @@ -371,8 +277,8 @@ void set_power_limits(u8 power_limit_1_time) limit.hi = 0; limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK; limit.hi |= PKG_POWER_LIMIT_EN; - /* Power limit 2 time is only programmable on server SKU */ + /* Power limit 2 time is only programmable on server SKU */ wrmsr(MSR_PKG_POWER_LIMIT, limit); /* Set power limit values in MCHBAR as well */ @@ -393,73 +299,13 @@ void set_power_limits(u8 power_limit_1_time) } } -static void configure_c_states(void) -{ - msr_t msr; - - msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL); - msr.lo |= (1 << 31); // Timed MWAIT Enable - msr.lo |= (1 << 30); // Package c-state Undemotion Enable - msr.lo |= (1 << 29); // Package c-state Demotion Enable - msr.lo |= (1 << 28); // C1 Auto Undemotion Enable - msr.lo |= (1 << 27); // C3 Auto Undemotion Enable - msr.lo |= (1 << 26); // C1 Auto Demotion Enable - msr.lo |= (1 << 25); // C3 Auto Demotion Enable - msr.lo &= ~(1 << 10); // Disable IO MWAIT redirection - /* The deepest package c-state defaults to factory-configured value. */ - wrmsr(MSR_PMG_CST_CONFIG_CONTROL, msr); - - msr = rdmsr(MSR_MISC_PWR_MGMT); - msr.lo &= ~(1 << 0); // Enable P-state HW_ALL coordination - wrmsr(MSR_MISC_PWR_MGMT, msr); - - msr = rdmsr(MSR_POWER_CTL); - msr.lo |= (1 << 18); // Enable Energy Perf Bias MSR 0x1b0 - msr.lo |= (1 << 1); // C1E Enable - msr.lo |= (1 << 0); // Bi-directional PROCHOT# - wrmsr(MSR_POWER_CTL, msr); - - /* C-state Interrupt Response Latency Control 0 - package C3 latency */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_0_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_0, msr); - - /* C-state Interrupt Response Latency Control 1 */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_1_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_1, msr); - - /* C-state Interrupt Response Latency Control 2 - package C6/C7 short */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_2_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_2, msr); - - /* C-state Interrupt Response Latency Control 3 - package C8 */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | - C_STATE_LATENCY_CONTROL_3_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_3, msr); - - /* C-state Interrupt Response Latency Control 4 - package C9 */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | - C_STATE_LATENCY_CONTROL_4_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_4, msr); - - /* C-state Interrupt Response Latency Control 5 - package C10 */ - msr.hi = 0; - msr.lo = IRTL_VALID | IRTL_1024_NS | - C_STATE_LATENCY_CONTROL_5_LIMIT; - wrmsr(MSR_C_STATE_LATENCY_CONTROL_5, msr); -} - static void configure_thermal_target(void) { device_t dev = SA_DEV_ROOT; config_t *conf = dev->chip_info; msr_t msr; - /* Set TCC activation offset if supported */ + /* Set TCC activaiton offset if supported */ msr = rdmsr(MSR_PLATFORM_INFO); if ((msr.lo & (1 << 30)) && conf->tcc_offset) { msr = rdmsr(MSR_TEMPERATURE_TARGET); @@ -474,9 +320,9 @@ static void configure_misc(void) msr_t msr; msr = rdmsr(IA32_MISC_ENABLE); - msr.lo |= (1 << 0); /* Fast String enable */ - msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ - msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */ + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */ wrmsr(IA32_MISC_ENABLE, msr); /* Disable Thermal interrupts */ @@ -567,37 +413,24 @@ static void configure_mca(void) msr = rdmsr(mcg_cap_msr); num_banks = msr.lo & 0xff; msr.lo = msr.hi = 0; - /* TODO(adurbin): This should only be done on a cold boot. Also, some + /* + * TODO(adurbin): This should only be done on a cold boot. Also, some * of these banks are core vs package scope. For now every CPU clears - * every bank. */ + * every bank. + */ for (i = 0; i < num_banks; i++) wrmsr(IA32_MC0_STATUS + (i * 4), msr); } -#if CONFIG_USBDEBUG -static unsigned ehci_debug_addr; -#endif - static void bsp_init_before_ap_bringup(struct bus *cpu_bus) { -#if CONFIG_USBDEBUG - if(!ehci_debug_addr) - ehci_debug_addr = get_ehci_debug(); - set_ehci_debug(0); -#endif - /* Setup MTRRs based on physical address size. */ x86_setup_fixed_mtrrs(); x86_setup_var_mtrrs(cpuid_eax(0x80000008) & 0xff, 2); x86_mtrr_check(); -#if CONFIG_USBDEBUG - set_ehci_debug(ehci_debug_addr); -#endif - initialize_vr_config(); calibrate_24mhz_bclk(); - configure_pch_power_sharing(); } /* All CPUs including BSP will run the following function. */ @@ -610,9 +443,6 @@ static void cpu_core_init(device_t cpu) enable_lapic_tpr(); setup_lapic(); - /* Configure C States */ - configure_c_states(); - /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); @@ -649,31 +479,36 @@ static void relocate_and_load_microcode(void *unused) static void enable_smis(void *unused) { - /* Now that all APs have been relocated as well as the BSP let SMIs - * start flowing. */ + /* + * Now that all APs have been relocated as well as the BSP let SMIs + * start flowing. + */ southbridge_smm_enable_smi(); /* Lock down the SMRAM space. */ +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) smm_lock(); +#endif } static struct mp_flight_record mp_steps[] = { MP_FR_NOBLOCK_APS(relocate_and_load_microcode, NULL, - relocate_and_load_microcode, NULL), + relocate_and_load_microcode, NULL), +#if IS_ENABLED(CONFIG_SMP) MP_FR_BLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL), /* Wait for APs to finish initialization before proceeding. */ +#endif MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL), }; static struct device_operations cpu_dev_ops = { .init = cpu_core_init, + .acpi_fill_ssdt_generator = generate_cpu_entries, }; static struct cpu_device_id cpu_table[] = { - { X86_VENDOR_INTEL, CPUID_HASWELL_ULT }, - { X86_VENDOR_INTEL, CPUID_BROADWELL_C0 }, - { X86_VENDOR_INTEL, CPUID_BROADWELL_D0 }, - { X86_VENDOR_INTEL, CPUID_BROADWELL_E0 }, + { X86_VENDOR_INTEL, CPUID_SKYLAKE_C0 }, + { X86_VENDOR_INTEL, CPUID_SKYLAKE_D0 }, { 0, 0 }, }; @@ -682,7 +517,7 @@ static const struct cpu_driver driver __cpu_driver = { .id_table = cpu_table, }; -void broadwell_init_cpus(device_t dev) +void soc_init_cpus(device_t dev) { struct bus *cpu_bus = dev->link_list; int num_threads; @@ -699,15 +534,20 @@ void broadwell_init_cpus(device_t dev) ht_disabled = num_threads == num_cores; - /* Perform any necessary BSP initialization before APs are brought up. + /* + * Perform any necessary BSP initialization before APs are brought up. * This call also allows the BSP to prepare for any secondary effects - * from calling cpu_initialize() such as smm_init(). */ + * from calling cpu_initialize() such as smm_init(). + */ bsp_init_before_ap_bringup(cpu_bus); microcode_patch = intel_microcode_find(); /* Save default SMM area before relocation occurs. */ - smm_save_area = backup_default_smm_area(); + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) + smm_save_area = backup_default_smm_area(); + else + smm_save_area = NULL; mp_params.num_cpus = num_threads; mp_params.parallel_microcode_load = 1; @@ -719,17 +559,18 @@ void broadwell_init_cpus(device_t dev) mp_params.num_records = ARRAY_SIZE(mp_steps); mp_params.microcode_pointer = microcode_patch; - /* Load relocation and permanent handlers. Then initiate relocation. */ + /* Load relocation and permeanent handlers. Then initiate relocation. */ if (smm_initialize()) - printk(BIOS_CRIT, "SMM initialization failed...\n"); + printk(BIOS_CRIT, "SMM Initialiazation failed...\n"); - if (mp_init(cpu_bus, &mp_params)) { - printk(BIOS_ERR, "MP initialization failure.\n"); - } + if (IS_ENABLED(CONFIG_SMP)) + if (mp_init(cpu_bus, &mp_params)) + printk(BIOS_ERR, "MP initialization failure.\n"); /* Set Max Ratio */ set_max_ratio(); /* Restore the default SMM region. */ - restore_default_smm_area(smm_save_area); + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) + restore_default_smm_area(smm_save_area); } diff --git a/src/soc/intel/skylake/cpu_info.c b/src/soc/intel/skylake/cpu_info.c index 72667ac18f..f3fd0bd0e9 100644 --- a/src/soc/intel/skylake/cpu_info.c +++ b/src/soc/intel/skylake/cpu_info.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <console/console.h> @@ -23,6 +24,7 @@ #include <cpu/x86/msr.h> #include <soc/cpu.h> #include <soc/msr.h> +#include <soc/ramstage.h> #include <soc/systemagent.h> u32 cpu_family_model(void) @@ -42,7 +44,7 @@ int cpu_is_ult(void) if (ult < 0) { u32 fm = cpu_family_model(); - if (fm == BROADWELL_FAMILY_ULT || fm == HASWELL_FAMILY_ULT) + if (fm == SKYLAKE_FAMILY_ULT) ult = 1; else ult = 0; diff --git a/src/soc/intel/skylake/ehci.c b/src/soc/intel/skylake/ehci.c deleted file mode 100644 index 3073a54a2e..0000000000 --- a/src/soc/intel/skylake/ehci.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <delay.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <arch/io.h> -#include <soc/ehci.h> -#include <soc/pch.h> - -static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) -{ - u8 access_cntl; - - access_cntl = pci_read_config8(dev, 0x80); - - /* Enable writes to protected registers. */ - pci_write_config8(dev, 0x80, access_cntl | 1); - - if (!vendor || !device) { - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, - pci_read_config32(dev, PCI_VENDOR_ID)); - } else { - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, - ((device & 0xffff) << 16) | (vendor & 0xffff)); - } - - /* Restore protection. */ - pci_write_config8(dev, 0x80, access_cntl); -} - -static void usb_ehci_set_resources(struct device *dev) -{ -#if CONFIG_USBDEBUG - struct resource *res; - u32 base; - u32 usb_debug; - - usb_debug = get_ehci_debug(); - set_ehci_debug(0); -#endif - pci_dev_set_resources(dev); - -#if CONFIG_USBDEBUG - res = find_resource(dev, 0x10); - set_ehci_debug(usb_debug); - if (!res) return; - base = res->base; - set_ehci_base(base); - report_resource_stored(dev, res, ""); -#endif -} - -static void ehci_enable(struct device *dev) -{ - if (CONFIG_USBDEBUG) - dev->enabled = 1; - else - pch_disable_devfn(dev); -} - -static struct pci_operations ehci_ops_pci = { - .set_subsystem = &usb_ehci_set_subsystem, -}; - -static struct device_operations usb_ehci_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &usb_ehci_set_resources, - .enable_resources = &pci_dev_enable_resources, - .ops_pci = &ehci_ops_pci, - .enable = &ehci_enable, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c26, /* LynxPoint-LP */ - 0x9ca6, /* WildcatPoint */ - 0 -}; - -static const struct pci_driver pch_usb_ehci __pci_driver = { - .ops = &usb_ehci_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/elog.c b/src/soc/intel/skylake/elog.c index 8cbc3e70b6..3ae0890c33 100644 --- a/src/soc/intel/skylake/elog.c +++ b/src/soc/intel/skylake/elog.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <bootstate.h> @@ -22,8 +23,8 @@ #include <console/console.h> #include <stdint.h> #include <elog.h> -#include <soc/lpc.h> #include <soc/pm.h> +#include <soc/pmc.h> static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start) { @@ -75,26 +76,17 @@ static void pch_log_wake_source(struct chipset_power_state *ps) static void pch_log_power_and_resets(struct chipset_power_state *ps) { - /* Thermal Trip Status */ - if (ps->gen_pmcon2 & THERMTRIP_STS) - elog_add_event(ELOG_TYPE_THERM_TRIP); + /* TODO: Thermal Trip Status. There is a thermal device and + * other status registers. */ /* PWR_FLR Power Failure */ - if (ps->gen_pmcon2 & PWROK_FLR) + if (ps->gen_pmcon_b & PWR_FLR) elog_add_event(ELOG_TYPE_POWER_FAIL); /* SUS Well Power Failure */ - if (ps->gen_pmcon3 & SUS_PWR_FLR) + if (ps->gen_pmcon_b & SUS_PWR_FLR) elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); - /* SYS_PWROK Failure */ - if (ps->gen_pmcon2 & SYSPWR_FLR) - elog_add_event(ELOG_TYPE_SYS_PWROK_FAIL); - - /* PWROK Failure */ - if (ps->gen_pmcon2 & PWROK_FLR) - elog_add_event(ELOG_TYPE_PWROK_FAIL); - /* TCO Timeout */ if (ps->prev_sleep_state != 3 && ps->tco2_sts & TCO2_STS_SECOND_TO) @@ -105,15 +97,11 @@ static void pch_log_power_and_resets(struct chipset_power_state *ps) elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); /* RTC reset */ - if (ps->gen_pmcon3 & RTC_BATTERY_DEAD) + if (ps->gen_pmcon_b & RTC_BATTERY_DEAD) elog_add_event(ELOG_TYPE_RTC_RESET); - /* System Reset Status (reset button pushed) */ - if (ps->gen_pmcon2 & SYSTEM_RESET_STS) - elog_add_event(ELOG_TYPE_RESET_BUTTON); - - /* General Reset Status */ - if (ps->gen_pmcon3 & GEN_RST_STS) + /* Host Reset Status */ + if (ps->gen_pmcon_b & HOST_RST_STS) elog_add_event(ELOG_TYPE_SYSTEM_RESET); /* ACPI Wake Event */ @@ -126,8 +114,8 @@ static void pch_log_state(void *unused) struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); if (ps == NULL) { - printk(BIOS_ERR, "Not logging power state information. " - "Power state not found in cbmem.\n"); + printk(BIOS_ERR, + "Not logging power state information. Power state not found in cbmem.\n"); return; } diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index bf5cdcd9bf..bec8676c1d 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> @@ -26,101 +27,66 @@ #include <spi-generic.h> #include <stdlib.h> #include <soc/pci_devs.h> -#include <soc/lpc.h> -#include <soc/me.h> -#include <soc/rcba.h> +#include <soc/pcr.h> +#include <soc/pm.h> +#include <soc/pmc.h> #include <soc/spi.h> #include <soc/systemagent.h> +#include <device/pci.h> -const struct reg_script system_agent_finalize_script[] = { - REG_PCI_OR16(0x50, 1 << 0), /* GGC */ - REG_PCI_OR32(0x5c, 1 << 0), /* DPR */ - REG_PCI_OR32(0x78, 1 << 10), /* ME */ - REG_PCI_OR32(0x90, 1 << 0), /* REMAPBASE */ - REG_PCI_OR32(0x98, 1 << 0), /* REMAPLIMIT */ - REG_PCI_OR32(0xa0, 1 << 0), /* TOM */ - REG_PCI_OR32(0xa8, 1 << 0), /* TOUUD */ - REG_PCI_OR32(0xb0, 1 << 0), /* BDSM */ - REG_PCI_OR32(0xb4, 1 << 0), /* BGSM */ - REG_PCI_OR32(0xb8, 1 << 0), /* TSEGMB */ - REG_PCI_OR32(0xbc, 1 << 0), /* TOLUD */ - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x5500, 1 << 0), /* PAVP */ - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x5f00, 1 << 31), /* SA PM */ - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x6020, 1 << 0), /* UMA GFX */ - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x63fc, 1 << 0), /* VTDTRK */ - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x6800, 1 << 31), - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x7000, 1 << 31), - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x77fc, 1 << 0), - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x50fc, 0x8f), - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x7ffc, 1 << 0), - REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x5880, 1 << 5), - REG_MMIO_WRITE8(MCH_BASE_ADDRESS + 0x50fc, 0x8f), /* MC */ - - REG_SCRIPT_END -}; +static void pch_finalize_script(void) +{ + device_t dev; + uint32_t reg32, hsfs; + void *spibar = get_spi_bar(); + u8 reg8; + u16 tcobase; + u16 tcocnt; + uint8_t *pmcbase; + u32 pmsyncreg; -const struct reg_script pch_finalize_script[] = { /* Set SPI opcode menu */ - REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_PREOP, - SPI_OPPREFIX), - REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_OPTYPE, - SPI_OPTYPE), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + - SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + - SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER), - + write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX); + write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE); + write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER); + write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER); /* Lock SPIBAR */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_HSFS, - SPIBAR_HSFS_FLOCKDN), - - /* TC Lockdown */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x0050, (1 << 31)), + hsfs = read32(spibar + SPIBAR_HSFS); + hsfs |= SPIBAR_HSFS_FLOCKDN; + write32(spibar + SPIBAR_HSFS, hsfs); - /* BIOS Interface Lockdown */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + GCS, (1 << 0)), - - /* Function Disable SUS Well Lockdown */ - REG_MMIO_OR8(RCBA_BASE_ADDRESS + FDSW, (1 << 7)), + /*TCO Lock down*/ + tcobase = pmc_tco_regs(); + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_LOCK; + outw(tcocnt, tcobase + TCO1_CNT); /* Global SMI Lock */ - REG_PCI_OR16(GEN_PMCON_1, SMI_LOCK), + dev = PCH_DEV_PMC; + reg8 = pci_read_config8(dev, GEN_PMCON_A); + reg8 |= SMI_LOCK; + pci_write_config8(dev, GEN_PMCON_A, reg8); - /* GEN_PMCON Lock */ - REG_PCI_OR8(GEN_PMCON_LOCK, SLP_STR_POL_LOCK | ACPI_BASE_LOCK), + /* Lock down ABASE and sleep stretching policy */ + reg32 = pci_read_config32(dev, GEN_PMCON_B); + reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK); + pci_write_config32(dev, GEN_PMCON_B, reg32); /* PMSYNC */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + PMSYNC_CONFIG, (1 << 31)), - - - REG_SCRIPT_END -}; + pmcbase = pmc_mmio_regs(); + pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG); + pmsyncreg |= PMSYNC_LOCK; + write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg); +} -static void broadwell_finalize(void *unused) +static void soc_finalize(void *unused) { printk(BIOS_DEBUG, "Finalizing chipset.\n"); - - reg_script_run_on_dev(SA_DEV_ROOT, system_agent_finalize_script); - reg_script_run_on_dev(PCH_DEV_LPC, pch_finalize_script); - - /* Lock */ - RCBA32_OR(0x3a6c, 0x00000001); - - /* Read+Write the following registers */ - MCHBAR32(0x6030) = MCHBAR32(0x6030); - MCHBAR32(0x6034) = MCHBAR32(0x6034); - MCHBAR32(0x6008) = MCHBAR32(0x6008); - RCBA32(0x21a4) = RCBA32(0x21a4); - - /* Re-init SPI after lockdown */ - spi_init(); - - printk(BIOS_DEBUG, "Finalizing SMM.\n"); - outb(APM_CNT_FINALIZE, APM_CNT); + pch_finalize_script(); /* Indicate finalize step with post code */ post_code(POST_OS_BOOT); } -BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, broadwell_finalize, NULL); -BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, broadwell_finalize, NULL); +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL); diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c new file mode 100644 index 0000000000..d8528b19d9 --- /dev/null +++ b/src/soc/intel/skylake/flash_controller.c @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +/* This file is derived from the flashrom project. */ +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <bootstate.h> +#include <delay.h> +#include <arch/io.h> +#include <console/console.h> +#include <device/pci_ids.h> +#include <spi_flash.h> +#include <spi-generic.h> +#include <soc/pci_devs.h> +#include <soc/spi.h> + +#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ +#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) +#define HSFC_FCYCLE_WR (0x2 << HSFC_FCYCLE_OFF) +#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ +#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) + +#if ENV_SMM +#define pci_read_config_byte(dev, reg, targ)\ + (*(targ) = pci_read_config8(dev, reg)) +#define pci_read_config_word(dev, reg, targ)\ + (*(targ) = pci_read_config16(dev, reg)) +#define pci_read_config_dword(dev, reg, targ)\ + (*(targ) = pci_read_config32(dev, reg)) +#define pci_write_config_byte(dev, reg, val)\ + pci_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pci_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pci_write_config32(dev, reg, val) +#else /* !ENV_SMM */ +#include <device/device.h> +#include <device/pci.h> +#define pci_read_config_byte(dev, reg, targ)\ + (*(targ) = pci_read_config8(dev, reg)) +#define pci_read_config_word(dev, reg, targ)\ + (*(targ) = pci_read_config16(dev, reg)) +#define pci_read_config_dword(dev, reg, targ)\ + (*(targ) = pci_read_config32(dev, reg)) +#define pci_write_config_byte(dev, reg, val)\ + pci_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pci_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pci_write_config32(dev, reg, val) +#endif /* ENV_SMM */ + +#define B_PCH_SPI_BAR0_MASK 0x0FFF + +typedef struct spi_slave pch_spi_slave; +static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi); +static int pch_hwseq_write(struct spi_flash *flash, + u32 addr, size_t len, const void *buf); +static int pch_hwseq_read(struct spi_flash *flash, + u32 addr, size_t len, void *buf); + +typedef struct pch_spi_regs { + uint32_t bfpr; + uint16_t hsfs; + uint16_t hsfc; + uint32_t faddr; + uint32_t _reserved0; + uint32_t fdata[16]; + uint32_t frap; + uint32_t freg[6]; + uint32_t _reserved1[6]; + uint32_t pr[5]; + uint32_t _reserved2[2]; + uint8_t ssfs; + uint8_t ssfc[3]; + uint16_t preop; + uint16_t optype; + uint8_t opmenu[8]; + uint32_t bbar; + uint32_t fdoc; + uint32_t fdod; + uint8_t _reserved4[8]; + uint32_t afc; + uint32_t lvscc; + uint32_t uvscc; + uint8_t _reserved5[4]; + uint32_t fpb; + uint8_t _reserved6[28]; + uint32_t srdl; + uint32_t srdc; + uint32_t srd; +} __attribute__((packed)) pch_spi_regs; + +typedef struct pch_spi_controller { + int locked; + uint32_t flmap0; + uint32_t hsfs; + pch_spi_regs *pch_spi; + uint8_t *opmenu; + int menubytes; + uint16_t *preop; + uint16_t *optype; + uint32_t *addr; + uint8_t *data; + unsigned databytes; + uint8_t *status; + uint16_t *control; + uint32_t *bbar; +} pch_spi_controller; + +static pch_spi_controller cntlr; + +enum { + HSFS_FDONE = 0x0001, + HSFS_FCERR = 0x0002, + HSFS_AEL = 0x0004, + HSFS_BERASE_MASK = 0x0018, + HSFS_BERASE_SHIFT = 3, + HSFS_SCIP = 0x0020, + HSFS_FDOPSS = 0x2000, + HSFS_FDV = 0x4000, + HSFS_FLOCKDN = 0x8000 +}; + +enum { + HSFC_FGO = 0x0001, + HSFC_FCYCLE_MASK = 0x0006, + HSFC_FCYCLE_SHIFT = 1, + HSFC_FDBC_MASK = 0x3f00, + HSFC_FDBC_SHIFT = 8, + HSFC_FSMIE = 0x8000 +}; + +#if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH) + +static u8 readb_(const void *addr) +{ + u8 v = read8(addr); + printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static u16 readw_(const void *addr) +{ + u16 v = read16(addr); + printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static u32 readl_(const void *addr) +{ + u32 v = read32(addr); + printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static void writeb_(u8 b, void *addr) +{ + write8(addr, b); + printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +static void writew_(u16 b, void *addr) +{ + write16(addr, b); + printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +static void writel_(u32 b, void *addr) +{ + write32(addr, b); + printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ + +#define readb_(a) read8(a) +#define readw_(a) read16(a) +#define readl_(a) read32(a) +#define writeb_(val, addr) write8(addr, val) +#define writew_(val, addr) write16(addr, val) +#define writel_(val, addr) write32(addr, val) + +#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ + +static void pch_set_bbar(uint32_t minaddr) +{ + uint32_t pchspi_bbar; + + minaddr &= SPIBAR_MEMBAR_MASK; + pchspi_bbar = readl_(cntlr.bbar) & ~SPIBAR_MEMBAR_MASK; + pchspi_bbar |= minaddr; + writel_(pchspi_bbar, cntlr.bbar); +} + +unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) +{ + return min(cntlr.databytes, buf_len); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +{ + pch_spi_slave *slave = malloc(sizeof(*slave)); + + if (!slave) { + printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); + return NULL; + } + + memset(slave, 0, sizeof(*slave)); + + slave->bus = bus; + slave->cs = cs; + slave->force_programmer_specific = 1; + slave->programmer_specific_probe = spi_flash_hwseq_probe; + + return slave; +} + +static u32 spi_get_flash_size(void) +{ + uint32_t flcomp; + u32 size; + + writel_(SPIBAR_FDOC_COMPONENT, &cntlr.pch_spi->fdoc); + flcomp = readl_(&cntlr.pch_spi->fdod); + printk(BIOS_DEBUG, "flcomp = %x\n", flcomp); + + switch (flcomp & FLCOMP_C0DEN_MASK) { + case FLCOMP_C0DEN_8MB: + size = 0x100000; + break; + case FLCOMP_C0DEN_16MB: + size = 0x1000000; + break; + case FLCOMP_C0DEN_32MB: + size = 0x10000000; + break; + default: + size = 0x1000000; + } + + printk(BIOS_DEBUG, "flash size 0x%x bytes\n", size); + + return size; +} + +int spi_xfer(struct spi_slave *slave, const void *dout, + unsigned int bytesout, void *din, unsigned int bytesin) +{ + /* TODO: Define xfer for hardware sequencing. */ + return -1; +} + +void spi_init(void) +{ + uint8_t bios_cntl; + device_t dev = PCH_DEV_SPI; + pch_spi_regs *pch_spi; + uint16_t hsfs; + + /* Root Complex Register Block */ + pch_spi = (pch_spi_regs *)(get_spi_bar()); + cntlr.pch_spi = pch_spi; + hsfs = readw_(&pch_spi->hsfs); + cntlr.hsfs = hsfs; + cntlr.opmenu = pch_spi->opmenu; + cntlr.menubytes = sizeof(pch_spi->opmenu); + cntlr.optype = &pch_spi->optype; + cntlr.addr = &pch_spi->faddr; + cntlr.data = (uint8_t *)pch_spi->fdata; + cntlr.databytes = sizeof(pch_spi->fdata); + cntlr.status = &pch_spi->ssfs; + cntlr.control = (uint16_t *)pch_spi->ssfc; + cntlr.bbar = &pch_spi->bbar; + cntlr.preop = &pch_spi->preop; + + if (cntlr.hsfs & HSFS_FDV) { + /* Select Flash Descriptor Section Index to 1 */ + writel_(SPIBAR_FDOC_FDSI_1, &pch_spi->fdoc); + cntlr.flmap0 = readl_(&pch_spi->fdod); + } + + pch_set_bbar(0); + + /* Disable the BIOS write protect so write commands are allowed. */ + pci_read_config_byte(dev, SPIBAR_BIOS_CNTL, &bios_cntl); + bios_cntl &= ~SPIBAR_BC_EISS; + bios_cntl |= SPIBAR_BC_WPD; + pci_write_config_byte(dev, SPIBAR_BIOS_CNTL, bios_cntl); +} + +#if ENV_RAMSTAGE + +static void spi_init_cb(void *unused) +{ + spi_init(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); + +#endif /* ENV_RAMSTAGE */ + +int spi_claim_bus(struct spi_slave *slave) +{ + /* Handled by PCH automatically. */ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + /* Handled by PCH automatically. */ +} + +static void pch_hwseq_set_addr(uint32_t addr) +{ + uint32_t addr_old = readl_(&cntlr.pch_spi->faddr) & ~SPIBAR_FADDR_MASK; + writel_((addr & SPIBAR_FADDR_MASK) | addr_old, &cntlr.pch_spi->faddr); +} + +/* + * Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. + * Resets all error flags in HSFS. + * Returns 0 if the cycle completes successfully without errors within + * timeout us, 1 on errors. + */ +static int pch_hwseq_wait_for_cycle_complete(unsigned int timeout, + unsigned int len) +{ + uint16_t hsfs; + uint32_t addr; + + timeout /= 8; /* scale timeout duration to counter */ + while ((((hsfs = readw_(&cntlr.pch_spi->hsfs)) & + (HSFS_FDONE | HSFS_FCERR)) == 0) && --timeout) { + udelay(8); + } + writew_(readw_(&cntlr.pch_spi->hsfs), &cntlr.pch_spi->hsfs); + + if (!timeout) { + uint16_t hsfc; + addr = readl_(&cntlr.pch_spi->faddr) & SPIBAR_FADDR_MASK; + hsfc = readw_(&cntlr.pch_spi->hsfc); + printk(BIOS_ERR, "Transaction timeout between offset 0x%08x \ + and 0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs); + return 1; + } + + if (hsfs & HSFS_FCERR) { + uint16_t hsfc; + addr = readl_(&cntlr.pch_spi->faddr) & SPIBAR_FADDR_MASK; + hsfc = readw_(&cntlr.pch_spi->hsfc); + printk(BIOS_ERR, "Transaction error between offset 0x%08x and \ + 0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs); + return 1; + } + return 0; +} + + +static int pch_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) +{ + u32 start, end, erase_size; + int ret; + uint16_t hsfc; + uint16_t timeout = 1000 * 60; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); + return -1; + } + + flash->spi->rw = SPI_WRITE_FLAG; + ret = spi_claim_bus(flash->spi); + if (ret) { + printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); + return ret; + } + + start = offset; + end = start + len; + + while (offset < end) { + /* + * Make sure FDONE, FCERR, AEL are + * cleared by writing 1 to them. + */ + writew_(readw_(&cntlr.pch_spi->hsfs), &cntlr.pch_spi->hsfs); + + pch_hwseq_set_addr(offset); + + offset += erase_size; + + hsfc = readw_(&cntlr.pch_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= HSFC_FCYCLE; /* set erase operation */ + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.pch_spi->hsfc); + if (pch_hwseq_wait_for_cycle_complete(timeout, len)) { + printk(BIOS_ERR, "SF: Erase failed at %x\n", + offset - erase_size); + ret = -1; + goto out; + } + } + + printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", + len, start); + +out: + spi_release_bus(flash->spi); + return ret; +} + +static void pch_read_data(uint8_t *data, int len) +{ + int i; + uint32_t temp32 = 0; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = readl_(cntlr.data + i); + + data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; + } +} + +static int pch_hwseq_read(struct spi_flash *flash, + u32 addr, size_t len, void *buf) +{ + uint16_t hsfc; + uint16_t timeout = 100 * 60; + uint8_t block_len; + + if (addr + len > spi_get_flash_size()) { + printk(BIOS_ERR, + "Attempt to read %x-%x which is out of chip\n", + (unsigned) addr, + (unsigned) addr+(unsigned) len); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.pch_spi->hsfs), &cntlr.pch_spi->hsfs); + + while (len > 0) { + block_len = min(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + pch_hwseq_set_addr(addr); + hsfc = readw_(&cntlr.pch_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* set read operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.pch_spi->hsfc); + + if (pch_hwseq_wait_for_cycle_complete(timeout, block_len)) + return 1; + pch_read_data(buf, block_len); + addr += block_len; + buf += block_len; + len -= block_len; + } + return 0; +} + +/* Fill len bytes from the data array into the fdata/spid registers. + * + * Note that using len > flash->pgm->spi.max_data_write will trash the registers + * following the data registers. + */ +static void pch_fill_data(const uint8_t *data, int len) +{ + uint32_t temp32 = 0; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = 0; + + temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8); + + if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); + } + i--; + if ((i % 4) != 3) /* Write remaining data to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); +} + +static int pch_hwseq_write(struct spi_flash *flash, + u32 addr, size_t len, const void *buf) +{ + uint16_t hsfc; + uint16_t timeout = 100 * 60; + uint8_t block_len; + uint32_t start = addr; + + if (addr + len > spi_get_flash_size()) { + printk(BIOS_ERR, + "Attempt to write 0x%x-0x%x which is out of chip\n", + (unsigned)addr, (unsigned) (addr+len)); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.pch_spi->hsfs), &cntlr.pch_spi->hsfs); + + while (len > 0) { + block_len = min(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + + pch_hwseq_set_addr(addr); + + pch_fill_data(buf, block_len); + hsfc = readw_(&cntlr.pch_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= HSFC_FCYCLE_WR; /* set write operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.pch_spi->hsfc); + + if (pch_hwseq_wait_for_cycle_complete(timeout, block_len)) { + printk(BIOS_ERR, "SF: write failure at %x\n", addr); + return -1; + } + addr += block_len; + buf += block_len; + len -= block_len; + } + printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", + (unsigned) (addr - start), start); + return 0; +} + + +static struct spi_flash *spi_flash_hwseq_probe(struct spi_slave *spi) +{ + struct spi_flash *flash = NULL; + u32 berase; + + flash = malloc(sizeof(*flash)); + if (!flash) { + printk(BIOS_WARNING, "SF: Failed to allocate memory\n"); + return NULL; + } + + flash->spi = spi; + flash->name = "Opaque HW-sequencing"; + + flash->write = pch_hwseq_write; + flash->erase = pch_hwseq_erase; + flash->read = pch_hwseq_read; + pch_hwseq_set_addr(0); + + berase = (cntlr.hsfs >> SPIBAR_HSFS_BERASE_OFFSET) & + SPIBAR_HSFS_BERASE_MASK; + + switch (berase) { + case 0: + flash->sector_size = 256; + break; + case 1: + flash->sector_size = 4096; + break; + case 2: + flash->sector_size = 8192; + break; + case 3: + flash->sector_size = 65536; + break; + } + + flash->size = spi_get_flash_size(); + + return flash; +} diff --git a/src/soc/intel/skylake/gpio.c b/src/soc/intel/skylake/gpio.c index dc7d71371c..9f7b409e5c 100644 --- a/src/soc/intel/skylake/gpio.c +++ b/src/soc/intel/skylake/gpio.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -11,10 +12,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdint.h> @@ -22,178 +19,305 @@ #include <arch/io.h> #include <device/device.h> #include <device/pci.h> -#include <soc/gpio.h> +#include <gpio.h> +#include <soc/pcr.h> #include <soc/iomap.h> #include <soc/pm.h> +/* Keep the ordering intact GPP_A ~ G, GPD. + * As the gpio/smi functions get_smi_status() and + * enable_gpio_groupsmi() depends on this ordering. + */ +static const GPIO_GROUP_INFO gpio_group_info[] = { + /* GPP_A */ + { + .community = PID_GPIOCOM0, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_A_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_A_PAD_MAX, + .smistsoffset = R_PCH_PCR_GPIO_GPP_A_SMI_STS, + .smienoffset = R_PCH_PCR_GPIO_GPP_A_SMI_EN, + }, + /* GPP_B */ + { + .community = PID_GPIOCOM0, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_B_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_B_PAD_MAX, + .smistsoffset = R_PCH_PCR_GPIO_GPP_B_SMI_STS, + .smienoffset = R_PCH_PCR_GPIO_GPP_B_SMI_EN, + }, + /* GPP_C */ + { + .community = PID_GPIOCOM1, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_C_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_C_PAD_MAX, + .smistsoffset = R_PCH_PCR_GPIO_GPP_C_SMI_STS, + .smienoffset = R_PCH_PCR_GPIO_GPP_C_SMI_EN, + }, + /* GPP_D */ + { + .community = PID_GPIOCOM1, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_D_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_D_PAD_MAX, + .smistsoffset = R_PCH_PCR_GPIO_GPP_D_SMI_STS, + .smienoffset = R_PCH_PCR_GPIO_GPP_D_SMI_EN, + }, + /* GPP_E */ + { + .community = PID_GPIOCOM1, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_E_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_E_PAD_MAX, + .smistsoffset = R_PCH_PCR_GPIO_GPP_E_SMI_STS, + .smienoffset = R_PCH_PCR_GPIO_GPP_E_SMI_EN, + }, + /* GPP_F */ + { + .community = PID_GPIOCOM3, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_F_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_F_PAD_MAX, + .smistsoffset = NO_REGISTER_PROPERTY, + .smienoffset = NO_REGISTER_PROPERTY, + }, + /* GPP_G */ + { + .community = PID_GPIOCOM3, + .padcfgoffset = R_PCH_PCR_GPIO_GPP_G_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPP_G_PAD_MAX, + .smistsoffset = NO_REGISTER_PROPERTY, + .smienoffset = NO_REGISTER_PROPERTY, + }, + /* GPP_H */ + { + .community = PID_GPIOCOM2, + .padcfgoffset = R_PCH_PCR_GPIO_GPD_PADCFG_OFFSET, + .padpergroup = V_PCH_GPIO_GPD_PAD_MAX, + .smistsoffset = NO_REGISTER_PROPERTY, + .smienoffset = NO_REGISTER_PROPERTY, + }, +}; + /* - * This function will return a number that indicates which PIRQ - * this GPIO maps to. If this is not a PIRQ capable GPIO then - * it will return -1. The GPIO to PIRQ mapping is not linear. + * SPT has 7 GPIO communities named as GPP_A to GPP_G. + * Each community has 24 GPIO PIN. + * Below formula to calculate GPIO Pin from GPIO PAD. + * PIN# = GROUP_PAD# + GROUP# * 24 + * ==================================== + * Community || Group# + * ==================================== + * GPP_A || 0 + * GPP_B || 1 + * GPP_C || 2 + * GPP_D || 3 + * GPP_E || 4 + * GPP_F || 5 + * GPP_G || 6 */ -static int gpio_to_pirq(int gpio) +static u32 get_padnumber_from_gpiopad(GPIO_PAD gpiopad) { - switch (gpio) { - case 8: return 0; /* PIRQI */ - case 9: return 1; /* PIRQJ */ - case 10: return 2; /* PIRQK */ - case 13: return 3; /* PIRQL */ - case 14: return 4; /* PIRQM */ - case 45: return 5; /* PIRQN */ - case 46: return 6; /* PIRQO */ - case 47: return 7; /* PIRQP */ - case 48: return 8; /* PIRQQ */ - case 49: return 9; /* PIRQR */ - case 50: return 10; /* PIRQS */ - case 51: return 11; /* PIRQT */ - case 52: return 12; /* PIRQU */ - case 53: return 13; /* PIRQV */ - case 54: return 14; /* PIRQW */ - case 55: return 15; /* PIRQX */ - default: return -1; - }; + return (u32) GPIO_GET_PAD_NUMBER(gpiopad); } -void init_one_gpio(int gpio_num, struct gpio_config *config) +static u32 get_groupindex_from_gpiopad(GPIO_PAD gpiopad) { - u32 owner, route, irqen, reset; - int set, bit; + return (u32) GPIO_GET_GROUP_INDEX_FROM_PAD(gpiopad); +} - if (gpio_num > MAX_GPIO_NUMBER || !config) - return; +static int read_write_gpio_pad_reg(u32 gpiopad, u8 dwreg, u32 mask, int write, + u32 *readwriteval) +{ + u32 padcfgreg; + u32 gpiogroupinfolength; + u32 groupindex; + u32 padnumber; - outl(config->conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); - outl(config->conf1, GPIO_BASE_ADDRESS + GPIO_CONFIG1(gpio_num)); - - /* Determine set and bit based on GPIO number */ - set = gpio_num >> 5; - bit = gpio_num % 32; - - /* Save settings from current GPIO config */ - owner = inl(GPIO_BASE_ADDRESS + GPIO_OWNER(set)); - route = inl(GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); - irqen = inl(GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); - reset = inl(GPIO_BASE_ADDRESS + GPIO_RESET(set)); - - owner |= config->owner << bit; - route |= config->route << bit; - irqen |= config->irqen << bit; - reset |= config->reset << bit; - - outl(owner, GPIO_BASE_ADDRESS + GPIO_OWNER(set)); - outl(route, GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); - outl(irqen, GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); - outl(reset, GPIO_BASE_ADDRESS + GPIO_RESET(set)); - - if (set == 0) { - u32 blink = inl(GPIO_BASE_ADDRESS + GPIO_BLINK); - blink |= config->blink << bit; - outl(blink, GPIO_BASE_ADDRESS + GPIO_BLINK); - } + groupindex = get_groupindex_from_gpiopad(gpiopad); + padnumber = get_padnumber_from_gpiopad(gpiopad); + + gpiogroupinfolength = sizeof(gpio_group_info) / sizeof(GPIO_GROUP_INFO); - /* PIRQ to IO-APIC map */ - if (config->pirq == GPIO_PIRQ_APIC_ROUTE) { - u32 pirq2apic = inl(GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); - set = gpio_to_pirq(gpio_num); - if (set >= 0) { - pirq2apic |= 1 << set; - outl(pirq2apic, GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); - } + /* Check if group argument exceeds GPIO GROUP INFO array */ + if ((u32) groupindex >= gpiogroupinfolength) + return -1; + /* Check if legal pin number */ + if (padnumber >= gpio_group_info[groupindex].padpergroup) + return -1; + /* Create Pad Configuration register offset */ + padcfgreg = 0x8 * padnumber + gpio_group_info[groupindex].padcfgoffset; + if (dwreg == 1) + padcfgreg += 0x4; + if (write) { + pcr_andthenor32(gpio_group_info[groupindex].community, + padcfgreg, (u32) (~mask), + (u32) (*readwriteval & mask)); + } else { + pcr_read32(gpio_group_info[groupindex].community, padcfgreg, + readwriteval); + *readwriteval &= mask; } + + return 0; } -void init_gpios(const struct gpio_config config[]) +static int convert_gpio_num_to_pad(gpio_t gpionum) { - const struct gpio_config *entry; - u32 owner[3] = {0}; - u32 route[3] = {0}; - u32 irqen[3] = {0}; - u32 reset[3] = {0}; - u32 blink = 0; - u16 pirq2apic = 0; - int set, bit, gpio = 0; - - for (entry = config; entry->conf0 != GPIO_LIST_END; entry++, gpio++) { - if (gpio > MAX_GPIO_NUMBER) - break; - - /* Setup Configuration registers 1 and 2 */ - outl(entry->conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio)); - outl(entry->conf1, GPIO_BASE_ADDRESS + GPIO_CONFIG1(gpio)); - - /* Determine set and bit based on GPIO number */ - set = gpio >> 5; - bit = gpio % 32; - - /* Apply settings to set specific bits */ - owner[set] |= entry->owner << bit; - route[set] |= entry->route << bit; - irqen[set] |= entry->irqen << bit; - reset[set] |= entry->reset << bit; - - if (set == 0) - blink |= entry->blink << bit; - - /* PIRQ to IO-APIC map */ - if (entry->pirq == GPIO_PIRQ_APIC_ROUTE) { - set = gpio_to_pirq(gpio); - if (set >= 0) - pirq2apic |= 1 << set; - } - } + int group_pad_num = 0; + int gpio_group = 0; + u32 gpio_pad = 0; + + group_pad_num = (gpionum % MAX_GPIO_PIN_PER_GROUP); + gpio_group = (gpionum / MAX_GPIO_PIN_PER_GROUP); + + switch (gpio_group) { + case GPIO_LP_GROUP_A: + gpio_pad = GPIO_LP_GROUP_GPP_A; + break; - for (set = 0; set <= 2; set++) { - outl(owner[set], GPIO_BASE_ADDRESS + GPIO_OWNER(set)); - outl(route[set], GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); - outl(irqen[set], GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); - outl(reset[set], GPIO_BASE_ADDRESS + GPIO_RESET(set)); + case GPIO_LP_GROUP_B: + gpio_pad = GPIO_LP_GROUP_GPP_B; + break; + + case GPIO_LP_GROUP_C: + gpio_pad = GPIO_LP_GROUP_GPP_C; + break; + + case GPIO_LP_GROUP_D: + gpio_pad = GPIO_LP_GROUP_GPP_D; + break; + + case GPIO_LP_GROUP_E: + gpio_pad = GPIO_LP_GROUP_GPP_E; + break; + + case GPIO_LP_GROUP_F: + gpio_pad = GPIO_LP_GROUP_GPP_F; + break; + + case GPIO_LP_GROUP_G: + gpio_pad = GPIO_LP_GROUP_GPP_G; + break; + default: + return -1; + break; } + gpio_pad = (gpio_pad << GPIO_GROUP_SHIFT) + group_pad_num; - outl(blink, GPIO_BASE_ADDRESS + GPIO_BLINK); - outl(pirq2apic, GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); + return gpio_pad; } -int get_gpio(int gpio_num) +int gpio_get(gpio_t gpio_num) { + u32 gpiopad = 0; + u32 outputvalue = 0; + int status = 0; + if (gpio_num > MAX_GPIO_NUMBER) return 0; - return !!(inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)) & GPI_LEVEL); + gpiopad = convert_gpio_num_to_pad(gpio_num); + if (gpiopad < 0) + return -1; + + status = read_write_gpio_pad_reg(gpiopad, + 0, + B_PCH_GPIO_TX_STATE, + READ, &outputvalue); + outputvalue >>= N_PCH_GPIO_TX_STATE; + return outputvalue; } -/* - * get a number comprised of multiple GPIO values. gpio_num_array points to - * the array of gpio pin numbers to scan, terminated by -1. - */ -unsigned get_gpios(const int *gpio_num_array) +void gpio_set(gpio_t gpio_num, int value) { - int gpio; - unsigned bitmask = 1; - unsigned vector = 0; - - while (bitmask && - ((gpio = *gpio_num_array++) != -1)) { - if (get_gpio(gpio)) - vector |= bitmask; - bitmask <<= 1; + int status = 0; + u32 gpiopad = 0; + u32 outputvalue = 0; + + if (gpio_num > MAX_GPIO_NUMBER) + return; + + gpiopad = convert_gpio_num_to_pad(gpio_num); + if (gpiopad < 0) + return; + + outputvalue = value; + + status = read_write_gpio_pad_reg(gpiopad, + 0, + B_PCH_GPIO_TX_STATE, + WRITE, &outputvalue); +} + +void clear_all_smi(void) +{ + u32 gpiogroupinfolength; + u32 gpioindex = 0; + + gpiogroupinfolength = sizeof(gpio_group_info) / sizeof(GPIO_GROUP_INFO); + + for (gpioindex = 0; gpioindex < gpiogroupinfolength; gpioindex++) { + /*Check if group has GPI SMI register */ + if (gpio_group_info[gpioindex].smistsoffset == + NO_REGISTER_PROPERTY) + continue; + /* Clear all GPI SMI Status bits by writing '1' */ + pcr_write32(gpio_group_info[gpioindex].community, + gpio_group_info[gpioindex].smistsoffset, + 0xFFFFFFFF); } - return vector; } -void set_gpio(int gpio_num, int value) +void get_smi_status(u32 status[GPIO_COMMUNITY_MAX]) { - u32 conf0; + u32 num_of_communities; + u32 gpioindex; + u32 outputvalue = 0; - if (gpio_num > MAX_GPIO_NUMBER) - return; + num_of_communities = ARRAY_SIZE(gpio_group_info); - conf0 = inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); - conf0 &= ~GPO_LEVEL_MASK; - conf0 |= value << GPO_LEVEL_SHIFT; - outl(conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); + for (gpioindex = 0; gpioindex < num_of_communities; gpioindex++) { + /*Check if group has GPI SMI register */ + if (gpio_group_info[gpioindex].smistsoffset == + NO_REGISTER_PROPERTY) + continue; + /* Read SMI status register */ + pcr_read32(gpio_group_info[gpioindex].community, + gpio_group_info[gpioindex].smistsoffset, + &outputvalue); + status[gpioindex] = outputvalue; + } } -int gpio_is_native(int gpio_num) +void enable_all_smi(void) { - return !(inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)) & 1); + u32 gpiogroupinfolength; + u32 gpioindex = 0; + + gpiogroupinfolength = sizeof(gpio_group_info) / sizeof(GPIO_GROUP_INFO); + + for (gpioindex = 0; gpioindex < gpiogroupinfolength; gpioindex++) { + /*Check if group has GPI SMI register */ + if (gpio_group_info[gpioindex].smienoffset == + NO_REGISTER_PROPERTY) + continue; + /* Set all GPI SMI Enable bits by writing '1' */ + pcr_write32(gpio_group_info[gpioindex].community, + gpio_group_info[gpioindex].smienoffset, + 0xFFFFFFFF); + } +} + +void enable_gpio_groupsmi(gpio_t gpio_num, u32 mask) +{ + u32 gpioindex = 0; + u32 smien = 0; + + if (gpio_num > MAX_GPIO_NUMBER) + return; + + gpioindex = (gpio_num / MAX_GPIO_PIN_PER_GROUP); + + pcr_read32(gpio_group_info[gpioindex].community, + gpio_group_info[gpioindex].smienoffset, &smien); + smien |= mask; + /* Set all GPI SMI Enable bits by writing '1' */ + pcr_write32(gpio_group_info[gpioindex].community, + gpio_group_info[gpioindex].smienoffset, smien); } diff --git a/src/soc/intel/skylake/hda.c b/src/soc/intel/skylake/hda.c deleted file mode 100644 index b2992e85b2..0000000000 --- a/src/soc/intel/skylake/hda.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Advanced Micro Devices, Inc. - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> -#include <arch/io.h> -#include <delay.h> -#include <soc/intel/common/hda_verb.h> -#include <soc/pch.h> -#include <soc/ramstage.h> -#include <soc/rcba.h> - -const u32 * cim_verb_data = NULL; -u32 cim_verb_data_size = 0; -const u32 * pc_beep_verbs = NULL; -u32 pc_beep_verbs_size = 0; - -static void codecs_init(u8 *base, u32 codec_mask) -{ - int i; - - /* Can support up to 4 codecs */ - for (i = 3; i >= 0; i--) { - if (codec_mask & (1 << i)) - hda_codec_init(base, i, - cim_verb_data_size, - cim_verb_data); - } - - if (pc_beep_verbs_size && pc_beep_verbs) - hda_codec_write(base, pc_beep_verbs_size, pc_beep_verbs); -} - -static void hda_pch_init(struct device *dev, u8 *base) -{ - u8 reg8; - u16 reg16; - u32 reg32; - - if (RCBA32(0x2030) & (1 << 31)) { - reg32 = pci_read_config32(dev, 0x120); - reg32 &= 0xf8ffff01; - reg32 |= (1 << 25); - reg32 |= RCBA32(0x2030) & 0xfe; - pci_write_config32(dev, 0x120, reg32); - } else - printk(BIOS_DEBUG, "HDA: V1CTL disabled.\n"); - - reg32 = pci_read_config32(dev, 0x114); - reg32 &= ~0xfe; - pci_write_config32(dev, 0x114, reg32); - - // Set VCi enable bit - if (pci_read_config32(dev, 0x120) & ((1 << 24) | - (1 << 25) | (1 << 26))) { - reg32 = pci_read_config32(dev, 0x120); - reg32 &= ~(1 << 31); - pci_write_config32(dev, 0x120, reg32); - } - - /* Additional programming steps */ - reg32 = pci_read_config32(dev, 0xc4); - reg32 |= (1 << 24); - pci_write_config32(dev, 0xc4, reg32); - - reg8 = pci_read_config8(dev, 0x40); // Audio Control - reg8 |= 1; // Select HDA mode - pci_write_config8(dev, 0x40, reg8); - - reg8 = pci_read_config8(dev, 0x4d); // Docking Status - reg8 &= ~(1 << 7); // Docking not supported - pci_write_config8(dev, 0x4d, reg8); - - reg16 = read32(base + 0x0012); - reg16 |= (1 << 0); - write32(base + 0x0012, reg16); - - /* disable Auto Voltage Detector */ - reg8 = pci_read_config8(dev, 0x42); - reg8 |= (1 << 2); - pci_write_config8(dev, 0x42, reg8); -} - -static void hda_init(struct device *dev) -{ - u8 *base; - struct resource *res; - u32 codec_mask; - u32 reg32; - - /* Find base address */ - res = find_resource(dev, PCI_BASE_ADDRESS_0); - if (!res) - return; - - base = res2mmio(res, 0, 0); - printk(BIOS_DEBUG, "HDA: base = %p\n", base); - - /* Set Bus Master */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); - - hda_pch_init(dev, base); - - codec_mask = hda_codec_detect(base); - - if (codec_mask) { - printk(BIOS_DEBUG, "HDA: codec_mask = %02x\n", codec_mask); - codecs_init(base, codec_mask); - } -} - -static void hda_enable(struct device *dev) -{ - u32 reg32; - u8 reg8; - - reg8 = pci_read_config8(dev, 0x43); - reg8 |= 0x6f; - pci_write_config8(dev, 0x43, reg8); - - if (!dev->enabled) { - /* Route I/O buffers to ADSP function */ - reg8 = pci_read_config8(dev, 0x42); - reg8 |= (1 << 7) | (1 << 6); - pci_write_config8(dev, 0x42, reg8); - - printk(BIOS_INFO, "HDA disabled, I/O buffers routed to ADSP\n"); - - /* Ensure memory, io, and bus master are all disabled */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~(PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | PCI_COMMAND_IO); - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Disable this device */ - pch_disable_devfn(dev); - } -} - -static struct device_operations hda_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .init = &hda_init, - .enable = &hda_enable, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c20, /* LynxPoint-LP */ - 0x9ca0, /* WildcatPoint */ - 0 -}; - -static const struct pci_driver pch_hda __pci_driver = { - .ops = &hda_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/igd.c b/src/soc/intel/skylake/igd.c index 86da0a9cb2..25d89c3e89 100644 --- a/src/soc/intel/skylake/igd.c +++ b/src/soc/intel/skylake/igd.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,12 +15,12 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/acpi.h> #include <arch/io.h> -#include <bootmode.h> +#include <chip.h> #include <console/console.h> #include <delay.h> #include <device/device.h> @@ -33,214 +34,13 @@ #include <soc/pm.h> #include <soc/ramstage.h> #include <soc/systemagent.h> -#include <soc/intel/broadwell/chip.h> #include <vendorcode/google/chromeos/chromeos.h> -#define GT_RETRY 1000 +#define GT_RETRY 1000 #define GT_CDCLK_337 0 #define GT_CDCLK_450 1 #define GT_CDCLK_540 2 #define GT_CDCLK_675 3 - -struct reg_script haswell_early_init_script[] = { - /* Enable Force Wake */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa180, 0x00000020), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa188, 0x00010001), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, FORCEWAKE_ACK_HSW, 1, 1, GT_RETRY), - - /* Enable Counters */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa248, 0x00000016), - - /* GFXPAUSE settings */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa000, 0x00070020), - - /* ECO Settings */ - REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0xa180, 0xff3fffff, 0x15000000), - - /* Enable DOP Clock Gating */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9424, 0x000003fd), - - /* Enable Unit Level Clock Gating */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9400, 0x00000080), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9404, 0x40401000), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9408, 0x00000000), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x940c, 0x02000001), - - /* - * RC6 Settings - */ - - /* Wake Rate Limits */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa090, 0x00000000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa098, 0x03e80000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa09c, 0x00280000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa0a8, 0x0001e848), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa0ac, 0x00000019), - - /* Render/Video/Blitter Idle Max Count */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x02054, 0x0000000a), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x12054, 0x0000000a), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x22054, 0x0000000a), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1a054, 0x0000000a), - - /* RC Sleep / RCx Thresholds */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa0b0, 0x00000000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa0b4, 0x000003e8), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa0b8, 0x0000c350), - - /* RP Settings */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa010, 0x000f4240), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa014, 0x12060000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa02c, 0x0000e808), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa030, 0x0003bd08), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa068, 0x000101d0), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa06c, 0x00055730), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa070, 0x0000000a), - - /* RP Control */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa024, 0x00000b92), - - /* HW RC6 Control */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa090, 0x88040000), - - /* Video Frequency Request */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa00c, 0x08000000), - - /* Set RC6 VIDs */ - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x138124, (1 << 31), 0, GT_RETRY), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x138128, 0), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x138124, 0x80000004), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x138124, (1 << 31), 0, GT_RETRY), - - /* Enable PM Interrupts */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x4402c, 0x03000076), - - /* Enable RC6 in idle */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa094, 0x00040000), - - REG_SCRIPT_END -}; - -static const struct reg_script haswell_late_init_script[] = { - /* Lock settings */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a248, (1 << 31)), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a004, (1 << 4)), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a080, (1 << 2)), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a180, (1 << 31)), - - /* Disable Force Wake */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa188, 0x00010000), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, FORCEWAKE_ACK_HSW, 1, 0, GT_RETRY), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa188, 0x00000001), - - /* Enable power well for DP and Audio */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x45400, (1 << 31)), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x45400, - (1 << 30), (1 << 30), GT_RETRY), - - REG_SCRIPT_END -}; - -static const struct reg_script broadwell_early_init_script[] = { - /* Enable Force Wake */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa188, 0x00010001), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, FORCEWAKE_ACK_HSW, 1, 1, GT_RETRY), - - /* Enable push bus metric control and shift */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa248, 0x00000004), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa250, 0x000000ff), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa25c, 0x00000010), - - /* GFXPAUSE settings (set based on stepping) */ - - /* ECO Settings */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa180, 0x45200000), - - /* Enable DOP Clock Gating */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9424, 0x000000fd), - - /* Enable Unit Level Clock Gating */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9400, 0x00000000), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9404, 0x40401000), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9408, 0x00000000), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x940c, 0x02000001), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1a054, 0x0000000a), - - /* Video Frequency Request */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa00c, 0x08000000), - - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x138158, 0x00000009), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x13815c, 0x0000000d), - - /* - * RC6 Settings - */ - - /* Wake Rate Limits */ - REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x0a090, 0, 0), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a098, 0x03e80000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a09c, 0x00280000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a0a8, 0x0001e848), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a0ac, 0x00000019), - - /* Render/Video/Blitter Idle Max Count */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x02054, 0x0000000a), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x12054, 0x0000000a), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x22054, 0x0000000a), - - /* RC Sleep / RCx Thresholds */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a0b0, 0x00000000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a0b8, 0x00000271), - - /* RP Settings */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a010, 0x000f4240), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a014, 0x12060000), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a02c, 0x0000e808), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a030, 0x0003bd08), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a068, 0x000101d0), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a06c, 0x00055730), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a070, 0x0000000a), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a168, 0x00000006), - - /* RP Control */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa024, 0x00000b92), - - /* HW RC6 Control */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa090, 0x90040000), - - /* Set RC6 VIDs */ - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x138124, (1 << 31), 0, GT_RETRY), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x138128, 0), - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x138124, 0x80000004), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x138124, (1 << 31), 0, GT_RETRY), - - /* Enable PM Interrupts */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x4402c, 0x03000076), - - /* Enable RC6 in idle */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa094, 0x00040000), - - REG_SCRIPT_END -}; - -static const struct reg_script broadwell_late_init_script[] = { - /* Lock settings */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a248, (1 << 31)), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a000, (1 << 18)), - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x0a180, (1 << 31)), - - /* Disable Force Wake */ - REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa188, 0x00010000), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, FORCEWAKE_ACK_HSW, 1, 0, GT_RETRY), - - /* Enable power well for DP and Audio */ - REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x45400, (1 << 31)), - REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x45400, - (1 << 30), (1 << 30), GT_RETRY), - - REG_SCRIPT_END -}; - u32 map_oprom_vendev(u32 vendev) { return SA_IGD_OPROM_VENDEV; @@ -251,14 +51,13 @@ static struct resource *gtt_res = NULL; static unsigned long gtt_read(unsigned long reg) { u32 val; - val = read32(res2mmio(gtt_res, reg, 0)); + val = read32((void *)(unsigned int)(gtt_res->base + reg)); return val; - } static void gtt_write(unsigned long reg, unsigned long data) { - write32(res2mmio(gtt_res, reg, 0), data); + write32((void *)(unsigned int)(gtt_res->base + reg), data); } static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask) @@ -269,216 +68,8 @@ static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask) gtt_write(reg, val); } -static int gtt_poll(u32 reg, u32 mask, u32 value) -{ - unsigned try = GT_RETRY; - u32 data; - - while (try--) { - data = gtt_read(reg); - if ((data & mask) == value) - return 1; - udelay(10); - } - - printk(BIOS_ERR, "GT init timeout\n"); - return 0; -} - -static void igd_setup_panel(struct device *dev) -{ - config_t *conf = dev->chip_info; - u32 reg32; - - /* Setup Digital Port Hotplug */ - reg32 = gtt_read(PCH_PORT_HOTPLUG); - if (!reg32) { - reg32 = (conf->gpu_dp_b_hotplug & 0x7) << 2; - reg32 |= (conf->gpu_dp_c_hotplug & 0x7) << 10; - reg32 |= (conf->gpu_dp_d_hotplug & 0x7) << 18; - gtt_write(PCH_PORT_HOTPLUG, reg32); - } - - /* Setup Panel Power On Delays */ - reg32 = gtt_read(PCH_PP_ON_DELAYS); - if (!reg32) { - reg32 = (conf->gpu_panel_port_select & 0x3) << 30; - reg32 |= (conf->gpu_panel_power_up_delay & 0x1fff) << 16; - reg32 |= (conf->gpu_panel_power_backlight_on_delay & 0x1fff); - gtt_write(PCH_PP_ON_DELAYS, reg32); - } - - /* Setup Panel Power Off Delays */ - reg32 = gtt_read(PCH_PP_OFF_DELAYS); - if (!reg32) { - reg32 = (conf->gpu_panel_power_down_delay & 0x1fff) << 16; - reg32 |= (conf->gpu_panel_power_backlight_off_delay & 0x1fff); - gtt_write(PCH_PP_OFF_DELAYS, reg32); - } - - /* Setup Panel Power Cycle Delay */ - if (conf->gpu_panel_power_cycle_delay) { - reg32 = gtt_read(PCH_PP_DIVISOR); - reg32 &= ~0xff; - reg32 |= conf->gpu_panel_power_cycle_delay & 0xff; - gtt_write(PCH_PP_DIVISOR, reg32); - } - - /* Enable Backlight if needed */ - if (conf->gpu_cpu_backlight) { - gtt_write(BLC_PWM_CPU_CTL2, BLC_PWM2_ENABLE); - gtt_write(BLC_PWM_CPU_CTL, conf->gpu_cpu_backlight); - } - if (conf->gpu_pch_backlight) { - gtt_write(BLC_PWM_PCH_CTL1, BLM_PCH_PWM_ENABLE); - gtt_write(BLC_PWM_PCH_CTL2, conf->gpu_pch_backlight); - } -} - -static void igd_cdclk_init_haswell(struct device *dev) -{ - config_t *conf = dev->chip_info; - int cdclk = conf->cdclk; - int devid = pci_read_config16(dev, PCI_DEVICE_ID); - int gpu_is_ulx = 0; - u32 dpdiv, lpcll; - - /* Check for ULX GT1 or GT2 */ - if (devid == 0x0a0e || devid == 0x0a1e) - gpu_is_ulx = 1; - - /* 675MHz is not supported on haswell */ - if (cdclk == GT_CDCLK_675) - cdclk = GT_CDCLK_337; - - /* If CD clock is fixed or ULT then set to 450MHz */ - if ((gtt_read(0x42014) & 0x1000000) || cpu_is_ult()) - cdclk = GT_CDCLK_450; - - /* 540MHz is not supported on ULX */ - if (gpu_is_ulx && cdclk == GT_CDCLK_540) - cdclk = GT_CDCLK_337; - - /* 337.5MHz is not supported on non-ULT/ULX */ - if (!gpu_is_ulx && !cpu_is_ult() && cdclk == GT_CDCLK_337) - cdclk = GT_CDCLK_450; - - /* Set variables based on CD Clock setting */ - switch (cdclk) { - case GT_CDCLK_337: - dpdiv = 169; - lpcll = (1 << 26); - break; - case GT_CDCLK_450: - dpdiv = 225; - lpcll = 0; - break; - case GT_CDCLK_540: - dpdiv = 270; - lpcll = (1 << 26); - break; - default: - return; - } - - /* Set LPCLL_CTL CD Clock Frequency Select */ - gtt_rmw(0x130040, 0xf3ffffff, lpcll); - - /* ULX: Inform power controller of selected frequency */ - if (gpu_is_ulx) { - if (cdclk == GT_CDCLK_450) - gtt_write(0x138128, 0x00000000); /* 450MHz */ - else - gtt_write(0x138128, 0x00000001); /* 337.5MHz */ - gtt_write(0x13812c, 0x00000000); - gtt_write(0x138124, 0x80000017); - } - - /* Set CPU DP AUX 2X bit clock dividers */ - gtt_rmw(0x64010, 0xfffff800, dpdiv); - gtt_rmw(0x64810, 0xfffff800, dpdiv); -} - -static void igd_cdclk_init_broadwell(struct device *dev) -{ - config_t *conf = dev->chip_info; - int cdclk = conf->cdclk; - u32 dpdiv, lpcll, pwctl, cdset; - - /* Inform power controller of upcoming frequency change */ - gtt_write(0x138128, 0); - gtt_write(0x13812c, 0); - gtt_write(0x138124, 0x80000018); - - /* Poll GT driver mailbox for run/busy clear */ - if (!gtt_poll(0x138124, (1 << 31), (0 << 31))) - cdclk = GT_CDCLK_450; - - if (gtt_read(0x42014) & 0x1000000) { - /* If CD clock is fixed then set to 450MHz */ - cdclk = GT_CDCLK_450; - } else { - /* Program CD clock to highest supported freq */ - if (cpu_is_ult()) - cdclk = GT_CDCLK_540; - else - cdclk = GT_CDCLK_675; - } - - /* CD clock frequency 675MHz not supported on ULT */ - if (cpu_is_ult() && cdclk == GT_CDCLK_675) - cdclk = GT_CDCLK_540; - - /* Set variables based on CD Clock setting */ - switch (cdclk) { - case GT_CDCLK_337: - cdset = 337; - lpcll = (1 << 27); - pwctl = 2; - dpdiv = 169; - break; - case GT_CDCLK_450: - cdset = 449; - lpcll = 0; - pwctl = 0; - dpdiv = 225; - break; - case GT_CDCLK_540: - cdset = 539; - lpcll = (1 << 26); - pwctl = 1; - dpdiv = 270; - break; - case GT_CDCLK_675: - cdset = 674; - lpcll = (1 << 26) | (1 << 27); - pwctl = 3; - dpdiv = 338; - default: - return; - } - - /* Set LPCLL_CTL CD Clock Frequency Select */ - gtt_rmw(0x130040, 0xf3ffffff, lpcll); - - /* Inform power controller of selected frequency */ - gtt_write(0x138128, pwctl); - gtt_write(0x13812c, 0); - gtt_write(0x138124, 0x80000017); - - /* Program CD Clock Frequency */ - gtt_rmw(0x46200, 0xfffffc00, cdset); - - /* Set CPU DP AUX 2X bit clock dividers */ - gtt_rmw(0x64010, 0xfffff800, dpdiv); - gtt_rmw(0x64810, 0xfffff800, dpdiv); -} - static void igd_init(struct device *dev) { - int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT); - u32 rp1_gfx_freq; - /* IGD needs to be Bus Master */ u32 reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; @@ -491,58 +82,19 @@ static void igd_init(struct device *dev) /* Wait for any configured pre-graphics delay */ if (acpi_slp_type != SLEEP_STATE_S3) { #if IS_ENABLED(CONFIG_CHROMEOS) - if (developer_mode_enabled() || recovery_mode_enabled() || - vboot_wants_oprom()) - mdelay(CONFIG_PRE_GRAPHICS_DELAY); -#else + if (developer_mode_enabled() || recovery_mode_enabled() || + vboot_wants_oprom()) mdelay(CONFIG_PRE_GRAPHICS_DELAY); +#else + mdelay(CONFIG_PRE_GRAPHICS_DELAY); #endif - } - - /* Early init steps */ - if (is_broadwell) { - reg_script_run_on_dev(dev, broadwell_early_init_script); - /* Set GFXPAUSE based on stepping */ - if (cpu_stepping() <= (CPUID_BROADWELL_E0 & 0xf) && - systemagent_revision() <= 9) { - gtt_write(0xa000, 0x300ff); - } else { - gtt_write(0xa000, 0x30020); - } - } else { - reg_script_run_on_dev(dev, haswell_early_init_script); } - - /* Set RP1 graphics frequency */ - rp1_gfx_freq = (MCHBAR32(0x5998) >> 8) & 0xff; - gtt_write(0xa008, rp1_gfx_freq << 24); - - /* Post VBIOS panel setup */ - igd_setup_panel(dev); - /* Initialize PCI device, load/execute BIOS Option ROM */ pci_dev_init(dev); - /* Late init steps */ - if (is_broadwell) { - igd_cdclk_init_broadwell(dev); - reg_script_run_on_dev(dev, broadwell_late_init_script); - } else { - igd_cdclk_init_haswell(dev); - reg_script_run_on_dev(dev, haswell_late_init_script); - } - - if (gfx_get_init_done()) { - /* - * Work around VBIOS issue that is not clearing first 64 - * bytes of the framebuffer during VBE mode set. - */ - struct resource *fb = find_resource(dev, PCI_BASE_ADDRESS_2); - memset((void *)((u32)fb->base), 0, 64); - } - - if (!gfx_get_init_done() && acpi_slp_type != 3) { +#if IS_ENABLED(CONFIG_CHROMEOS) + if (!gfx_get_init_done() && !acpi_is_wakeup_s3()) { /* * Enable DDI-A if the Option ROM did not execute: * @@ -553,6 +105,7 @@ static void igd_init(struct device *dev) gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES | DDI_INIT_DISPLAY_DETECTED); } +#endif /* CONFIG_CHROMEOS */ } static struct device_operations igd_ops = { @@ -560,20 +113,13 @@ static struct device_operations igd_ops = { .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, .init = &igd_init, - .ops_pci = &broadwell_pci_ops, + .ops_pci = &soc_pci_ops, }; static const unsigned short pci_device_ids[] = { - IGD_HASWELL_ULT_GT1, - IGD_HASWELL_ULT_GT2, - IGD_HASWELL_ULT_GT3, - IGD_BROADWELL_U_GT1, - IGD_BROADWELL_U_GT2, - IGD_BROADWELL_U_GT3_15W, - IGD_BROADWELL_U_GT3_28W, - IGD_BROADWELL_Y_GT2, - IGD_BROADWELL_H_GT2, - IGD_BROADWELL_H_GT3, + IGD_SKYLAKE_GT1_SULTM, + IGD_SKYLAKE_GT2_SULXM, + IGD_SKYLAKE_GT2_SULTM, 0, }; diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h index 2b1e77eea0..cd1a6639cc 100644 --- a/src/soc/intel/skylake/include/soc/acpi.h +++ b/src/soc/intel/skylake/include/soc/acpi.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_ACPI_H_ -#define _BROADWELL_ACPI_H_ +#ifndef _SOC_ACPI_H_ +#define _SOC_ACPI_H_ #include <arch/acpi.h> #include <soc/nvs.h> @@ -29,9 +30,13 @@ #define PSS_LATENCY_TRANSITION 10 #define PSS_LATENCY_BUSMASTER 10 -void acpi_create_intel_hpet(acpi_hpet_t *hpet); +void acpi_create_serialio_ssdt(acpi_header_t *ssdt); void acpi_fill_in_fadt(acpi_fadt_t *fadt); unsigned long acpi_madt_irq_overrides(unsigned long current); void acpi_init_gnvs(global_nvs_t *gnvs); +void southcluster_inject_dsdt(device_t device); +unsigned long southcluster_write_acpi_tables(device_t device, + unsigned long current, struct acpi_rsdp *rsdp); + +#endif /* _SOC_ACPI_H_ */ -#endif diff --git a/src/soc/intel/skylake/include/soc/adsp.h b/src/soc/intel/skylake/include/soc/adsp.h deleted file mode 100644 index 747a123579..0000000000 --- a/src/soc/intel/skylake/include/soc/adsp.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_ADSP_H_ -#define _BROADWELL_ADSP_H_ - -#define ADSP_PCI_IRQ 23 -#define ADSP_ACPI_IRQ 3 -#define ADSP_ACPI_IRQEN (1 << 3) - -#define ADSP_SHIM_BASE_LPT 0xe7000 -#define ADSP_SHIM_BASE_WPT 0xfb000 -#define ADSP_SHIM_LTRC 0xe0 -#define ADSP_SHIM_LTRC_VALUE 0x3003 -#define ADSP_SHIM_IMC 0x28 -#define ADSP_SHIM_IPCD 0x40 - -#define ADSP_PCI_VDRTCTL0 0xa0 -#define ADSP_VDRTCTL0_D3PGD_LPT (1 << 1) -#define ADSP_VDRTCTL0_D3PGD_WPT (1 << 0) -#define ADSP_VDRTCTL0_D3SRAMPGD_LPT (1 << 2) -#define ADSP_VDRTCTL0_D3SRAMPGD_WPT (1 << 1) -#define ADSP_PCI_VDRTCTL1 0xa4 -#define ADSP_PCI_VDRTCTL2 0xa8 -#define ADSP_VDRTCTL2_VALUE 0x00000fff - -#define ADSP_IOBP_VDLDAT1 0xd7000624 -#define ADSP_VDLDAT1_VALUE 0x00040100 -#define ADSP_IOBP_VDLDAT2 0xd7000628 -#define ADSP_IOBP_ACPI_IRQ3 0xd9d8 -#define ADSP_IOBP_ACPI_IRQ3I 0xd8d9 -#define ADSP_IOBP_ACPI_IRQ4 0xdbda -#define ADSP_IOBP_PMCTL 0xd70001e0 -#define ADSP_PMCTL_VALUE 0x3f -#define ADSP_IOBP_PCICFGCTL 0xd7000500 -#define ADSP_PCICFGCTL_PCICD (1 << 0) -#define ADSP_PCICFGCTL_ACPIIE (1 << 1) -#define ADSP_PCICFGCTL_SPCBAD (1 << 7) - -#endif diff --git a/src/soc/intel/skylake/include/soc/chipset_fsp_util.h b/src/soc/intel/skylake/include/soc/chipset_fsp_util.h new file mode 100644 index 0000000000..2c05f01b79 --- /dev/null +++ b/src/soc/intel/skylake/include/soc/chipset_fsp_util.h @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#ifndef _CHIPSET_FSP_UTIL_H_ +#define _CHIPSET_FSP_UTIL_H_ + +/* + * Include the FSP binary interface files + * + * These files include the necessary UEFI constants and data structures + * that are used to interface to the FSP binary. + */ + +#include <uefi_types.h> /* UEFI data types */ +#include <IntelFspPkg/Include/FspApi.h> /* FSP API definitions */ +#include <IntelFspPkg/Include/FspInfoHeader.h> /* FSP binary layout */ +#include <MdePkg/Include/Pi/PiBootMode.h> /* UEFI boot mode definitions */ +#include <MdePkg/Include/Pi/PiFirmwareFile.h> /* UEFI file definitions */ +#include <MdePkg/Include/Pi/PiFirmwareVolume.h> /* UEFI file system defs */ +#include <MdePkg/Include/Uefi/UefiMultiPhase.h> /* UEFI memory types */ +#include <MdePkg/Include/Pi/PiHob.h> /* Hand off block definitions */ +#include <MdePkg/Include/Library/HobLib.h> /* HOB routine declarations */ +#include <FspUpdVpd.h> /* Vital/updatable product data definitions */ + +#endif /* _CHIPSET_FSP_UTIL_H_ */ diff --git a/src/soc/intel/skylake/include/soc/cpu.h b/src/soc/intel/skylake/include/soc/cpu.h index 312532d68a..c62b3080c9 100644 --- a/src/soc/intel/skylake/include/soc/cpu.h +++ b/src/soc/intel/skylake/include/soc/cpu.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,29 +15,21 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_CPU_H_ -#define _BROADWELL_CPU_H_ +#ifndef _SOC_CPU_H_ +#define _SOC_CPU_H_ #include <arch/cpu.h> #include <device/device.h> /* CPU types */ -#define HASWELL_FAMILY_ULT 0x40650 -#define BROADWELL_FAMILY_ULT 0x306d0 +#define SKYLAKE_FAMILY_ULT 0x406e0 /* Supported CPUIDs */ -#define CPUID_HASWELL_A0 0x306c1 -#define CPUID_HASWELL_B0 0x306c2 -#define CPUID_HASWELL_C0 0x306c3 -#define CPUID_HASWELL_ULT_B0 0x40650 -#define CPUID_HASWELL_ULT 0x40651 -#define CPUID_HASWELL_HALO 0x40661 -#define CPUID_BROADWELL_C0 0x306d2 -#define CPUID_BROADWELL_D0 0x306d3 -#define CPUID_BROADWELL_E0 0x306d4 +#define CPUID_SKYLAKE_C0 0x406e2 +#define CPUID_SKYLAKE_D0 0x406e3 /* CPU bus clock is fixed at 100MHz */ #define CPU_BCLK 100 @@ -53,7 +46,7 @@ (((1 << ((base)*5)) * (limit)) / 1000) #define C_STATE_LATENCY_FROM_LAT_REG(reg) \ C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \ - (IRTL_1024_NS >> 10)) + (IRTL_1024_NS >> 10)) /* Configure power limits for turbo mode */ void set_power_limits(u8 power_limit_1_time); diff --git a/src/soc/intel/skylake/include/soc/device_nvs.h b/src/soc/intel/skylake/include/soc/device_nvs.h index 7dab40da6a..822c976a15 100644 --- a/src/soc/intel/skylake/include/soc/device_nvs.h +++ b/src/soc/intel/skylake/include/soc/device_nvs.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,31 +15,33 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_DEVICE_NVS_H_ -#define _BROADWELL_DEVICE_NVS_H_ +#ifndef _SOC_DEVICE_NVS_H_ +#define _SOC_DEVICE_NVS_H_ #include <stdint.h> /* Offset in Global NVS where this structure lives */ #define DEVICE_NVS_OFFSET 0x1000 -#define SIO_NVS_DMA 0 -#define SIO_NVS_I2C0 1 -#define SIO_NVS_I2C1 2 -#define SIO_NVS_SPI0 3 -#define SIO_NVS_SPI1 4 -#define SIO_NVS_UART0 5 -#define SIO_NVS_UART1 6 -#define SIO_NVS_SDIO 7 -#define SIO_NVS_ADSP 8 +#define SIO_NVS_I2C0 0 +#define SIO_NVS_I2C1 1 +#define SIO_NVS_I2C2 2 +#define SIO_NVS_I2C3 3 +#define SIO_NVS_I2C4 4 +#define SIO_NVS_I2C5 5 +#define SIO_NVS_SPI0 6 +#define SIO_NVS_SPI1 7 +#define SIO_NVS_UART0 8 +#define SIO_NVS_UART1 9 +#define SIO_NVS_UART2 10 typedef struct { - u8 enable[9]; - u32 bar0[9]; - u32 bar1[9]; + u8 enable[11]; + u32 bar0[11]; + u32 bar1[11]; } __attribute__((packed)) device_nvs_t; #endif diff --git a/src/soc/intel/skylake/include/soc/ehci.h b/src/soc/intel/skylake/include/soc/ehci.h deleted file mode 100644 index 44d51ef311..0000000000 --- a/src/soc/intel/skylake/include/soc/ehci.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_EHCI_H_ -#define _BROADWELL_EHCI_H_ - -/* EHCI Memory Registers */ -#define EHCI_USB_CMD 0x20 -#define EHCI_USB_CMD_RUN (1 << 0) -#define EHCI_USB_CMD_PSE (1 << 4) -#define EHCI_USB_CMD_ASE (1 << 5) -#define EHCI_PORTSC(port) (0x64 + (port * 4)) -#define EHCI_PORTSC_ENABLED (1 << 2) -#define EHCI_PORTSC_SUSPEND (1 << 7) - -#endif diff --git a/src/soc/intel/skylake/include/soc/gpio.h b/src/soc/intel/skylake/include/soc/gpio.h index a0359755d2..efc666f4cd 100644 --- a/src/soc/intel/skylake/include/soc/gpio.h +++ b/src/soc/intel/skylake/include/soc/gpio.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_GPIO_H_ -#define _BROADWELL_GPIO_H_ +#ifndef _SOC_GPIO_H_ +#define _SOC_GPIO_H_ #include <stdint.h> @@ -39,11 +40,115 @@ #define GPIO_CONFIG0(gpio) (0x100 + ((gpio) * 8)) #define GPIO_CONFIG1(gpio) (0x104 + ((gpio) * 8)) -#define MAX_GPIO_NUMBER 94 /* zero based */ +/* + * GPP_Ax to GPP_Gx; + * where x=24 [between GPIO Community A to F] + * = 7 [only for GPIO Community G] + */ +#define MAX_GPIO_NUMBER 151 /* zero based */ #define GPIO_LIST_END 0xffffffff -/* conf0 */ +/* + * Skylake LP GPIO PIN to Pad Mapping + */ +#define GPIO_LP_GROUP_A 0x0 +#define GPIO_LP_GROUP_B 0x1 +#define GPIO_LP_GROUP_C 0x2 +#define GPIO_LP_GROUP_D 0x3 +#define GPIO_LP_GROUP_E 0x4 +#define GPIO_LP_GROUP_F 0x5 +#define GPIO_LP_GROUP_G 0x6 + +#define GPIO_LP_GROUP_GPP_A 0x0200 +#define GPIO_LP_GROUP_GPP_B 0x0201 +#define GPIO_LP_GROUP_GPP_C 0x0202 +#define GPIO_LP_GROUP_GPP_D 0x0203 +#define GPIO_LP_GROUP_GPP_E 0x0204 +#define GPIO_LP_GROUP_GPP_F 0x0205 +#define GPIO_LP_GROUP_GPP_G 0x0206 + +#define GPIO_GROUP_SHIFT 16 +#define MAX_GPIO_PIN_PER_GROUP 24 + +/* GPIO TX STATE */ +#define B_PCH_GPIO_TX_STATE 0x0001 +#define N_PCH_GPIO_TX_STATE 0 + +/* Interrupt number */ +#define B_PCH_GPIO_INTSEL 0x7F +#define N_PCH_GPIO_INTSEL 0 + +/* Structure for storing information about registers offset, community, + * maximal pad number, smi status and smi enable for available groups + */ +typedef struct { + u32 community; + u32 padcfgoffset; + u32 padpergroup; + u32 smistsoffset; + u32 smienoffset; +} GPIO_GROUP_INFO; + +/* + * GPIO Community 0 Registers are for GPP_A and GPP_B groups + */ +#define R_PCH_PCR_GPIO_GPP_A_PADCFG_OFFSET 0x400 +#define R_PCH_PCR_GPIO_GPP_B_PADCFG_OFFSET 0x4C0 +#define R_PCH_PCR_GPIO_GPP_A_SMI_STS 0x0180 +#define R_PCH_PCR_GPIO_GPP_B_SMI_STS 0x0184 +#define R_PCH_PCR_GPIO_GPP_A_SMI_EN 0x01A0 +#define R_PCH_PCR_GPIO_GPP_B_SMI_EN 0x01A4 + +/* + * GPIO Community 1 Registers are for GPP_C, GPP_D, GPP_E groups + */ +#define R_PCH_PCR_GPIO_GPP_C_PADCFG_OFFSET 0x400 +#define R_PCH_PCR_GPIO_GPP_D_PADCFG_OFFSET 0x4C0 +#define R_PCH_PCR_GPIO_GPP_E_PADCFG_OFFSET 0x580 +#define R_PCH_PCR_GPIO_GPP_C_SMI_STS 0x0180 +#define R_PCH_PCR_GPIO_GPP_D_SMI_STS 0x0184 +#define R_PCH_PCR_GPIO_GPP_E_SMI_STS 0x0188 +#define R_PCH_PCR_GPIO_GPP_C_SMI_EN 0x01A0 +#define R_PCH_PCR_GPIO_GPP_D_SMI_EN 0x01A4 +#define R_PCH_PCR_GPIO_GPP_E_SMI_EN 0x01A8 + +/* + * GPIO Community 3 Registers are for GPP_F and GPP_G groups + */ +#define R_PCH_PCR_GPIO_GPP_F_PADCFG_OFFSET 0x400 +#define R_PCH_PCR_GPIO_GPP_G_PADCFG_OFFSET 0x4C0 +/* + * GPIO Community 2 Registers are for GPP_DSW + */ +#define R_PCH_PCR_GPIO_GPD_PADCFG_OFFSET 0x400 + +#define READ 0 +#define WRITE 1 + +/* If in GPIO_GROUP_INFO structure certain register doesn't exist + * it will have value equal to NO_REGISTER_PROPERTY + */ +#define NO_REGISTER_PROPERTY (~0u) + +#define V_PCH_GPIO_GPP_A_PAD_MAX 24 +#define V_PCH_GPIO_GPP_B_PAD_MAX 24 +#define V_PCH_GPIO_GPP_C_PAD_MAX 24 +#define V_PCH_GPIO_GPP_D_PAD_MAX 24 +#define V_PCH_GPIO_GPP_E_PAD_MAX 24 +#define V_PCH_GPIO_GPP_F_PAD_MAX 24 +#define V_PCH_GPIO_GPP_G_PAD_MAX 8 +#define V_PCH_GPIO_GPD_PAD_MAX 12 + +/* SOC has 8 GPIO communities GPP A~G, GPD */ +#define GPIO_COMMUNITY_MAX 8 + +#define GPIO_GET_GROUP_INDEX(group) (group & 0xFF) +#define GPIO_GET_GROUP_INDEX_FROM_PAD(pad) (\ + GPIO_GET_GROUP_INDEX((pad >> 16))) +#define GPIO_GET_PAD_NUMBER(pad) (pad & 0xFFFF) + +/* conf0 */ #define GPIO_MODE_NATIVE (0 << 0) #define GPIO_MODE_GPIO (1 << 0) @@ -66,7 +171,6 @@ #define GPO_LEVEL_HIGH (GPIO_OUT_HIGH << GPO_LEVEL_SHIFT) /* conf1 */ - #define GPIO_PULL_NONE (0 << 0) #define GPIO_PULL_DOWN (1 << 0) #define GPIO_PULL_UP (2 << 0) @@ -75,27 +179,22 @@ #define GPIO_SENSE_DISABLE (1 << 2) /* owner */ - #define GPIO_OWNER_ACPI 0 #define GPIO_OWNER_GPIO 1 /* route */ - #define GPIO_ROUTE_SCI 0 #define GPIO_ROUTE_SMI 1 /* irqen */ - #define GPIO_IRQ_DISABLE 0 #define GPIO_IRQ_ENABLE 1 /* blink */ - #define GPO_NO_BLINK 0 #define GPO_BLINK 1 /* reset */ - #define GPIO_RESET_PWROK 0 #define GPIO_RESET_RSMRST 1 @@ -170,23 +269,388 @@ struct gpio_config { u8 pirq; } __attribute__ ((packed)); -/* Configure GPIOs with mainboard provided settings */ -void init_one_gpio(int gpio_num, struct gpio_config *config); -void init_gpios(const struct gpio_config config[]); -/* Get GPIO pin value */ -int get_gpio(int gpio_num); +/* For any GpioPad usage in code use GPIO_PAD type*/ +typedef u32 GPIO_PAD; + +/* For any GpioGroup usage in code use GPIO_GROUP type */ +typedef u32 GPIO_GROUP; + +/* + * GPIO configuration structure used for pin programming. + * Structure contains fields that can be used to configure pad. + */ +typedef struct { + /* + Pad Mode + Pad can be set as GPIO or one of its native functions. + When in native mode setting Direction, OutputState, Interrupt is unnecessary. + Refer to definition of GPIO_PAD_MODE. + Refer to EDS for each native mode according to the pad. + */ + u32 PadMode : 4; + /* + Host Software Pad Ownership + Set pad to ACPI mode or GPIO Driver Mode. + Refer to definition of GPIO_HOSTSW_OWN. + */ + u32 HostSoftPadOwn : 2; + /* + GPIO Direction + Can choose between In, In with inversion Out, both In and Out, both In with inversion and out or d + isabling both. + Refer to definition of GPIO_DIRECTION for supported settings. + */ + u32 Direction : 5; + /* + Output State + Set Pad output value. + Refer to definition of GPIO_OUTPUT_STATE for supported settings. + This setting takes place when output is enabled. + */ + u32 OutputState : 2; + /* + GPIO Interrupt Configuration + Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI). This setting is applicable only if GPIO + A is in input mode. + If GPIO is set to cause an SCI then also Gpe is enabled for this pad. + Refer to definition of GPIO_INT_CONFIG for supported settings. + */ + u32 InterruptConfig : 8; + /* + GPIO Power Configuration. + This setting controls Pad Reset Configuration and Power Rail Type. + Refer to definition of GPIO_RESET_CONFIG for supported settings. + */ + u32 PowerConfig : 4; + /* + GPIO Electrical Configuration + This setting controls pads termination and voltage tolerance. + Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings. + */ + u32 ElectricalConfig : 7; + /* + GPIO Lock Configuration + This setting controls pads lock. + Refer to definition of GPIO_LOCK_CONFIG for supported settings. + */ + u32 LockConfig : 3; + /* + Additional GPIO configuration + Refer to definition of GPIO_OTHER_CONFIG for supported settings. + */ + u32 OtherSettings : 2; + u32 RsvdBits : 27; +} GPIO_CONFIG; + +typedef struct { + GPIO_PAD GpioPad; + GPIO_CONFIG GpioConfig; +} GPIO_INIT_CONFIG; + +typedef enum { + GpioHardwareDefault = 0x0 +} GPIO_HARDWARE_DEFAULT; + +/* GPIO Pad Mode */ +typedef enum { + GpioPadModeGpio = 0x1, + GpioPadModeNative1 = 0x3, + GpioPadModeNative2 = 0x5, + GpioPadModeNative3 = 0x7, + GpioPadModeNative4 = 0x9, +} GPIO_PAD_MODE; + +/* Host Software Pad Ownership modes */ +typedef enum { + GpioHostOwnDefault = 0x0, /* Leave ownership value unmodified */ + GpioHostOwnAcpi = 0x1, /* Set HOST ownership to ACPI */ + GpioHostOwnGpio = 0x3 /* Set HOST ownership to GPIO */ +} GPIO_HOSTSW_OWN; + +/* GPIO Direction */ +typedef enum { + GpioDirDefault = 0x0, /* Leave pad direction setting unmodified */ + GpioDirInOut = (0x1 | (0x1 << 3)), /* Set pad for both output and input */ + GpioDirInInvOut = (0x1 | (0x3 << 3)), /* Set pad for both output and input with inversion */ + GpioDirIn = (0x3 | (0x1 << 3)), /* Set pad for input only */ + GpioDirInInv = (0x3 | (0x3 << 3)), /* Set pad for input with inversion */ + GpioDirOut = 0x5, /* Set pad for output only */ + GpioDirNone = 0x7 /* Disable both output and input */ +} GPIO_DIRECTION; + +/* GPIO Output State */ +typedef enum { + GpioOutDefault = 0x0, + GpioOutLow = 0x1, + GpioOutHigh = 0x3 +} GPIO_OUTPUT_STATE; + +/* + * GPIO interrupt configuration + * This setting is applicable only if GPIO is in input mode. + * GPIO_INT_CONFIG allows to choose which interrupt is generted + * (IOxAPIC/SCI/SMI/NMI) and how it is triggered (edge or level). + * Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to + * GpioIntBothEdgecan to describe an interrupt e.g. GpioIntApic | GpioIntLevel + * If GPIO is set to cause an SCI then also Gpe is enabled for this pad. + * Not all GPIO are capable of generating an SMI or NMI interrupt + */ +typedef enum { + GpioIntDefault = 0x0, /* Leave value of interrupt routing unmodified */ + GpioIntDis = 0x1, /* Disable IOxAPIC/SCI/SMI/NMI interrupt generation */ + GpioIntNmi = 0x3, /* Enable NMI interrupt only */ + GpioIntSmi = 0x5, /* Enable SMI interrupt only */ + GpioIntSci = 0x9, /* Enable SCI interrupt only */ + GpioIntApic = 0x11, /* Enable IOxAPIC interrupt only */ + GpioIntLevel = (0x1 << 5), /* Set interrupt as level triggered */ + GpioIntEdge = (0x3 << 5), /* Set interrupt as edge triggered */ + GpioIntLvlEdgDis = (0x5 << 5), /* Disable interrupt trigger */ + GpioIntBothEdge = (0x7 << 5) /* Set interrupt as both edge triggered */ +} GPIO_INT_CONFIG; + +/* + * GPIO Power Configuration + * GPIO_RESET_CONFIG allows to set GPIO Reset (used to reset the specified + * Pad Register fields). + */ +typedef enum { + GpioResetDefault = 0x0, /* Leave value of pad reset unmodified */ + GpioResetPwrGood = 0x1, /* Powergood reset */ + GpioResetDeep = 0x3, /* Deep GPIO Reset */ + GpioResetNormal = 0x5, /* GPIO Reset */ + GpioResetResume = 0x7 /* Resume Reset */ +} GPIO_RESET_CONFIG; + +typedef int gpio_t; + +/* Clear GPIO SMI Status */ +void clear_all_smi(void); -/* Set GPIO pin value */ -void set_gpio(int gpio_num, int value); +/* Get GPIO SMI Status */ +void get_smi_status(u32 status[GPIO_COMMUNITY_MAX]); -/* Return non-zero if gpio is set to native function. 0 otherwise. */ -int gpio_is_native(int gpio_num); +/* Enable GPIO SMI */ +void enable_all_smi(void); + +/* Enable GPIO individual Group SMI */ +void enable_gpio_groupsmi(gpio_t gpio_num, u32 mask); /* - * Get a number comprised of multiple GPIO values. gpio_num_array points to - * the array of gpio pin numbers to scan, terminated by -1. + * GPIO Electrical Configuration + * Set GPIO termination and Pad Tolerance (applicable only for some pads) + * Field from GpioTermDefault to GpioTermNative can be OR'ed with + * GpioTolerance1v8. */ -unsigned get_gpios(const int *gpio_num_array); +typedef enum { + GpioTermDefault = 0x0, /* Leave termination setting unmodified */ + GpioTermNone = 0x1, /* none */ + GpioTermWpd5K = 0x5, /* 5kOhm weak pull-down */ + GpioTermWpd20K = 0x9, /* 20kOhm weak pull-down */ + GpioTermWpu1K = 0x13, /* 1kOhm weak pull-up */ + GpioTermWpu2K = 0x17, /* 2kOhm weak pull-up */ + GpioTermWpu5K = 0x15, /* 5kOhm weak pull-up */ + GpioTermWpu20K = 0x19, /* 20kOhm weak pull-up */ + GpioTermWpu1K2K = 0x1B, /* 1kOhm & 2kOhm weak pull-up */ + GpioTermNative = 0x1F, /* Native function for pads termination */ + GpioNoTolerance1v8 = (0x1 << 5), /* Disable 1.8V pad tolerance */ + GpioTolerance1v8 = (0x3 << 5) /* Enable 1.8V pad tolerance */ +} GPIO_ELECTRICAL_CONFIG; +/* + * GPIO LockConfiguration + * Set GPIO configuration lock and output state lock + * GpioLockPadConfig and GpioLockOutputState can be OR'ed + */ +typedef enum { + GpioLockDefault = 0x0, /* Leave lock setting unmodified */ + GpioPadConfigLock = 0x3, /* Lock Pad Configuration */ + GpioOutputStateLock = 0x5 /* Lock GPIO pad output value */ +} GPIO_LOCK_CONFIG; + +/* + * Other GPIO Configuration GPIO_OTHER_CONFIG is used for less often + * settings and for future extensions Supported settings: + * - RX raw override to '1' - allows to override input value to '1' + * This is applicable only if in input mode (both in GPIO and native usage) + * The override takes place at the internal pad state directly from buffer + * and before the RXINV. + */ +typedef enum { + GpioRxRaw1Default = 0x0, /* Use default input override value */ + GpioRxRaw1Dis = 0x1, /* Don't override input */ + GpioRxRaw1En = 0x3 /* Override input to '1' */ +} GPIO_OTHER_CONFIG; + +/* + * LP GPIO pins: Use below for functions from PCH GPIO Lib which + * require GpioPad as argument. Encoding used here + * has all information required by library functions + */ +#define GPIO_LP_GPP_A0 0x02000000 +#define GPIO_LP_GPP_A1 0x02000001 +#define GPIO_LP_GPP_A2 0x02000002 +#define GPIO_LP_GPP_A3 0x02000003 +#define GPIO_LP_GPP_A4 0x02000004 +#define GPIO_LP_GPP_A5 0x02000005 +#define GPIO_LP_GPP_A6 0x02000006 +#define GPIO_LP_GPP_A7 0x02000007 +#define GPIO_LP_GPP_A8 0x02000008 +#define GPIO_LP_GPP_A9 0x02000009 +#define GPIO_LP_GPP_A10 0x0200000A +#define GPIO_LP_GPP_A11 0x0200000B +#define GPIO_LP_GPP_A12 0x0200000C +#define GPIO_LP_GPP_A13 0x0200000D +#define GPIO_LP_GPP_A14 0x0200000E +#define GPIO_LP_GPP_A15 0x0200000F +#define GPIO_LP_GPP_A16 0x02000010 +#define GPIO_LP_GPP_A17 0x02000011 +#define GPIO_LP_GPP_A18 0x02000012 +#define GPIO_LP_GPP_A19 0x02000013 +#define GPIO_LP_GPP_A20 0x02000014 +#define GPIO_LP_GPP_A21 0x02000015 +#define GPIO_LP_GPP_A22 0x02000016 +#define GPIO_LP_GPP_A23 0x02000017 +#define GPIO_LP_GPP_B0 0x02010000 +#define GPIO_LP_GPP_B1 0x02010001 +#define GPIO_LP_GPP_B2 0x02010002 +#define GPIO_LP_GPP_B3 0x02010003 +#define GPIO_LP_GPP_B4 0x02010004 +#define GPIO_LP_GPP_B5 0x02010005 +#define GPIO_LP_GPP_B6 0x02010006 +#define GPIO_LP_GPP_B7 0x02010007 +#define GPIO_LP_GPP_B8 0x02010008 +#define GPIO_LP_GPP_B9 0x02010009 +#define GPIO_LP_GPP_B10 0x0201000A +#define GPIO_LP_GPP_B11 0x0201000B +#define GPIO_LP_GPP_B12 0x0201000C +#define GPIO_LP_GPP_B13 0x0201000D +#define GPIO_LP_GPP_B14 0x0201000E +#define GPIO_LP_GPP_B15 0x0201000F +#define GPIO_LP_GPP_B16 0x02010010 +#define GPIO_LP_GPP_B17 0x02010011 +#define GPIO_LP_GPP_B18 0x02010012 +#define GPIO_LP_GPP_B19 0x02010013 +#define GPIO_LP_GPP_B20 0x02010014 +#define GPIO_LP_GPP_B21 0x02010015 +#define GPIO_LP_GPP_B22 0x02010016 +#define GPIO_LP_GPP_B23 0x02010017 +#define GPIO_LP_GPP_C0 0x02020000 +#define GPIO_LP_GPP_C1 0x02020001 +#define GPIO_LP_GPP_C2 0x02020002 +#define GPIO_LP_GPP_C3 0x02020003 +#define GPIO_LP_GPP_C4 0x02020004 +#define GPIO_LP_GPP_C5 0x02020005 +#define GPIO_LP_GPP_C6 0x02020006 +#define GPIO_LP_GPP_C7 0x02020007 +#define GPIO_LP_GPP_C8 0x02020008 +#define GPIO_LP_GPP_C9 0x02020009 +#define GPIO_LP_GPP_C10 0x0202000A +#define GPIO_LP_GPP_C11 0x0202000B +#define GPIO_LP_GPP_C12 0x0202000C +#define GPIO_LP_GPP_C13 0x0202000D +#define GPIO_LP_GPP_C14 0x0202000E +#define GPIO_LP_GPP_C15 0x0202000F +#define GPIO_LP_GPP_C16 0x02020010 +#define GPIO_LP_GPP_C17 0x02020011 +#define GPIO_LP_GPP_C18 0x02020012 +#define GPIO_LP_GPP_C19 0x02020013 +#define GPIO_LP_GPP_C20 0x02020014 +#define GPIO_LP_GPP_C21 0x02020015 +#define GPIO_LP_GPP_C22 0x02020016 +#define GPIO_LP_GPP_C23 0x02020017 +#define GPIO_LP_GPP_D0 0x02030000 +#define GPIO_LP_GPP_D1 0x02030001 +#define GPIO_LP_GPP_D2 0x02030002 +#define GPIO_LP_GPP_D3 0x02030003 +#define GPIO_LP_GPP_D4 0x02030004 +#define GPIO_LP_GPP_D5 0x02030005 +#define GPIO_LP_GPP_D6 0x02030006 +#define GPIO_LP_GPP_D7 0x02030007 +#define GPIO_LP_GPP_D8 0x02030008 +#define GPIO_LP_GPP_D9 0x02030009 +#define GPIO_LP_GPP_D10 0x0203000A +#define GPIO_LP_GPP_D11 0x0203000B +#define GPIO_LP_GPP_D12 0x0203000C +#define GPIO_LP_GPP_D13 0x0203000D +#define GPIO_LP_GPP_D14 0x0203000E +#define GPIO_LP_GPP_D15 0x0203000F +#define GPIO_LP_GPP_D16 0x02030010 +#define GPIO_LP_GPP_D17 0x02030011 +#define GPIO_LP_GPP_D18 0x02030012 +#define GPIO_LP_GPP_D19 0x02030013 +#define GPIO_LP_GPP_D20 0x02030014 +#define GPIO_LP_GPP_D21 0x02030015 +#define GPIO_LP_GPP_D22 0x02030016 +#define GPIO_LP_GPP_D23 0x02030017 +#define GPIO_LP_GPP_E0 0x02040000 +#define GPIO_LP_GPP_E1 0x02040001 +#define GPIO_LP_GPP_E2 0x02040002 +#define GPIO_LP_GPP_E3 0x02040003 +#define GPIO_LP_GPP_E4 0x02040004 +#define GPIO_LP_GPP_E5 0x02040005 +#define GPIO_LP_GPP_E6 0x02040006 +#define GPIO_LP_GPP_E7 0x02040007 +#define GPIO_LP_GPP_E8 0x02040008 +#define GPIO_LP_GPP_E9 0x02040009 +#define GPIO_LP_GPP_E10 0x0204000A +#define GPIO_LP_GPP_E11 0x0204000B +#define GPIO_LP_GPP_E12 0x0204000C +#define GPIO_LP_GPP_E13 0x0204000D +#define GPIO_LP_GPP_E14 0x0204000E +#define GPIO_LP_GPP_E15 0x0204000F +#define GPIO_LP_GPP_E16 0x02040010 +#define GPIO_LP_GPP_E17 0x02040011 +#define GPIO_LP_GPP_E18 0x02040012 +#define GPIO_LP_GPP_E19 0x02040013 +#define GPIO_LP_GPP_E20 0x02040014 +#define GPIO_LP_GPP_E21 0x02040015 +#define GPIO_LP_GPP_E22 0x02040016 +#define GPIO_LP_GPP_E23 0x02040017 +#define GPIO_LP_GPP_F0 0x02050000 +#define GPIO_LP_GPP_F1 0x02050001 +#define GPIO_LP_GPP_F2 0x02050002 +#define GPIO_LP_GPP_F3 0x02050003 +#define GPIO_LP_GPP_F4 0x02050004 +#define GPIO_LP_GPP_F5 0x02050005 +#define GPIO_LP_GPP_F6 0x02050006 +#define GPIO_LP_GPP_F7 0x02050007 +#define GPIO_LP_GPP_F8 0x02050008 +#define GPIO_LP_GPP_F9 0x02050009 +#define GPIO_LP_GPP_F10 0x0205000A +#define GPIO_LP_GPP_F11 0x0205000B +#define GPIO_LP_GPP_F12 0x0205000C +#define GPIO_LP_GPP_F13 0x0205000D +#define GPIO_LP_GPP_F14 0x0205000E +#define GPIO_LP_GPP_F15 0x0205000F +#define GPIO_LP_GPP_F16 0x02050010 +#define GPIO_LP_GPP_F17 0x02050011 +#define GPIO_LP_GPP_F18 0x02050012 +#define GPIO_LP_GPP_F19 0x02050013 +#define GPIO_LP_GPP_F20 0x02050014 +#define GPIO_LP_GPP_F21 0x02050015 +#define GPIO_LP_GPP_F22 0x02050016 +#define GPIO_LP_GPP_F23 0x02050017 +#define GPIO_LP_GPP_G0 0x02060000 +#define GPIO_LP_GPP_G1 0x02060001 +#define GPIO_LP_GPP_G2 0x02060002 +#define GPIO_LP_GPP_G3 0x02060003 +#define GPIO_LP_GPP_G4 0x02060004 +#define GPIO_LP_GPP_G5 0x02060005 +#define GPIO_LP_GPP_G6 0x02060006 +#define GPIO_LP_GPP_G7 0x02060007 +#define GPIO_LP_GPD0 0x02070000 +#define GPIO_LP_GPD1 0x02070001 +#define GPIO_LP_GPD2 0x02070002 +#define GPIO_LP_GPD3 0x02070003 +#define GPIO_LP_GPD4 0x02070004 +#define GPIO_LP_GPD5 0x02070005 +#define GPIO_LP_GPD6 0x02070006 +#define GPIO_LP_GPD7 0x02070007 +#define GPIO_LP_GPD8 0x02070008 +#define GPIO_LP_GPD9 0x02070009 +#define GPIO_LP_GPD10 0x0207000A +#define GPIO_LP_GPD11 0x0207000B + +#define END_OF_GPIO_TABLE 0xFFFFFFFF #endif diff --git a/src/soc/intel/skylake/include/soc/iobp.h b/src/soc/intel/skylake/include/soc/iobp.h deleted file mode 100644 index 9f17692508..0000000000 --- a/src/soc/intel/skylake/include/soc/iobp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_IOBP_H_ -#define _BROADWELL_IOBP_H_ - -u32 pch_iobp_read(u32 address); -void pch_iobp_write(u32 address, u32 data); -void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); -void pch_iobp_exec(u32 addr, u16 op_dcode, u8 route_id, u32 *data, u8 *resp); - -#endif diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h index bb98975d85..05c5419f49 100644 --- a/src/soc/intel/skylake/include/soc/iomap.h +++ b/src/soc/intel/skylake/include/soc/iomap.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_IOMAP_H_ -#define _BROADWELL_IOMAP_H_ +#ifndef _SOC_IOMAP_H_ +#define _SOC_IOMAP_H_ #define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS #define MCFG_BASE_SIZE 0x4000000 @@ -38,12 +39,16 @@ #define GDXC_BASE_ADDRESS 0xfed84000 #define GDXC_BASE_SIZE 0x1000 +/* TODO: need to remove RCBA code after ASL clean up */ #define RCBA_BASE_ADDRESS 0xfed1c000 #define RCBA_BASE_SIZE 0x4000 #define HPET_BASE_ADDRESS 0xfed00000 -#define ACPI_BASE_ADDRESS 0x1000 +#define PCH_PWRM_BASE_ADDRESS 0xfe000000 +#define PCH_PWRM_BASE_SIZE 0x10000 + +#define ACPI_BASE_ADDRESS 0x1800 #define ACPI_BASE_SIZE 0x100 #define GPIO_BASE_ADDRESS 0x1400 @@ -55,7 +60,6 @@ /* Temporary addresses used in romstage */ #define EARLY_GTT_BAR 0xe0000000 #define EARLY_XHCI_BAR 0xd7000000 -#define EARLY_EHCI_BAR CONFIG_EHCI_BAR #define EARLY_UART_BAR CONFIG_TTYS0_BASE #define EARLY_TEMP_MMIO 0xfed08000 diff --git a/src/soc/intel/skylake/acpi/hda.asl b/src/soc/intel/skylake/include/soc/irq.h index 21736615ac..7f3fd65617 100644 --- a/src/soc/intel/skylake/acpi/hda.asl +++ b/src/soc/intel/skylake/include/soc/irq.h @@ -1,8 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,18 +12,22 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* Intel PCH HDA */ +#ifndef _SOC_IRQ_H_ +#define _SOC_IRQ_H_ -// Intel High Definition Audio (Azalia) 0:1b.0 +#define LPSS_I2C0_IRQ 16 +#define LPSS_I2C1_IRQ 17 +#define LPSS_I2C2_IRQ 18 +#define LPSS_I2C3_IRQ 19 +#define LPSS_I2C4_IRQ 34 +#define LPSS_I2C5_IRQ 33 +#define LPSS_SPI0_IRQ 22 +#define LPSS_SPI1_IRQ 23 +#define LPSS_UART0_IRQ 20 +#define LPSS_UART1_IRQ 21 +#define LPSS_UART2_IRQ 32 +#define SDIO_IRQ 22 -Device (HDEF) -{ - Name (_ADR, 0x001b0000) - Name (_PRW, Package () { 0x6d, 3 }) -} +#endif /* _SOC_IRQ_H_ */ diff --git a/src/soc/intel/skylake/include/soc/lpc.h b/src/soc/intel/skylake/include/soc/lpc.h index 180e527c9e..4e826d7688 100644 --- a/src/soc/intel/skylake/include/soc/lpc.h +++ b/src/soc/intel/skylake/include/soc/lpc.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,16 +15,15 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_LPC_H_ -#define _BROADWELL_LPC_H_ +#ifndef _SOC_LPC_H_ +#define _SOC_LPC_H_ /* PCI Configuration Space (D31:F0): LPC */ -#define SERIRQ_CNTL 0x64 -#define PMBASE 0x40 -#define ACPI_CNTL 0x44 +#define ABASE 0x40 +#define ACNTL 0x44 #define ACPI_EN (1 << 7) #define SCI_IRQ_SEL (7 << 0) #define SCIS_IRQ9 0 @@ -33,23 +33,10 @@ #define SCIS_IRQ21 5 #define SCIS_IRQ22 6 #define SCIS_IRQ23 7 -#define GPIOBASE 0x48 -#define BIOS_CNTL 0xdc -#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ -#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ -#define GPIO_EN (1 << 4) -#define GPIO_ROUT 0xb8 - -#define PIRQA_ROUT 0x60 -#define PIRQB_ROUT 0x61 -#define PIRQC_ROUT 0x62 -#define PIRQD_ROUT 0x63 -#define PIRQE_ROUT 0x68 -#define PIRQF_ROUT 0x69 -#define PIRQG_ROUT 0x6A -#define PIRQH_ROUT 0x6B - +#define SERIRQ_CNTL 0x64 #define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define COMA_RANGE 0x0 /* 0x3F8 - 0x3FF COM1*/ +#define COMB_RANGE 0x1 /* 0x2F8 - 0x2FF COM2*/ #define LPC_EN 0x82 /* LPC IF Enables Register */ #define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ #define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ @@ -66,28 +53,5 @@ #define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ #define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ #define LGMR 0x98 /* LPC Generic Memory Range */ -#define RCBA 0xf0 /* Root Complex Register Block */ - -/* Power Management */ - -#define GEN_PMCON_1 0xa0 -#define SMI_LOCK (1 << 4) -#define GEN_PMCON_2 0xa2 -#define SYSTEM_RESET_STS (1 << 4) -#define THERMTRIP_STS (1 << 3) -#define SYSPWR_FLR (1 << 1) -#define PWROK_FLR (1 << 0) -#define GEN_PMCON_3 0xa4 -#define SUS_PWR_FLR (1 << 14) -#define GEN_RST_STS (1 << 9) -#define RTC_BATTERY_DEAD (1 << 2) -#define PWR_FLR (1 << 1) -#define SLEEP_AFTER_POWER_FAIL (1 << 0) -#define GEN_PMCON_LOCK 0xa6 -#define SLP_STR_POL_LOCK (1 << 2) -#define ACPI_BASE_LOCK (1 << 1) -#define PMIR 0xac -#define PMIR_CF9LOCK (1 << 31) -#define PMIR_CF9GR (1 << 20) - +#define BIOS_CNTL 0xdc #endif diff --git a/src/soc/intel/skylake/include/soc/me.h b/src/soc/intel/skylake/include/soc/me.h deleted file mode 100644 index 3973fc85bf..0000000000 --- a/src/soc/intel/skylake/include/soc/me.h +++ /dev/null @@ -1,507 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_ME_H_ -#define _BROADWELL_ME_H_ - -#include <console/loglevel.h> - -#define ME_RETRY 100000 /* 1 second */ -#define ME_DELAY 10 /* 10 us */ - -/* - * Management Engine PCI registers - */ - -#define PCI_CPU_MEBASE_L 0x70 /* Set by MRC */ -#define PCI_CPU_MEBASE_H 0x74 /* Set by MRC */ - -#define PCI_ME_HFS 0x40 -#define ME_HFS_CWS_RESET 0 -#define ME_HFS_CWS_INIT 1 -#define ME_HFS_CWS_REC 2 -#define ME_HFS_CWS_NORMAL 5 -#define ME_HFS_CWS_WAIT 6 -#define ME_HFS_CWS_TRANS 7 -#define ME_HFS_CWS_INVALID 8 -#define ME_HFS_STATE_PREBOOT 0 -#define ME_HFS_STATE_M0_UMA 1 -#define ME_HFS_STATE_M3 4 -#define ME_HFS_STATE_M0 5 -#define ME_HFS_STATE_BRINGUP 6 -#define ME_HFS_STATE_ERROR 7 -#define ME_HFS_ERROR_NONE 0 -#define ME_HFS_ERROR_UNCAT 1 -#define ME_HFS_ERROR_IMAGE 3 -#define ME_HFS_ERROR_DEBUG 4 -#define ME_HFS_MODE_NORMAL 0 -#define ME_HFS_MODE_DEBUG 2 -#define ME_HFS_MODE_DIS 3 -#define ME_HFS_MODE_OVER_JMPR 4 -#define ME_HFS_MODE_OVER_MEI 5 -#define ME_HFS_BIOS_DRAM_ACK 1 -#define ME_HFS_ACK_NO_DID 0 -#define ME_HFS_ACK_RESET 1 -#define ME_HFS_ACK_PWR_CYCLE 2 -#define ME_HFS_ACK_S3 3 -#define ME_HFS_ACK_S4 4 -#define ME_HFS_ACK_S5 5 -#define ME_HFS_ACK_GBL_RESET 6 -#define ME_HFS_ACK_CONTINUE 7 - -struct me_hfs { - u32 working_state: 4; - u32 mfg_mode: 1; - u32 fpt_bad: 1; - u32 operation_state: 3; - u32 fw_init_complete: 1; - u32 ft_bup_ld_flr: 1; - u32 update_in_progress: 1; - u32 error_code: 4; - u32 operation_mode: 4; - u32 reserved: 4; - u32 boot_options_present: 1; - u32 ack_data: 3; - u32 bios_msg_ack: 4; -} __attribute__ ((packed)); - -#define PCI_ME_UMA 0x44 - -struct me_uma { - u32 size: 6; - u32 reserved_1: 10; - u32 valid: 1; - u32 reserved_0: 14; - u32 set_to_one: 1; -} __attribute__ ((packed)); - -#define PCI_ME_H_GS 0x4c -#define ME_INIT_DONE 1 -#define ME_INIT_STATUS_SUCCESS 0 -#define ME_INIT_STATUS_NOMEM 1 -#define ME_INIT_STATUS_ERROR 2 -#define ME_INIT_STATUS_SUCCESS_OTHER 3 /* SEE ME9 BWG */ - -#define ME_HSIO_MESSAGE (7 << 28) -#define ME_HSIO_CMD_GETHSIOVER 1 -#define ME_HSIO_CMD_CLOSE 0 - -struct me_did { - u32 uma_base: 16; - u32 reserved: 7; - u32 rapid_start: 1; - u32 status: 4; - u32 init_done: 4; -} __attribute__ ((packed)); - -/* - * Apparently the GMES register is renamed to HFS2 (or HFSTS2 according - * to ME9 BWG). Sadly the PCH EDS and the ME BWG do not match on nomenclature. - */ -#define PCI_ME_HFS2 0x48 -/* Infrastructure Progress Values */ -#define ME_HFS2_PHASE_ROM 0 -#define ME_HFS2_PHASE_BUP 1 -#define ME_HFS2_PHASE_UKERNEL 2 -#define ME_HFS2_PHASE_POLICY 3 -#define ME_HFS2_PHASE_MODULE_LOAD 4 -#define ME_HFS2_PHASE_UNKNOWN 5 -#define ME_HFS2_PHASE_HOST_COMM 6 -/* Current State - Based on Infra Progress values. */ -/* ROM State */ -#define ME_HFS2_STATE_ROM_BEGIN 0 -#define ME_HFS2_STATE_ROM_DISABLE 6 -/* BUP State */ -#define ME_HFS2_STATE_BUP_INIT 0 -#define ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1 -#define ME_HFS2_STATE_BUP_FLOW_DET 4 -#define ME_HFS2_STATE_BUP_VSCC_ERR 8 -#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa -#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb -#define ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd -#define ME_HFS2_STATE_BUP_M3 0x11 -#define ME_HFS2_STATE_BUP_M0 0x12 -#define ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13 -#define ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15 -#define ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17 -#define ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18 -#define ME_HFS2_STATE_BUP_T32_MISSING 0x1c -#define ME_HFS2_STATE_BUP_WAIT_DID 0x1f -#define ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20 -#define ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21 -#define ME_HFS2_STATE_BUP_ENABLE_UMA 0x22 -#define ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23 -#define ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24 -#define ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25 -#define ME_HFS2_STATE_BUP_M0_CLK 0x26 -#define ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27 -#define ME_HFS2_STATE_BUP_TEMP_DIS 0x28 -#define ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32 -/* Policy Module State */ -#define ME_HFS2_STATE_POLICY_ENTRY 0 -#define ME_HFS2_STATE_POLICY_RCVD_S3 3 -#define ME_HFS2_STATE_POLICY_RCVD_S4 4 -#define ME_HFS2_STATE_POLICY_RCVD_S5 5 -#define ME_HFS2_STATE_POLICY_RCVD_UPD 6 -#define ME_HFS2_STATE_POLICY_RCVD_PCR 7 -#define ME_HFS2_STATE_POLICY_RCVD_NPCR 8 -#define ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9 -#define ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa -#define ME_HFS2_STATE_POLICY_RCVD_DID 0xb -#define ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc -#define ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd -#define ME_HFS2_STATE_POLICY_FPB_ERR 0xe -#define ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf -#define ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10 -/* Current PM Event Values */ -#define ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0 -#define ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1 -#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2 -#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3 -#define ME_HFS2_PMEVENT_CLEAN_ME_RESET 4 -#define ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5 -#define ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6 -#define ME_HFS2_PMEVENT_S0MO_SXM3 7 -#define ME_HFS2_PMEVENT_SXM3_S0M0 8 -#define ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9 -#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa -#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb -#define ME_HFS2_PMEVENT_SXMX_SXMOFF 0xc - -struct me_hfs2 { - u32 bist_in_progress: 1; - u32 reserved1: 2; - u32 invoke_mebx: 1; - u32 cpu_replaced_sts: 1; - u32 mbp_rdy: 1; - u32 mfs_failure: 1; - u32 warm_reset_request: 1; - u32 cpu_replaced_valid: 1; - u32 reserved2: 4; - u32 mbp_cleared: 1; - u32 reserved3: 2; - u32 current_state: 8; - u32 current_pmevent: 4; - u32 progress_code: 4; -} __attribute__ ((packed)); - -#define PCI_ME_HFS5 0x68 - -#define PCI_ME_H_GS2 0x70 -#define PCI_ME_MBP_GIVE_UP 0x01 - -#define PCI_ME_HERES 0xbc -#define PCI_ME_EXT_SHA1 0x00 -#define PCI_ME_EXT_SHA256 0x02 -#define PCI_ME_HER(x) (0xc0+(4*(x))) - -struct me_heres { - u32 extend_reg_algorithm: 4; - u32 reserved: 26; - u32 extend_feature_present: 1; - u32 extend_reg_valid: 1; -} __attribute__ ((packed)); - -/* - * Management Engine MEI registers - */ - -#define MEI_H_CB_WW 0x00 -#define MEI_H_CSR 0x04 -#define MEI_ME_CB_RW 0x08 -#define MEI_ME_CSR_HA 0x0c - -struct mei_csr { - u32 interrupt_enable: 1; - u32 interrupt_status: 1; - u32 interrupt_generate: 1; - u32 ready: 1; - u32 reset: 1; - u32 reserved: 3; - u32 buffer_read_ptr: 8; - u32 buffer_write_ptr: 8; - u32 buffer_depth: 8; -} __attribute__ ((packed)); - -#define MEI_ADDRESS_CORE 0x01 -#define MEI_ADDRESS_AMT 0x02 -#define MEI_ADDRESS_RESERVED 0x03 -#define MEI_ADDRESS_WDT 0x04 -#define MEI_ADDRESS_MKHI 0x07 -#define MEI_ADDRESS_ICC 0x08 -#define MEI_ADDRESS_THERMAL 0x09 - -#define MEI_HOST_ADDRESS 0 - -struct mei_header { - u32 client_address: 8; - u32 host_address: 8; - u32 length: 9; - u32 reserved: 6; - u32 is_complete: 1; -} __attribute__ ((packed)); - -#define MKHI_GROUP_ID_CBM 0x00 -#define MKHI_GLOBAL_RESET 0x0b -#define MKHI_GROUP_ID_FWCAPS 0x03 -#define MKHI_FWCAPS_GET_RULE 0x02 -#define MKHI_GROUP_ID_HMRFPO 0x05 -#define MKHI_HMRFPO_LOCK 0x02 -#define MKHI_HMRFPO_LOCK_NOACK 0x05 -#define MKHI_GROUP_ID_MDES 0x08 -#define MKHI_MDES_ENABLE 0x09 -#define MKHI_GROUP_ID_GEN 0xff -#define MKHI_GET_FW_VERSION 0x02 -#define MKHI_END_OF_POST 0x0c -#define MKHI_FEATURE_OVERRIDE 0x14 -#define MKHI_END_OF_POST_NOACK 0x1a - -struct mkhi_header { - u32 group_id: 8; - u32 command: 7; - u32 is_response: 1; - u32 reserved: 8; - u32 result: 8; -} __attribute__ ((packed)); - -struct me_fw_version { - u16 code_minor; - u16 code_major; - u16 code_build_number; - u16 code_hot_fix; - u16 recovery_minor; - u16 recovery_major; - u16 recovery_build_number; - u16 recovery_hot_fix; -} __attribute__ ((packed)); - -/* ICC Messages */ -#define ICC_SET_CLOCK_ENABLES 0x3 -#define ICC_API_VERSION_LYNXPOINT 0x00030000 - -struct icc_header { - u32 api_version; - u32 icc_command; - u32 icc_status; - u32 length; - u32 reserved; -} __attribute__ ((packed)); - -struct icc_clock_enables_msg { - u32 clock_enables; - u32 clock_mask; - u32 no_response: 1; - u32 reserved: 31; -} __attribute__ ((packed)); - -#define HECI_EOP_STATUS_SUCCESS 0x0 -#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1 - -#define CBM_RR_GLOBAL_RESET 0x01 - -#define GLOBAL_RESET_BIOS_MRC 0x01 -#define GLOBAL_RESET_BIOS_POST 0x02 -#define GLOBAL_RESET_MEBX 0x03 - -struct me_global_reset { - u8 request_origin; - u8 reset_type; -} __attribute__ ((packed)); - -typedef enum { - ME_NORMAL_BIOS_PATH, - ME_S3WAKE_BIOS_PATH, - ME_ERROR_BIOS_PATH, - ME_RECOVERY_BIOS_PATH, - ME_DISABLE_BIOS_PATH, - ME_FIRMWARE_UPDATE_BIOS_PATH, -} me_bios_path; - -/* - * ME to BIOS Payload Datastructures and definitions. The ordering of the - * structures follows the ordering in the ME9 BWG. - */ - -#define MBP_APPID_KERNEL 1 -#define MBP_APPID_INTEL_AT 3 -#define MBP_APPID_HWA 4 -#define MBP_APPID_ICC 5 -#define MBP_APPID_NFC 6 -/* Kernel items: */ -#define MBP_KERNEL_FW_VER_ITEM 1 -#define MBP_KERNEL_FW_CAP_ITEM 2 -#define MBP_KERNEL_ROM_BIST_ITEM 3 -#define MBP_KERNEL_PLAT_KEY_ITEM 4 -#define MBP_KERNEL_FW_TYPE_ITEM 5 -#define MBP_KERNEL_MFS_FAILURE_ITEM 6 -#define MBP_KERNEL_PLAT_TIME_ITEM 7 -/* Intel AT items: */ -#define MBP_INTEL_AT_STATE_ITEM 1 -/* ICC Items: */ -#define MBP_ICC_PROFILE_ITEM 1 -/* HWA Items: */ -#define MBP_HWA_REQUEST_ITEM 1 -/* NFC Items: */ -#define MBP_NFC_SUPPORT_DATA_ITEM 1 - -#define MBP_MAKE_IDENT(appid, item) ((appid << 8) | item) -#define MBP_IDENT(appid, item) \ - MBP_MAKE_IDENT(MBP_APPID_##appid, MBP_##appid##_##item##_ITEM) - -typedef struct { - u32 mbp_size : 8; - u32 num_entries : 8; - u32 rsvd : 16; -} __attribute__ ((packed)) mbp_header; - -typedef struct { - u32 app_id : 8; - u32 item_id : 8; - u32 length : 8; - u32 rsvd : 8; -} __attribute__ ((packed)) mbp_item_header; - -typedef struct { - u32 major_version : 16; - u32 minor_version : 16; - u32 hotfix_version : 16; - u32 build_version : 16; -} __attribute__ ((packed)) mbp_fw_version_name; - -typedef struct { - u32 full_net : 1; - u32 std_net : 1; - u32 manageability : 1; - u32 reserved_2 : 2; - u32 intel_at : 1; - u32 intel_cls : 1; - u32 reserved : 3; - u32 intel_mpc : 1; - u32 icc_over_clocking : 1; - u32 pavp : 1; - u32 reserved_1 : 4; - u32 ipv6 : 1; - u32 kvm : 1; - u32 och : 1; - u32 vlan : 1; - u32 tls : 1; - u32 reserved_4 : 1; - u32 wlan : 1; - u32 reserved_5 : 8; -} __attribute__ ((packed)) mbp_mefwcaps; - -typedef struct { - u16 device_id; - u16 fuse_test_flags; - u32 umchid[4]; -} __attribute__ ((packed)) mbp_rom_bist_data; - -typedef struct { - u32 key[8]; -} mbp_platform_key; - -typedef struct { - u32 mobile: 1; - u32 desktop: 1; - u32 server: 1; - u32 workstation: 1; - u32 corporate: 1; - u32 consumer: 1; - u32 regular_super_sku: 1; - u32 rsvd: 1; - u32 image_type: 4; - u32 brand: 4; - u32 rsvd1: 16; -} __attribute__ ((packed)) mbp_me_firmware_type; - -typedef struct { - mbp_me_firmware_type rule_data; - u8 available; -} mbp_plat_type; - -typedef struct { - u16 icc_start_address; - u16 mask; -} __attribute__ ((packed)) icc_address_mask; - -typedef struct { - u8 num_icc_profiles; - u8 icc_profile_soft_strap; - u8 icc_profile_index; - u8 reserved; - u32 icc_reg_bundles; - icc_address_mask icc_address_mask[0]; -} __attribute__ ((packed)) mbp_icc_profile; - -typedef struct { - u16 lock_state : 1; - u16 authenticate_module : 1; - u16 s3authentication : 1; - u16 flash_wear_out : 1; - u16 flash_variable_security : 1; - u16 reserved : 11; -} __attribute__ ((packed)) tdt_state_flag; - -typedef struct { - u8 state; - u8 last_theft_trigger; - tdt_state_flag flags; -} __attribute__ ((packed)) mbp_at_state; - -typedef struct { - u32 wake_event_mrst_time_ms; - u32 mrst_pltrst_time_ms; - u32 pltrst_cpurst_time_ms; -} __attribute__ ((packed)) mbp_plat_time; - -typedef struct { - u32 device_type : 2; - u32 reserved : 30; -} __attribute__ ((packed)) mbp_nfc_data; - -typedef struct { - mbp_fw_version_name *fw_version_name; - mbp_mefwcaps *fw_capabilities; - mbp_rom_bist_data *rom_bist_data; - mbp_platform_key *platform_key; - mbp_plat_type *fw_plat_type; - mbp_icc_profile *icc_profile; - mbp_at_state *at_state; - u32 *mfsintegrity; - mbp_plat_time *plat_time; - mbp_nfc_data *nfc_data; -} me_bios_payload; - -struct me_fwcaps { - u32 id; - u8 length; - mbp_mefwcaps caps_sku; - u8 reserved[3]; -} __attribute__ ((packed)); - -void intel_me_hsio_version(uint16_t *version, uint16_t *checksum); - -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) -/* Defined in me_status.c for both romstage and ramstage */ -void intel_me_status(void); -#else -static inline void intel_me_status(void) { } -#endif - -#endif diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h index 707041a161..b857dbe85e 100644 --- a/src/soc/intel/skylake/include/soc/msr.h +++ b/src/soc/intel/skylake/include/soc/msr.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_MSR_H_ -#define _BROADWELL_MSR_H_ +#ifndef _SOC_MSR_H_ +#define _SOC_MSR_H_ #define MSR_PIC_MSG_CONTROL 0x2e #define CORE_THREAD_COUNT_MSR 0x35 @@ -41,21 +42,21 @@ #define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) #define MSR_TURBO_RATIO_LIMIT 0x1ad #define MSR_TEMPERATURE_TARGET 0x1a2 -#define IA32_PERF_CTL 0x199 +#define IA32_PERF_CTL 0x199 #define IA32_THERM_INTERRUPT 0x19b #define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 #define ENERGY_POLICY_PERFORMANCE 0 #define ENERGY_POLICY_NORMAL 6 #define ENERGY_POLICY_POWERSAVE 15 #define IA32_PACKAGE_THERM_INTERRUPT 0x1b2 -#define EMRRphysBase_MSR 0x1f4 -#define EMRRphysMask_MSR 0x1f5 +#define EMRR_PHYS_BASE_MSR 0x1f4 +#define EMRR_PHYS_MASK_MSR 0x1f5 #define IA32_PLATFORM_DCA_CAP 0x1f8 #define MSR_POWER_CTL 0x1fc #define MSR_LT_LOCK_MEMORY 0x2e7 -#define UNCORE_EMRRphysBase_MSR 0x2f4 -#define UNCORE_EMRRphysMask_MSR 0x2f5 -#define IA32_MC0_STATUS 0x401 +#define UNCORE_EMRR_PHYS_BASE_MSR 0x2f4 +#define UNCORE_EMRR_PHYS_MASK_MSR 0x2f5 +#define IA32_MC0_STATUS 0x401 #define SMM_FEATURE_CONTROL_MSR 0x4e0 #define SMM_CPU_SAVE_EN (1 << 1) diff --git a/src/soc/intel/skylake/include/soc/nvs.h b/src/soc/intel/skylake/include/soc/nvs.h index 0f1e63a67a..2c83c5f019 100644 --- a/src/soc/intel/skylake/include/soc/nvs.h +++ b/src/soc/intel/skylake/include/soc/nvs.h @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,12 +16,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_NVS_H_ -#define _BROADWELL_NVS_H_ +#ifndef _SOC_NVS_H_ +#define _SOC_NVS_H_ +#include <rules.h> #include <vendorcode/google/chromeos/gnvs.h> #include <soc/device_nvs.h> @@ -53,7 +55,9 @@ typedef struct { u32 cbmc; /* 0x1c - 0x1f - Coreboot Memory Console */ u64 pm1i; /* 0x20 - 0x27 - PM1 wake status bit */ u64 gpei; /* 0x28 - 0x2f - GPE wake status bit */ - u8 unused[208]; + u32 rpa[12]; /* 0x30 - 0x5f - Root Port Address */ + + u8 unused[160]; /* ChromeOS specific (0x100 - 0xfff) */ chromeos_acpi_t chromeos; @@ -63,7 +67,7 @@ typedef struct { } __attribute__((packed)) global_nvs_t; void acpi_create_gnvs(global_nvs_t *gnvs); -#ifdef __SMM__ +#if ENV_SMM /* Used in SMM to find the ACPI GNVS address */ global_nvs_t *smm_get_gnvs(void); #endif diff --git a/src/soc/intel/skylake/include/soc/pch.h b/src/soc/intel/skylake/include/soc/pch.h index e677215c7f..4b67e998db 100644 --- a/src/soc/intel/skylake/include/soc/pch.h +++ b/src/soc/intel/skylake/include/soc/pch.h @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,38 +16,27 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_PCH_H_ -#define _BROADWELL_PCH_H_ +#ifndef _SOC_PCH_H_ +#define _SOC_PCH_H_ -/* Haswell ULT Pch (LynxPoint-LP) */ -#define PCH_LPT_LP_SAMPLE 0x9c41 -#define PCH_LPT_LP_PREMIUM 0x9c43 -#define PCH_LPT_LP_MAINSTREAM 0x9c45 -#define PCH_LPT_LP_VALUE 0x9c47 +#include <device/device.h> +#include <rules.h> -/* Broadwell PCH (WildatPoint) */ -#define PCH_WPT_HSW_U_SAMPLE 0x9cc1 -#define PCH_WPT_BDW_U_SAMPLE 0x9cc2 -#define PCH_WPT_BDW_U_PREMIUM 0x9cc3 -#define PCH_WPT_BDW_U_BASE 0x9cc5 -#define PCH_WPT_BDW_Y_SAMPLE 0x9cc6 -#define PCH_WPT_BDW_Y_PREMIUM 0x9cc7 -#define PCH_WPT_BDW_Y_BASE 0x9cc9 -#define PCH_WPT_BDW_H 0x9ccb - -/* Power Management Control and Status */ -#define PCH_PCS 0x84 -#define PCH_PCS_PS_D3HOT 3 +/* PCH (SunRisePoint LP) */ +#define PCH_SPT_LP_SAMPLE 0x9d41 +#define PCH_SPT_LP_U_BASE 0x9d43 +#define PCH_SPT_LP_U_PREMIUM 0x9d48 +#define PCH_SPT_LP_Y_PREMIUM 0x9d46 u8 pch_revision(void); u16 pch_type(void); -int pch_is_wpt(void); -int pch_is_wpt_ulx(void); u32 pch_read_soft_strap(int id); void pch_log_state(void); +#if ENV_RAMSTAGE void pch_disable_devfn(device_t dev); - #endif + +#endif /* _SOC_PCH_H_ */ diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 76e3a688ed..240bd4a4e1 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,24 +15,26 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_PCI_DEVS_H_ -#define _BROADWELL_PCI_DEVS_H_ +#ifndef _SOC_PCI_DEVS_H_ +#define _SOC_PCI_DEVS_H_ + +#include <rules.h> #define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0) -#define _PCH_DEVFN(slot,func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func) +#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func) -#if defined(__PRE_RAM__) || defined(__SMM__) || defined(__ROMCC__) -#include <arch/io.h> -#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0) -#define _PCH_DEV(slot,func) PCI_DEV(0, PCH_DEV_SLOT_ ## slot, func) -#else +#if ENV_RAMSTAGE #include <device/device.h> #include <device/pci_def.h> #define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot)) -#define _PCH_DEV(slot,func) dev_find_slot(0, _PCH_DEVFN(slot, func)) +#define _PCH_DEV(slot, func) dev_find_slot(0, _PCH_DEVFN(slot, func)) +#else +#include <arch/io.h> +#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0) +#define _PCH_DEV(slot, func) PCI_DEV(0, PCH_DEV_SLOT_ ## slot, func) #endif /* System Agent Devices */ @@ -44,76 +47,84 @@ #define SA_DEVFN_IGD _SA_DEVFN(IGD) #define SA_DEV_IGD _SA_DEV(IGD) -#define SA_DEV_SLOT_MINIHD 0x03 -#define SA_DEVFN_MINIHD _SA_DEVFN(MINIHD) -#define SA_DEV_MINIHD _SA_DEV(MINIHD) - /* PCH Devices */ - -#define PCH_DEV_SLOT_ADSP 0x13 -#define PCH_DEVFN_ADSP _PCH_DEVFN(ADSP, 0) -#define PCH_DEV_ADSP _PCH_DEV(ADSP, 0) - #define PCH_DEV_SLOT_XHCI 0x14 #define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0) +#define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1) +#define PCH_DEVFN_THERMAL _PCH_DEVFN(XHCI, 2) #define PCH_DEV_XHCI _PCH_DEV(XHCI, 0) - -#define PCH_DEV_SLOT_SIO 0x15 -#define PCH_DEV_SDMA _PCH_DEV(SIO, 0) -#define PCH_DEV_I2C0 _PCH_DEV(SIO, 1) -#define PCH_DEV_I2C1 _PCH_DEV(SIO, 2) -#define PCH_DEV_SPI0 _PCH_DEV(SIO, 3) -#define PCH_DEV_SPI1 _PCH_DEV(SIO, 4) -#define PCH_DEV_UART0 _PCH_DEV(SIO, 5) -#define PCH_DEV_UART1 _PCH_DEV(SIO, 6) -#define PCH_DEVFN_SDMA _PCH_DEVFN(SIO, 0) -#define PCH_DEVFN_I2C0 _PCH_DEVFN(SIO, 1) -#define PCH_DEVFN_I2C1 _PCH_DEVFN(SIO, 2) -#define PCH_DEVFN_SPI0 _PCH_DEVFN(SIO, 3) -#define PCH_DEVFN_SPI1 _PCH_DEVFN(SIO, 4) -#define PCH_DEVFN_UART0 _PCH_DEVFN(SIO, 5) -#define PCH_DEVFN_UART1 _PCH_DEVFN(SIO, 6) +#define PCH_DEV_USBOTG _PCH_DEV(XHCI, 1) +#define PCH_DEV_THERMAL _PCH_DEV(XHCI, 2) + +#define PCH_DEV_SLOT_SIO1 0x15 +#define PCH_DEVFN_I2C0 _PCH_DEVFN(SIO1, 0) +#define PCH_DEVFN_I2C1 _PCH_DEVFN(SIO1, 1) +#define PCH_DEVFN_I2C2 _PCH_DEVFN(SIO1, 2) +#define PCH_DEVFN_I2C3 _PCH_DEVFN(SIO1, 3) +#define PCH_DEV_I2C0 _PCH_DEV(SIO1, 0) +#define PCH_DEV_I2C1 _PCH_DEV(SIO1, 1) +#define PCH_DEV_I2C2 _PCH_DEV(SIO1, 2) +#define PCH_DEV_I2C3 _PCH_DEV(SIO1, 3) #define PCH_DEV_SLOT_ME 0x16 #define PCH_DEVFN_ME _PCH_DEVFN(ME, 0) #define PCH_DEVFN_ME_2 _PCH_DEVFN(ME, 1) #define PCH_DEVFN_ME_IDER _PCH_DEVFN(ME, 2) #define PCH_DEVFN_ME_KT _PCH_DEVFN(ME, 3) +#define PCH_DEVFN_ME_3 _PCH_DEVFN(ME, 4) #define PCH_DEV_ME _PCH_DEV(ME, 0) #define PCH_DEV_ME_2 _PCH_DEV(ME, 1) #define PCH_DEV_ME_IDER _PCH_DEV(ME, 2) #define PCH_DEV_ME_KT _PCH_DEV(ME, 3) +#define PCH_DEV_ME_3 _PCH_DEV(ME, 4) -#define PCH_DEV_SLOT_SDIO 0x17 -#define PCH_DEVFN_SDIO _PCH_DEVFN(SDIO, 0) -#define PCH_DEV_SDIO _PCH_DEV(SDIO, 0) +#define PCH_DEV_SLOT_SATA 0x17 +#define PCH_DEVFN_SATA _PCH_DEVFN(SATA, 0) +#define PCH_DEV_SATA _PCH_DEV(SATA, 0) -#define PCH_DEV_SLOT_GBE 0x19 -#define PCH_DEVFN_GBE _PCH_DEVFN(GBE, 0) -#define PCH_DEV_GBE _PCH_DEV(GBE, 0) - -#define PCH_DEV_SLOT_HDA 0x1b -#define PCH_DEVFN_HDA _PCH_DEVFN(HDA, 0) -#define PCH_DEV_HDA _PCH_DEV(HDA, 0) +#define PCH_DEV_SLOT_SIO2 0x19 +#define PCH_DEVFN_UART2 _PCH_DEVFN(SIO2, 0) +#define PCH_DEVFN_I2C5 _PCH_DEVFN(SIO2, 1) +#define PCH_DEVFN_I2C4 _PCH_DEVFN(SIO2, 2) +#define PCH_DEV_UART2 _PCH_DEV(SIO2, 0) +#define PCH_DEV_I2C5 _PCH_DEV(SIO2, 1) +#define PCH_DEV_I2C4 _PCH_DEV(SIO2, 2) #define PCH_DEV_SLOT_PCIE 0x1c - -#define PCH_DEV_SLOT_EHCI 0x1d -#define PCH_DEVFN_EHCI _PCH_DEVFN(EHCI, 0) -#define PCH_DEV_EHCI _PCH_DEV(EHCI, 0) +#define PCH_DEVFN_PCIE1 _PCH_DEVFN(PCIE, 0) +#define PCH_DEVFN_PCIE2 _PCH_DEVFN(PCIE, 1) +#define PCH_DEVFN_PCIE3 _PCH_DEVFN(PCIE, 2) +#define PCH_DEVFN_PCIE4 _PCH_DEVFN(PCIE, 3) +#define PCH_DEVFN_PCIE5 _PCH_DEVFN(PCIE, 4) +#define PCH_DEVFN_PCIE6 _PCH_DEVFN(PCIE, 5) +#define PCH_DEV_PCIE1 _PCH_DEV(PCIE, 0) +#define PCH_DEV_PCIE2 _PCH_DEV(PCIE, 1) +#define PCH_DEV_PCIE3 _PCH_DEV(PCIE, 2) +#define PCH_DEV_PCIE4 _PCH_DEV(PCIE, 3) +#define PCH_DEV_PCIE5 _PCH_DEV(PCIE, 4) +#define PCH_DEV_PCIE6 _PCH_DEV(PCIE, 5) + +#define PCH_DEV_SLOT_STORAGE 0x1e +#define PCH_DEVFN_UART0 _PCH_DEVFN(STORAGE, 0) +#define PCH_DEVFN_UART1 _PCH_DEVFN(STORAGE, 1) +#define PCH_DEVFN_EMMC _PCH_DEVFN(STORAGE, 4) +#define PCH_DEVFN_SDCARD _PCH_DEVFN(STORAGE, 6) +#define PCH_DEV_UART0 _PCH_DEV(STORAGE, 0) +#define PCH_DEV_UART1 _PCH_DEV(STORAGE, 1) +#define PCH_DEV_EMMC _PCH_DEV(STORAGE, 4) +#define PCH_DEV_SDCARD _PCH_DEV(STORAGE, 6) #define PCH_DEV_SLOT_LPC 0x1f #define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0) -#define PCH_DEVFN_IDE _PCH_DEVFN(LPC, 1) -#define PCH_DEVFN_SATA _PCH_DEVFN(LPC, 2) -#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 3) -#define PCH_DEVFN_SATA2 _PCH_DEVFN(LPC, 5) -#define PCH_DEVFN_THERMAL _PCH_DEVFN(LPC, 6) +#define PCH_DEVFN_PMC _PCH_DEVFN(LPC, 2) +#define PCH_DEVFN_HDA _PCH_DEVFN(LPC, 3) +#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 4) +#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5) +#define PCH_DEVFN_GBE _PCH_DEVFN(LPC, 6) #define PCH_DEV_LPC _PCH_DEV(LPC, 0) -#define PCH_DEV_IDE _PCH_DEV(LPC, 1) -#define PCH_DEV_SATA _PCH_DEV(LPC, 2) -#define PCH_DEV_SMBUS _PCH_DEV(LPC, 3) -#define PCH_DEV_SATA2 _PCH_DEV(LPC, 5) -#define PCH_DEV_THERMAL _PCH_DEV(LPC, 6) - +#define PCH_DEV_PMC _PCH_DEV(LPC, 2) +#define PCH_DEV_HDA _PCH_DEV(LPC, 3) +#define PCH_DEV_SMBUS _PCH_DEV(LPC, 4) +#define PCH_DEV_SPI _PCH_DEV(LPC, 5) +#define PCH_DEV_GBE _PCH_DEV(LPC, 6) #endif diff --git a/src/soc/intel/skylake/include/soc/pcr.h b/src/soc/intel/skylake/include/soc/pcr.h new file mode 100644 index 0000000000..9ac9eddd48 --- /dev/null +++ b/src/soc/intel/skylake/include/soc/pcr.h @@ -0,0 +1,104 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_PCR_H_ +#define _SOC_PCR_H_ + +/* PCH (SunRisePoint LP) */ +#define PCH_PCR_BASE_ADDRESS 0xFD000000 +#define R_PCH_PCR_LPC_GCFD 0x3418 + +/* DMI Control Register */ +#define R_PCH_PCR_DMI_DMIC 0x2234 +#define B_PCH_PCR_DMI_DMIC_SRL (1 << 31) +#define R_PCH_PCR_DMI_LPCLGIR1 0x2730 +#define R_PCH_PCR_DMI_LPCLGIR2 0x2734 +#define R_PCH_PCR_DMI_LPCLGIR3 0x2738 +#define R_PCH_PCR_DMI_LPCLGIR4 0x273c +#define R_PCH_PCR_DMI_LPCIOD 0x2770 +#define R_PCH_PCR_DMI_LPCIOE 0x2774 + +/* RTC configuration */ +#define R_PCH_PCR_RTC_CONF 0x3400 +#define B_PCH_PCR_RTC_CONF_UCMOS_EN 0x4 + +/* ITSS PCRs*/ +/* PIRQA Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQA_ROUT 0x3100 +/* PIRQB Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQB_ROUT 0x3101 +/* PIRQC Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQC_ROUT 0x3102 +/* PIRQD Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQD_ROUT 0x3103 +/* PIRQE Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQE_ROUT 0x3104 +/* PIRQF Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQF_ROUT 0x3105 +/* PIRQG Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQG_ROUT 0x3106 +/* PIRQH Routing Control Register*/ +#define R_PCH_PCR_ITSS_PIRQH_ROUT 0x3107 + +/* IO Trap PCRs */ +/* Trap status Register */ +#define R_PCH_PCR_PSTH_TRPST 0x1E00 +/* Trapped cycle */ +#define R_PCH_PCR_PSTH_TRPC 0x1E10 +/* Trapped write data */ +#define R_PCH_PCR_PSTH_TRPD 0x1E18 + +/* Serial IO UART controller legacy mode */ +#define R_PCH_PCR_SERIAL_IO_GPPRVRW7 0x618 +#define SIO_PCH_LEGACY_UART0 (1 << 0) +#define SIO_PCH_LEGACY_UART1 (1 << 1) +#define SIO_PCH_LEGACY_UART2 (1 << 2) + +/* + * Definition for PCR address + * The PCR address is used to the PCR MMIO programming + */ +#define PCH_PCR_ADDRESS(pid, offset) (void *)(\ + PCH_PCR_BASE_ADDRESS | ((u8)(pid) << 16) | (u16)(offset)) + +/* + * Definition for SBI PID + * The PCH_SBI_PID defines the PID for PCR MMIO programming and + * PCH SBI programming as well. + */ +typedef enum { + PID_PSTH = 0x89, + PID_GPIOCOM3 = 0xAC, + PID_GPIOCOM2 = 0xAD, + PID_GPIOCOM1 = 0xAE, + PID_GPIOCOM0 = 0xAF, + PID_LPC = 0xC7, + PID_ITSS = 0xC4, + PID_RTC = 0xC3, + PID_SERIALIO = 0xCB, + PID_DMI = 0xEF, +} PCH_SBI_PID; + +u8 pcr_read32(PCH_SBI_PID pid, u16 offset, u32 *outdata); +u8 pcr_read16(PCH_SBI_PID pid, u16 offset, u16 *outdata); +u8 pcr_read8(PCH_SBI_PID pid, u16 offset, u8 *outdata); +u8 pcr_write32(PCH_SBI_PID pid, u16 offset, u32 indata); +u8 pcr_write16(PCH_SBI_PID pid, u16 offset, u16 indata); +u8 pcr_write8(PCH_SBI_PID pid, u16 offset, u8 indata); +u8 pcr_andthenor32(PCH_SBI_PID pid, u16 offset, u32 anddata, u32 ordata); +u8 pcr_andthenor16(PCH_SBI_PID pid, u16 offset, u16 anddata, u16 ordata); +u8 pcr_andthenor8(PCH_SBI_PID pid, u16 offset, u8 anddata, u8 ordata); + +#endif /* _SOC_PCR_H_ */ diff --git a/src/soc/intel/skylake/include/soc/pei_data.h b/src/soc/intel/skylake/include/soc/pei_data.h index e6147181f7..232843664a 100644 --- a/src/soc/intel/skylake/include/soc/pei_data.h +++ b/src/soc/intel/skylake/include/soc/pei_data.h @@ -1,7 +1,8 @@ /* - * Broadwell UEFI PEI wrapper + * UEFI PEI wrapper * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -26,17 +27,16 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PEI_DATA_H -#define PEI_DATA_H +#ifndef _PEI_DATA_H_ +#define _PEI_DATA_H_ #include <types.h> -#include <memory_info.h> #define PEI_VERSION 22 #define ABI_X86 __attribute__((regparm(0))) -typedef void ABI_X86 (*tx_byte_func)(unsigned char byte); +typedef void ABI_X86(*tx_byte_func)(unsigned char byte); enum board_type { BOARD_TYPE_CRB_MOBILE = 0, /* CRB Mobile */ @@ -86,24 +86,19 @@ struct usb3_port_setting { uint8_t fixed_eq; } __attribute__((packed)); -struct pei_data -{ +struct pei_data { uint32_t pei_version; enum board_type board_type; int boot_mode; int ec_present; - int usbdebug; /* Base addresses */ uint32_t pciexbar; uint16_t smbusbar; uint32_t xhcibar; - uint32_t ehcibar; uint32_t gttbar; - uint32_t rcba; uint32_t pmbase; - uint32_t gpiobase; uint32_t temp_mmio_base; uint32_t tseg_size; @@ -173,14 +168,15 @@ struct pei_data * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] * since we have 1 CA Vref */ - uint8_t dq_map[2][6][2]; + uint8_t dq_map[2][12]; /* * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins * [CHANNEL][MAX_BYTES] */ uint8_t dqs_map[2][8]; - + uint16_t RcompResistor[3]; + uint16_t RcompTarget[5]; /* Data read from flash and passed into MRC */ const void *saved_data; int saved_data_size; @@ -191,9 +187,8 @@ struct pei_data /* Data from MRC that should be saved to flash */ void *data_to_save; int data_to_save_size; - struct memory_info meminfo; } __attribute__((packed)); typedef struct pei_data PEI_DATA; -#endif +#endif /* _PEI_DATA_H_ */ diff --git a/src/soc/intel/skylake/include/soc/pei_wrapper.h b/src/soc/intel/skylake/include/soc/pei_wrapper.h index 3ade4ffff7..7d37c10e2e 100644 --- a/src/soc/intel/skylake/include/soc/pei_wrapper.h +++ b/src/soc/intel/skylake/include/soc/pei_wrapper.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,15 +15,15 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_PEI_WRAPPER_H_ -#define _BROADWELL_PEI_WRAPPER_H_ +#ifndef _SOC_PEI_WRAPPER_H_ +#define _SOC_PEI_WRAPPER_H_ #include <soc/pei_data.h> -typedef int ABI_X86 (*pei_wrapper_entry_t)(struct pei_data *pei_data); +typedef int ABI_X86(*pei_wrapper_entry_t)(struct pei_data *pei_data); static inline void pei_data_usb2_port(struct pei_data *pei_data, int port, uint16_t length, uint8_t enable, @@ -43,7 +44,7 @@ static inline void pei_data_usb3_port(struct pei_data *pei_data, int port, pei_data->usb3_ports[port].fixed_eq = fixed_eq; } -void broadwell_fill_pei_data(struct pei_data *pei_data); +void soc_fill_pei_data(struct pei_data *pei_data); void mainboard_fill_pei_data(struct pei_data *pei_data); #endif diff --git a/src/soc/intel/skylake/include/soc/pm.h b/src/soc/intel/skylake/include/soc/pm.h index 54fc4a7f1d..3be83f4add 100644 --- a/src/soc/intel/skylake/include/soc/pm.h +++ b/src/soc/intel/skylake/include/soc/pm.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_PM_H_ -#define _BROADWELL_PM_H_ +#ifndef _SOC_PM_H_ +#define _SOC_PM_H_ /* ACPI_BASE_ADDRESS / PMBASE */ @@ -76,12 +77,6 @@ #define SWGPE_CTRL (1 << 1) #define DEVACT_STS 0x44 #define PM2_CNT 0x50 -#define TCO1_CNT 0x60 -#define TCO_TMR_HLT (1 << 11) -#define TCO1_STS 0x64 -#define DMISCI_STS (1 << 9) -#define TCO2_STS 0x66 -#define TCO2_STS_SECOND_TO (1 << 1) #define GPE0_REG_MAX 4 #define GPE0_REG_SIZE 32 @@ -102,7 +97,7 @@ #define SWGPE_STS (1 << 2) #define HOT_PLUG_STS (1 << 1) #define GPE0_EN(x) (0x90 + (x * 4)) -#define WADT_en (1 << 18) +#define WADT_EN (1 << 18) #define GP27_EN (1 << 16) #define PME_B0_EN (1 << 13) #define ME_SCI_EN (1 << 12) @@ -129,9 +124,8 @@ struct chipset_power_state { uint16_t tco2_sts; uint32_t gpe0_sts[4]; uint32_t gpe0_en[4]; - uint16_t gen_pmcon1; - uint16_t gen_pmcon2; - uint16_t gen_pmcon3; + uint16_t gen_pmcon_a; + uint16_t gen_pmcon_b; int prev_sleep_state; uint16_t hsio_version; uint16_t hsio_checksum; @@ -152,7 +146,8 @@ void disable_smi(uint32_t mask); /* ALT_GP_SMI */ uint32_t clear_alt_smi_status(void); -void enable_alt_smi(uint32_t mask); +void enable_alt_smi(int gpionum, u32 mask); +void reset_alt_smi_status(void); /* TCO */ uint32_t clear_tco_status(void); @@ -169,4 +164,9 @@ void disable_gpe(uint32_t mask); /* Return the selected ACPI SCI IRQ */ int acpi_sci_irq(void); +/* Get base address PMC memory mapped registers. */ +uint8_t *pmc_mmio_regs(void); +/* Get base address of TCO I/O registers. */ +uint16_t pmc_tco_regs(void); + #endif diff --git a/src/soc/intel/skylake/include/soc/pmc.h b/src/soc/intel/skylake/include/soc/pmc.h new file mode 100644 index 0000000000..72c9a59e47 --- /dev/null +++ b/src/soc/intel/skylake/include/soc/pmc.h @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_PMC_H_ +#define _SOC_PMC_H_ + +/* PCI Configuration Space (D31:F2): PMC */ +#define ABASE 0x40 +#define ACTL 0x44 +#define PWRM_EN (1 << 8) +#define ACPI_EN (1 << 7) +#define SCI_IRQ_SEL (7 << 0) +#define SCIS_IRQ9 0 +#define SCIS_IRQ10 1 +#define SCIS_IRQ11 2 +#define SCIS_IRQ20 4 +#define SCIS_IRQ21 5 +#define SCIS_IRQ22 6 +#define SCIS_IRQ23 7 +#define PWRMBASE 0x48 +#define GEN_PMCON_A 0xa0 +#define SMI_LOCK (1 << 4) +#define GEN_PMCON_B 0xa4 +#define SLP_STR_POL_LOCK (1 << 18) +#define ACPI_BASE_LOCK (1 << 17) +#define SUS_PWR_FLR (1 << 14) +#define HOST_RST_STS (1 << 9) +#define RTC_BATTERY_DEAD (1 << 2) +#define PWR_FLR (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define ETR3 0xac +#define ETR3_CF9LOCK (1 << 31) +#define ETR3_CF9GR (1 << 20) + +/* Memory mapped IO registers in PMC */ +#define S3_PWRGATE_POL 0x28 +#define S3DC_GATE_SUS (1 << 1) +#define S3AC_GATE_SUS (1 << 0) +#define S4_PWRGATE_POL 0x2c +#define S4DC_GATE_SUS (1 << 1) +#define S4AC_GATE_SUS (1 << 0) +#define S5_PWRGATE_POL 0x30 +#define S5DC_GATE_SUS (1 << 15) +#define S5AC_GATE_SUS (1 << 14) +#define PMSYNC_TPR_CFG 0xc4 +#define PMSYNC_LOCK (1 << 31) + + +/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */ +#define TCO1_STS 0x04 +#define TCO2_STS 0x06 +#define TCO2_STS_SECOND_TO 0x02 +#define TCO2_STS_BOOT 0x04 +#define TCO1_CNT 0x08 +#define TCO_LOCK (1 << 12) +#define TCO_TMR_HLT (1 << 11) + +#endif diff --git a/src/soc/intel/skylake/include/soc/ramstage.h b/src/soc/intel/skylake/include/soc/ramstage.h index 9242aa9ea3..fb06b3386f 100644 --- a/src/soc/intel/skylake/include/soc/ramstage.h +++ b/src/soc/intel/skylake/include/soc/ramstage.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,25 +15,20 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_RAMSTAGE_H_ -#define _BROADWELL_RAMSTAGE_H_ +#ifndef _SOC_RAMSTAGE_H_ +#define _SOC_RAMSTAGE_H_ +#include <chip.h> #include <device/device.h> -#include <soc/intel/broadwell/chip.h> +#include <soc/intel/common/ramstage.h> -void broadwell_init_pre_device(void *chip_info); -void broadwell_init_cpus(device_t dev); -void broadwell_pch_enable_dev(device_t dev); +void pch_enable_dev(device_t dev); +void soc_init_pre_device(void *chip_info); +void soc_init_cpus(device_t dev); -#if CONFIG_HAVE_REFCODE_BLOB -void broadwell_run_reference_code(void); -#else -static inline void broadwell_run_reference_code(void) { } -#endif - -extern struct pci_operations broadwell_pci_ops; +extern struct pci_operations soc_pci_ops; #endif diff --git a/src/soc/intel/skylake/include/soc/rcba.h b/src/soc/intel/skylake/include/soc/rcba.h deleted file mode 100644 index 2c40d0720b..0000000000 --- a/src/soc/intel/skylake/include/soc/rcba.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_RCBA_H_ -#define _BROADWELL_RCBA_H_ - -#include <soc/iomap.h> - -#define RCBA8(x) *((volatile u8 *)(RCBA_BASE_ADDRESS + x)) -#define RCBA16(x) *((volatile u16 *)(RCBA_BASE_ADDRESS + x)) -#define RCBA32(x) *((volatile u32 *)(RCBA_BASE_ADDRESS + x)) - -#define RCBA_AND_OR(bits, x, and, or) \ - RCBA##bits(x) = ((RCBA##bits(x) & (and)) | (or)) -#define RCBA8_AND_OR(x, and, or) RCBA_AND_OR(8, x, and, or) -#define RCBA16_AND_OR(x, and, or) RCBA_AND_OR(16, x, and, or) -#define RCBA32_AND_OR(x, and, or) RCBA_AND_OR(32, x, and, or) -#define RCBA32_OR(x, or) RCBA_AND_OR(32, x, ~0UL, or) - -#define RPC 0x0400 /* 32bit */ -#define RPFN 0x0404 /* 32bit */ - -/* Root Port configuration space hide */ -#define RPFN_HIDE(port) (1 << (((port) * 4) + 3)) -/* Get the function number assigned to a Root Port */ -#define RPFN_FNGET(reg,port) (((reg) >> ((port) * 4)) & 7) -/* Set the function number for a Root Port */ -#define RPFN_FNSET(port,func) (((func) & 7) << ((port) * 4)) -/* Root Port function number mask */ -#define RPFN_FNMASK(port) (7 << ((port) * 4)) - -#define NOINT 0 -#define INTA 1 -#define INTB 2 -#define INTC 3 -#define INTD 4 - -#define DIR_IDR 12 /* Interrupt D Pin Offset */ -#define DIR_ICR 8 /* Interrupt C Pin Offset */ -#define DIR_IBR 4 /* Interrupt B Pin Offset */ -#define DIR_IAR 0 /* Interrupt A Pin Offset */ - -#define PIRQA 0 -#define PIRQB 1 -#define PIRQC 2 -#define PIRQD 3 -#define PIRQE 4 -#define PIRQF 5 -#define PIRQG 6 -#define PIRQH 7 - -/* IO Buffer Programming */ -#define IOBPIRI 0x2330 -#define IOBPD 0x2334 -#define IOBPS 0x2338 -#define IOBPS_READY 0x0001 -#define IOBPS_TX_MASK 0x0006 -#define IOBPS_MASK 0xff00 -#define IOBPS_READ 0x0600 -#define IOBPS_WRITE 0x0700 -#define IOBPU 0x233a -#define IOBPU_MAGIC 0xf000 -#define IOBP_PCICFG_READ 0x0400 -#define IOBP_PCICFG_WRITE 0x0500 - -#define D31IP 0x3100 /* 32bit */ -#define D31IP_TTIP 24 /* Thermal Throttle Pin */ -#define D31IP_SIP2 20 /* SATA Pin 2 */ -#define D31IP_SMIP 12 /* SMBUS Pin */ -#define D31IP_SIP 8 /* SATA Pin */ -#define D30IP 0x3104 /* 32bit */ -#define D30IP_PIP 0 /* PCI Bridge Pin */ -#define D29IP 0x3108 /* 32bit */ -#define D29IP_E1P 0 /* EHCI #1 Pin */ -#define D28IP 0x310c /* 32bit */ -#define D28IP_P8IP 28 /* PCI Express Port 8 */ -#define D28IP_P7IP 24 /* PCI Express Port 7 */ -#define D28IP_P6IP 20 /* PCI Express Port 6 */ -#define D28IP_P5IP 16 /* PCI Express Port 5 */ -#define D28IP_P4IP 12 /* PCI Express Port 4 */ -#define D28IP_P3IP 8 /* PCI Express Port 3 */ -#define D28IP_P2IP 4 /* PCI Express Port 2 */ -#define D28IP_P1IP 0 /* PCI Express Port 1 */ -#define D27IP 0x3110 /* 32bit */ -#define D27IP_ZIP 0 /* HD Audio Pin */ -#define D26IP 0x3114 /* 32bit */ -#define D26IP_E2P 0 /* EHCI #2 Pin */ -#define D25IP 0x3118 /* 32bit */ -#define D25IP_LIP 0 /* GbE LAN Pin */ -#define D22IP 0x3124 /* 32bit */ -#define D22IP_KTIP 12 /* KT Pin */ -#define D22IP_IDERIP 8 /* IDE-R Pin */ -#define D22IP_MEI2IP 4 /* MEI #2 Pin */ -#define D22IP_MEI1IP 0 /* MEI #1 Pin */ -#define D20IP 0x3128 /* 32bit */ -#define D20IP_XHCI 0 /* XHCI Pin */ -#define D31IR 0x3140 /* 16bit */ -#define D30IR 0x3142 /* 16bit */ -#define D29IR 0x3144 /* 16bit */ -#define D28IR 0x3146 /* 16bit */ -#define D27IR 0x3148 /* 16bit */ -#define D26IR 0x314c /* 16bit */ -#define D25IR 0x3150 /* 16bit */ -#define D23IR 0x3158 /* 16bit */ -#define D22IR 0x315c /* 16bit */ -#define D20IR 0x3160 /* 16bit */ -#define D21IR 0x3164 /* 16bit */ -#define D19IR 0x3168 /* 16bit */ -#define ACPIIRQEN 0x31e0 /* 32bit */ -#define OIC 0x31fe /* 16bit */ -#define DEEP_S3_POL 0x3328 /* 32bit */ -#define DEEP_S3_EN_AC (1 << 0) -#define DEEP_S3_EN_DC (1 << 1) -#define DEEP_S5_POL 0x3330 /* 32bit */ -#define DEEP_S5_EN_AC (1 << 14) -#define DEEP_S5_EN_DC (1 << 15) -#define DEEP_SX_CONFIG 0x3334 /* 32bit */ -#define DEEP_SX_WAKE_PIN_EN (1 << 2) -#define DEEP_SX_ACPRESENT_PD (1 << 1) -#define DEEP_SX_GP27_PIN_EN (1 << 0) -#define PMSYNC_CONFIG 0x33c4 /* 32bit */ -#define PMSYNC_CONFIG2 0x33cc /* 32bit */ -#define SOFT_RESET_CTRL 0x38f4 -#define SOFT_RESET_DATA 0x38f8 - -#define DIR_ROUTE(a,b,c,d) \ - (((d) << DIR_IDR) | ((c) << DIR_ICR) | \ - ((b) << DIR_IBR) | ((a) << DIR_IAR)) - -#define RC 0x3400 /* 32bit */ -#define HPTC 0x3404 /* 32bit */ -#define GCS 0x3410 /* 32bit */ -#define BUC 0x3414 /* 32bit */ -#define PCH_DISABLE_GBE (1 << 5) -#define FD 0x3418 /* 32bit */ -#define FDSW 0x3420 /* 8bit */ -#define DISPBDF 0x3424 /* 16bit */ -#define FD2 0x3428 /* 32bit */ -#define CG 0x341c /* 32bit */ - -/* Function Disable 1 RCBA 0x3418 */ -#define PCH_DISABLE_ALWAYS (1 << 0) -#define PCH_DISABLE_ADSPD (1 << 1) -#define PCH_DISABLE_SATA1 (1 << 2) -#define PCH_DISABLE_SMBUS (1 << 3) -#define PCH_DISABLE_HD_AUDIO (1 << 4) -#define PCH_DISABLE_EHCI2 (1 << 13) -#define PCH_DISABLE_LPC (1 << 14) -#define PCH_DISABLE_EHCI1 (1 << 15) -#define PCH_DISABLE_PCIE(x) (1 << (16 + x)) -#define PCH_DISABLE_THERMAL (1 << 24) -#define PCH_DISABLE_SATA2 (1 << 25) -#define PCH_DISABLE_XHCI (1 << 27) - -/* Function Disable 2 RCBA 0x3428 */ -#define PCH_DISABLE_KT (1 << 4) -#define PCH_DISABLE_IDER (1 << 3) -#define PCH_DISABLE_MEI2 (1 << 2) -#define PCH_DISABLE_MEI1 (1 << 1) -#define PCH_ENABLE_DBDF (1 << 0) - -#endif diff --git a/src/soc/intel/skylake/include/soc/romstage.h b/src/soc/intel/skylake/include/soc/romstage.h index b636223561..f030301bdb 100644 --- a/src/soc/intel/skylake/include/soc/romstage.h +++ b/src/soc/intel/skylake/include/soc/romstage.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,38 +15,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_ROMSTAGE_H_ -#define _BROADWELL_ROMSTAGE_H_ +#ifndef _SOC_ROMSTAGE_H_ +#define _SOC_ROMSTAGE_H_ -#include <stdint.h> -#include <arch/cpu.h> - -struct chipset_power_state; -struct pei_data; -struct romstage_params { - unsigned long bist; - struct chipset_power_state *power_state; - struct pei_data *pei_data; -}; - -void mainboard_romstage_entry(struct romstage_params *params); -void romstage_common(struct romstage_params *params); -void *asmlinkage romstage_main(unsigned long bist, uint32_t tsc_lo, - uint32_t tsc_high); -void asmlinkage romstage_after_car(void); -void raminit(struct pei_data *pei_data); -void *setup_stack_and_mttrs(void); +#include <soc/intel/common/romstage.h> struct chipset_power_state; struct chipset_power_state *fill_power_state(void); -void report_platform_info(void); -void report_memory_config(void); - -void set_max_freq(void); - void systemagent_early_init(void); void pch_early_init(void); void pch_uart_init(void); @@ -56,6 +35,6 @@ int smbus_read_byte(unsigned device, unsigned address); int early_spi_read(u32 offset, u32 size, u8 *buffer); int early_spi_read_wpsr(u8 *sr); +void mainboard_fill_spd_data(struct pei_data *pei_data); -void mainboard_pre_console_init(void); -#endif +#endif /* _SOC_ROMSTAGE_H_ */ diff --git a/src/soc/intel/skylake/include/soc/sata.h b/src/soc/intel/skylake/include/soc/sata.h deleted file mode 100644 index 73e7b3150a..0000000000 --- a/src/soc/intel/skylake/include/soc/sata.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _BROADWELL_SATA_H_ -#define _BROADWELL_SATA_H_ - -#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */ -#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */ -#define SATA_SP 0xd0 /* Scratchpad */ - -/* SATA IOBP Registers */ -#define SATA_IOBP_SP0_SECRT88 0xea002688 -#define SATA_IOBP_SP1_SECRT88 0xea002488 - -#define SATA_SECRT88_VADJ_MASK 0xff -#define SATA_SECRT88_VADJ_SHIFT 16 - -#define SATA_IOBP_SP0DTLE_DATA 0xea002550 -#define SATA_IOBP_SP0DTLE_EDGE 0xea002554 -#define SATA_IOBP_SP1DTLE_DATA 0xea002750 -#define SATA_IOBP_SP1DTLE_EDGE 0xea002754 - -#define SATA_DTLE_MASK 0xF -#define SATA_DTLE_DATA_SHIFT 24 -#define SATA_DTLE_EDGE_SHIFT 16 - -/* PCI Configuration Space (D31:F1): IDE */ -#define INTR_LN 0x3c -#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ -#define IDE_DECODE_ENABLE (1 << 15) -#define IDE_SITRE (1 << 14) -#define IDE_ISP_5_CLOCKS (0 << 12) -#define IDE_ISP_4_CLOCKS (1 << 12) -#define IDE_ISP_3_CLOCKS (2 << 12) -#define IDE_RCT_4_CLOCKS (0 << 8) -#define IDE_RCT_3_CLOCKS (1 << 8) -#define IDE_RCT_2_CLOCKS (2 << 8) -#define IDE_RCT_1_CLOCKS (3 << 8) -#define IDE_DTE1 (1 << 7) -#define IDE_PPE1 (1 << 6) -#define IDE_IE1 (1 << 5) -#define IDE_TIME1 (1 << 4) -#define IDE_DTE0 (1 << 3) -#define IDE_PPE0 (1 << 2) -#define IDE_IE0 (1 << 1) -#define IDE_TIME0 (1 << 0) -#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ - -#define IDE_SDMA_CNT 0x48 /* Synchronous DMA control */ -#define IDE_SSDE1 (1 << 3) -#define IDE_SSDE0 (1 << 2) -#define IDE_PSDE1 (1 << 1) -#define IDE_PSDE0 (1 << 0) - -#define IDE_SDMA_TIM 0x4a - -#define IDE_CONFIG 0x54 /* IDE I/O Configuration Register */ -#define SIG_MODE_SEC_NORMAL (0 << 18) -#define SIG_MODE_SEC_TRISTATE (1 << 18) -#define SIG_MODE_SEC_DRIVELOW (2 << 18) -#define SIG_MODE_PRI_NORMAL (0 << 16) -#define SIG_MODE_PRI_TRISTATE (1 << 16) -#define SIG_MODE_PRI_DRIVELOW (2 << 16) -#define FAST_SCB1 (1 << 15) -#define FAST_SCB0 (1 << 14) -#define FAST_PCB1 (1 << 13) -#define FAST_PCB0 (1 << 12) -#define SCB1 (1 << 3) -#define SCB0 (1 << 2) -#define PCB1 (1 << 1) -#define PCB0 (1 << 0) - -#endif diff --git a/src/soc/intel/skylake/include/soc/serialio.h b/src/soc/intel/skylake/include/soc/serialio.h index 2fd6dca973..0bc07c30d7 100644 --- a/src/soc/intel/skylake/include/soc/serialio.h +++ b/src/soc/intel/skylake/include/soc/serialio.h @@ -1,7 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2014 Google Inc. + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -11,84 +12,44 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _BROADWELL_SERIALIO_H_ -#define _BROADWELL_SERIALIO_H_ - -/* Serial IO IOBP Registers */ -#define SIO_IOBP_PORTCTRL0 0xcb000000 /* SDIO D23:F0 */ -#define SIO_IOBP_PORTCTRL0_ACPI_IRQ_EN (1 << 5) -#define SIO_IOBP_PORTCTRL0_PCI_CONF_DIS (1 << 4) -#define SIO_IOBP_PORTCTRL1 0xcb000014 /* SDIO D23:F0 */ -#define SIO_IOBP_PORTCTRL1_SNOOP_SELECT(x) (((x) & 3) << 13) -#define SIO_IOBP_GPIODF 0xcb000154 -#define SIO_IOBP_GPIODF_SDIO_IDLE_DET_EN (1 << 4) -#define SIO_IOBP_GPIODF_DMA_IDLE_DET_EN (1 << 3) -#define SIO_IOBP_GPIODF_UART_IDLE_DET_EN (1 << 2) -#define SIO_IOBP_GPIODF_I2C_IDLE_DET_EN (1 << 1) -#define SIO_IOBP_GPIODF_SPI_IDLE_DET_EN (1 << 0) -#define SIO_IOBP_GPIODF_UART0_BYTE_ACCESS (1 << 10) -#define SIO_IOBP_GPIODF_UART1_BYTE_ACCESS (1 << 11) -#define SIO_IOBP_PORTCTRL2 0xcb000240 /* DMA D21:F0 */ -#define SIO_IOBP_PORTCTRL3 0xcb000248 /* I2C0 D21:F1 */ -#define SIO_IOBP_PORTCTRL4 0xcb000250 /* I2C1 D21:F2 */ -#define SIO_IOBP_PORTCTRL5 0xcb000258 /* SPI0 D21:F3 */ -#define SIO_IOBP_PORTCTRL6 0xcb000260 /* SPI1 D21:F4 */ -#define SIO_IOBP_PORTCTRL7 0xcb000268 /* UART0 D21:F5 */ -#define SIO_IOBP_PORTCTRL8 0xcb000270 /* UART1 D21:F6 */ -#define SIO_IOBP_PORTCTRLX(x) (0xcb000240 + ((x) * 8)) -/* PORTCTRL 2-8 have the same layout */ -#define SIO_IOBP_PORTCTRL_ACPI_IRQ_EN (1 << 21) -#define SIO_IOBP_PORTCTRL_PCI_CONF_DIS (1 << 20) -#define SIO_IOBP_PORTCTRL_SNOOP_SELECT(x) (((x) & 3) << 18) -#define SIO_IOBP_PORTCTRL_INT_PIN(x) (((x) & 0xf) << 2) -#define SIO_IOBP_PORTCTRL_PM_CAP_PRSNT (1 << 1) -#define SIO_IOBP_FUNCDIS0 0xce00aa07 /* DMA D21:F0 */ -#define SIO_IOBP_FUNCDIS1 0xce00aa47 /* I2C0 D21:F1 */ -#define SIO_IOBP_FUNCDIS2 0xce00aa87 /* I2C1 D21:F2 */ -#define SIO_IOBP_FUNCDIS3 0xce00aac7 /* SPI0 D21:F3 */ -#define SIO_IOBP_FUNCDIS4 0xce00ab07 /* SPI1 D21:F4 */ -#define SIO_IOBP_FUNCDIS5 0xce00ab47 /* UART0 D21:F5 */ -#define SIO_IOBP_FUNCDIS6 0xce00ab87 /* UART1 D21:F6 */ -#define SIO_IOBP_FUNCDIS7 0xce00ae07 /* SDIO D23:F0 */ -#define SIO_IOBP_FUNCDIS_DIS (1 << 8) +#ifndef _SERIALIO_H_ +#define _SERIALIO_H_ -/* Serial IO Devices */ -#define SIO_ID_SDMA 0 /* D21:F0 */ -#define SIO_ID_I2C0 1 /* D21:F1 */ -#define SIO_ID_I2C1 2 /* D21:F2 */ -#define SIO_ID_SPI0 3 /* D21:F3 */ -#define SIO_ID_SPI1 4 /* D21:F4 */ -#define SIO_ID_UART0 5 /* D21:F5 */ -#define SIO_ID_UART1 6 /* D21:F6 */ -#define SIO_ID_SDIO 7 /* D23:F0 */ +#define SIO_REG_PPR_CLOCK 0x200 +#define SIO_REG_PPR_CLOCK_EN (1 << 0) +#define SIO_REG_PPR_CLOCK_UPDATE (1 << 31) +#define SIO_REG_PPR_CLOCK_N_DIV 0xc35 +#define SIO_REG_PPR_CLOCK_M_DIV 0x30 -#define SIO_REG_PPR_CLOCK 0x800 -#define SIO_REG_PPR_CLOCK_EN (1 << 0) -#define SIO_REG_PPR_CLOCK_UPDATE (1 << 31) -#define SIO_REG_PPR_CLOCK_M_DIV 0x25a -#define SIO_REG_PPR_CLOCK_N_DIV 0x7fff -#define SIO_REG_PPR_RST 0x804 -#define SIO_REG_PPR_RST_ASSERT 0x3 -#define SIO_REG_PPR_GEN 0x808 -#define SIO_REG_PPR_GEN_LTR_MODE_MASK (1 << 2) -#define SIO_REG_PPR_GEN_VOLTAGE_MASK (1 << 3) -#define SIO_REG_PPR_GEN_VOLTAGE(x) ((x & 1) << 3) -#define SIO_REG_AUTO_LTR 0x814 +#define SIO_REG_PPR_RESETS 0x204 +#define SIO_REG_PPR_RESETS_FUNC (1 << 0) +#define SIO_REG_PPR_RESETS_APB (1 << 1) +#define SIO_REG_PPR_RESETS_IDMA (1 << 2) -#define SIO_REG_SDIO_PPR_GEN 0x1008 -#define SIO_REG_SDIO_PPR_SW_LTR 0x1010 -#define SIO_REG_SDIO_PPR_CMD12 0x3c -#define SIO_REG_SDIO_PPR_CMD12_B30 (1 << 30) +typedef enum { + PchSerialIoDisabled, + PchSerialIoAcpi, + PchSerialIoPci, + PchSerialIoAcpiHidden, + PchSerialIoLegacyUart +} PCH_SERIAL_IO_MODE; -#define SIO_PIN_INTA 1 /* IRQ5 in ACPI mode */ -#define SIO_PIN_INTB 2 /* IRQ6 in ACPI mode */ -#define SIO_PIN_INTC 3 /* IRQ7 in ACPI mode */ -#define SIO_PIN_INTD 4 /* IRQ13 in ACPI mode */ +typedef enum { + PchSerialIoIndexI2C0, + PchSerialIoIndexI2C1, + PchSerialIoIndexI2C2, + PchSerialIoIndexI2C3, + PchSerialIoIndexI2C4, + PchSerialIoIndexI2C5, + PchSerialIoIndexSpi0, + PchSerialIoIndexSpi1, + PchSerialIoIndexUart0, + PchSerialIoIndexUart1, + PchSerialIoIndexUart2, + PchSerialIoIndexMax +} PCH_SERIAL_IO_CONTROLLER; #endif + diff --git a/src/soc/intel/skylake/include/soc/smbus.h b/src/soc/intel/skylake/include/soc/smbus.h index fb13c2d8a9..c081cdf3e3 100644 --- a/src/soc/intel/skylake/include/soc/smbus.h +++ b/src/soc/intel/skylake/include/soc/smbus.h @@ -4,6 +4,7 @@ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com> * Copyright (C) 2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,17 +17,19 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_SMBUS_H_ -#define _BROADWELL_SMBUS_H_ +#ifndef _SOC_SMBUS_H_ +#define _SOC_SMBUS_H_ /* PCI Configuration Space (D31:F3): SMBus */ #define SMB_BASE 0x20 #define HOSTC 0x40 #define HST_EN (1 << 0) #define SMB_RCV_SLVA 0x09 +/* SMBUS TCO base address. */ +#define TCOBASE 0x50 /* SMBus I/O bits. */ #define SMBHSTSTAT 0x0 diff --git a/src/soc/intel/skylake/include/soc/smm.h b/src/soc/intel/skylake/include/soc/smm.h index f7f515cd9b..d89530287e 100644 --- a/src/soc/intel/skylake/include/soc/smm.h +++ b/src/soc/intel/skylake/include/soc/smm.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,14 +15,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_SMM_H_ -#define _BROADWELL_SMM_H_ +#ifndef _SOC_SMM_H_ +#define _SOC_SMM_H_ #include <stdint.h> #include <cpu/x86/msr.h> +#include <soc/intel/common/romstage.h> +#include <soc/intel/common/memmap.h> struct ied_header { char signature[10]; @@ -40,23 +43,16 @@ struct smm_relocation_params { msr_t emrr_mask; msr_t uncore_emrr_base; msr_t uncore_emrr_mask; - /* The smm_save_state_in_msrs field indicates if SMM save state + /* + * The smm_save_state_in_msrs field indicates if SMM save state * locations live in MSRs. This indicates to the CPUs how to adjust - * the SMMBASE and IEDBASE */ + * the SMMBASE and IEDBASE + */ int smm_save_state_in_msrs; }; -/* There is a bug in the order of Kconfig includes in that arch/x86/Kconfig - * is included after chipset code. This causes the chipset's Kconfig to be - * clobbered by the arch/x86/Kconfig if they have the same name. */ -static inline int smm_region_size(void) -{ - /* Make it 8MiB by default. */ - if (CONFIG_SMM_TSEG_SIZE == 0) - return (8 << 20); - return CONFIG_SMM_TSEG_SIZE; -} - +#define smm_region_size mmap_region_granluarity +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) int smm_initialize(void); void smm_relocate(void); @@ -64,10 +60,24 @@ void smm_relocate(void); void southbridge_trigger_smi(void); void southbridge_clear_smi_status(void); -/* The initialization of the southbridge is split into 2 components. One is +/* + * The initialization of the southbridge is split into 2 compoments. One is * for clearing the state in the SMM registers. The other is for enabling - * SMIs. They are split so that other work between the 2 actions. */ + * SMIs. + */ void southbridge_smm_clear_state(void); void southbridge_smm_enable_smi(void); +#else /* CONFIG_HAVE_SMI_HANDLER */ +static inline int smm_initialize(void) +{ + return 0; +} + +static inline void smm_relocate(void) {} +static inline void southbridge_trigger_smi(void) {} +static inline void southbridge_clear_smi_status(void) {} +static inline void southbridge_smm_clear_state(void) {} +static inline void southbridge_smm_enable_smi(void) {} +#endif /* CONFIG_HAVE_SMI_HANDLER */ #endif diff --git a/src/soc/intel/skylake/include/soc/spi.h b/src/soc/intel/skylake/include/soc/spi.h index 1449e29cda..a31c9b2ceb 100644 --- a/src/soc/intel/skylake/include/soc/spi.h +++ b/src/soc/intel/skylake/include/soc/spi.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,39 +15,39 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_SPI_H_ -#define _BROADWELL_SPI_H_ +#ifndef _SOC_SPI_H_ +#define _SOC_SPI_H_ /* * SPI Opcode Menu setup for SPIBAR lockdown * should support most common flash chips. */ - -#define SPIBAR_OFFSET 0x3800 -#define SPIBAR8(x) RCBA8(x + SPIBAR_OFFSET) -#define SPIBAR16(x) RCBA16(x + SPIBAR_OFFSET) -#define SPIBAR32(x) RCBA32(x + SPIBAR_OFFSET) - -/* Registers within the SPIBAR */ -#define SPIBAR_SSFC 0x91 -#define SPIBAR_FDOC 0xb0 -#define SPIBAR_FDOD 0xb4 - -#define SPI_PRR_MAX 5 -#define SPI_PRR(x) (0x74 + ((x) * 4)) -#define SPI_PRR_SHIFT 12 -#define SPI_PRR_MASK 0x1fff -#define SPI_PRR_BASE_SHIFT 0 -#define SPI_PRR_LIMIT_SHIFT 16 -#define SPI_PRR_WPE (1 << 31) - -#define SPIBAR_PREOP 0x94 -#define SPIBAR_OPTYPE 0x96 -#define SPIBAR_OPMENU_LOWER 0x98 -#define SPIBAR_OPMENU_UPPER 0x9c +#define SPIDVID_OFFSET 0x0 +/* Temporay SPI BASE ADDRESS */ +#define TEMP_SPI_BAR 0xFE010000 +/* SPI BASE ADDRESS Register */ +#define B_PCH_SPI_BAR0_MASK 0x0FFF +#define PCH_SPI_BASE_ADDRESS 0x10 +#define SPIBAR_MEMBAR_MASK 0xFFFFF000 +/* Reigsters within the SPIBAR */ +#define SPIBAR_SSFC 0xA1 + +#define SPIBAR_PREOP 0xA4 +#define SPIBAR_OPTYPE 0xA6 +#define SPIBAR_OPMENU_LOWER 0xA8 +#define SPIBAR_OPMENU_UPPER 0xAc +/* STRAP LOCK Register */ +#define SPIBAR_RESET_LOCK 0xF0 +#define SPIBAR_RESET_LOCK_DISABLE 0 +#define SPIBAR_RESET_LOCK_ENABLE 1 +/* STRAP MSG Control Register*/ +#define SPIBAR_RESET_CTRL 0xF4 +#define SPIBAR_RESET_CTRL_SSMC 1 +/* STRAP Data Register*/ +#define SPIBAR_RESET_DATA 0xF8 #define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */ #define SPI_OPTYPE_0 0x01 /* Write, no address */ @@ -78,33 +79,52 @@ (SPI_OPMENU_1 << 8) | SPI_OPMENU_0) #define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \ - (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \ - (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \ + (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \ + (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \ (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0)) #define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */ -#define SPIBAR_HSFS 0x04 /* SPI hardware sequence status */ -#define SPIBAR_HSFS_FLOCKDN (1 << 15)/* Flash Configuration Lock-Down */ -#define SPIBAR_HSFS_SCIP (1 << 5) /* SPI Cycle In Progress */ -#define SPIBAR_HSFS_AEL (1 << 2) /* SPI Access Error Log */ -#define SPIBAR_HSFS_FCERR (1 << 1) /* SPI Flash Cycle Error */ -#define SPIBAR_HSFS_FDONE (1 << 0) /* SPI Flash Cycle Done */ -#define SPIBAR_HSFC 0x06 /* SPI hardware sequence control */ -#define SPIBAR_HSFC_BYTE_COUNT(c) (((c - 1) & 0x3f) << 8) -#define SPIBAR_HSFC_CYCLE_READ (0 << 1) /* Read cycle */ -#define SPIBAR_HSFC_CYCLE_WRITE (2 << 1) /* Write cycle */ -#define SPIBAR_HSFC_CYCLE_ERASE (3 << 1) /* Erase cycle */ -#define SPIBAR_HSFC_GO (1 << 0) /* GO: start SPI transaction */ -#define SPIBAR_FADDR 0x08 /* SPI flash address */ -#define SPIBAR_FDATA(n) (0x10 + (4 * n)) /* SPI flash data */ -#define SPIBAR_SSFS 0x90 -#define SPIBAR_SSFS_ERROR (1 << 3) -#define SPIBAR_SSFS_DONE (1 << 2) -#define SPIBAR_SSFC 0x91 -#define SPIBAR_SSFC_DATA (1 << 14) -#define SPIBAR_SSFC_GO (1 << 1) - -int spi_flash_protect(u32 start, u32 size); - +#define SPIBAR_HSFS 0x04 /* SPI hardware sequence status */ +#define SPIBAR_HSFS_FLOCKDN (1 << 15)/* Flash Configuration Lock-Down */ +#define SPIBAR_HSFS_SCIP (1 << 5) /* SPI Cycle In Progress */ +#define SPIBAR_HSFS_AEL (1 << 2) /* SPI Access Error Log */ +#define SPIBAR_HSFS_FCERR (1 << 1) /* SPI Flash Cycle Error */ +#define SPIBAR_HSFS_FDONE (1 << 0) /* SPI Flash Cycle Done */ +#define SPIBAR_HSFS_BERASE_MASK 3 /* Block/Sector Erase MASK */ +#define SPIBAR_HSFS_BERASE_OFFSET 3 /* Block/Sector Erase OFFSET */ +#define SPIBAR_HSFC 0x06 /* SPI hardware sequence control */ +#define SPIBAR_HSFC_BYTE_COUNT(c) (((c - 1) & 0x3f) << 8) +#define SPIBAR_HSFC_CYCLE_READ (0 << 1) /* Read cycle */ +#define SPIBAR_HSFC_CYCLE_WRITE (2 << 1) /* Write cycle */ +#define SPIBAR_HSFC_CYCLE_ERASE (3 << 1) /* Erase cycle */ +#define SPIBAR_HSFC_GO (1 << 0) /* GO: start SPI transaction */ +#define SPIBAR_FADDR 0x08 /* SPI flash address */ +#define SPIBAR_FADDR_MASK 0x7FFFFFF + +#define SPIBAR_FDATA(n) (0x10 + (4 * n)) /* SPI flash data */ +#define SPIBAR_FPR(n) (0x84 + (4 * n)) /* SPI flash protected range */ +#define SPIBAR_FPR_WPE (1 << 31) /* Flash Write protected */ +#define SPIBAR_SSFS 0xA0 +#define SPIBAR_SSFS_ERROR (1 << 3) +#define SPIBAR_SSFS_DONE (1 << 2) +#define SPIBAR_SSFC 0xA1 +#define SPIBAR_SSFC_DATA (1 << 14) +#define SPIBAR_SSFC_GO (1 << 1) + +#define SPIBAR_FDOC 0xB4 +#define SPIBAR_FDOC_COMPONENT (1 << 12) +#define SPIBAR_FDOC_FDSI_1 (1 << 2) + +#define SPIBAR_FDOD 0xB8 +#define FLCOMP_C0DEN_MASK 0xF +#define FLCOMP_C0DEN_8MB 4 +#define FLCOMP_C0DEN_16MB 5 +#define FLCOMP_C0DEN_32MB 6 + +#define SPIBAR_BIOS_CNTL 0xDC +#define SPIBAR_BC_WPD (1 << 0) +#define SPIBAR_BC_EISS (1 << 5) + +void *get_spi_bar(void); #endif diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h index 325a4a5a6c..6bb5c66d2a 100644 --- a/src/soc/intel/skylake/include/soc/systemagent.h +++ b/src/soc/intel/skylake/include/soc/systemagent.h @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2008 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,31 +16,23 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_SYSTEMAGENT_H_ -#define _BROADWELL_SYSTEMAGENT_H_ +#ifndef _SOC_SYSTEMAGENT_H_ +#define _SOC_SYSTEMAGENT_H_ #include <soc/iomap.h> #define SA_IGD_OPROM_VENDEV 0x80860406 -#define IGD_HASWELL_ULT_GT1 0x0a06 -#define IGD_HASWELL_ULT_GT2 0x0a16 -#define IGD_HASWELL_ULT_GT3 0x0a26 -#define IGD_BROADWELL_U_GT1 0x1606 -#define IGD_BROADWELL_U_GT2 0x1616 -#define IGD_BROADWELL_U_GT3_15W 0x1626 -#define IGD_BROADWELL_U_GT3_28W 0x162b -#define IGD_BROADWELL_Y_GT2 0x161e -#define IGD_BROADWELL_H_GT2 0x1612 -#define IGD_BROADWELL_H_GT3 0x1622 - -#define MCH_BROADWELL_ID_U_Y 0x1604 -#define MCH_BROADWELL_REV_D0 0x06 -#define MCH_BROADWELL_REV_E0 0x08 -#define MCH_BROADWELL_REV_F0 0x09 +#define IGD_SKYLAKE_GT1_SULTM 0x1906 +#define IGD_SKYLAKE_GT2_SULXM 0x191E +#define IGD_SKYLAKE_GT2_SULTM 0x1916 + +#define MCH_SKYLAKE_ID_U 0x1904 +#define MCH_SKYLAKE_ID_Y 0x190c +#define MCH_SKYLAKE_ID_ULX 0x1924 /* Device 0:0.0 PCI configuration space */ @@ -91,9 +84,9 @@ /* MCHBAR */ -#define MCHBAR8(x) *((volatile u8 *)(MCH_BASE_ADDRESS + x)) -#define MCHBAR16(x) *((volatile u16 *)(MCH_BASE_ADDRESS + x)) -#define MCHBAR32(x) *((volatile u32 *)(MCH_BASE_ADDRESS + x)) +#define MCHBAR8(x) (*(volatile u8 *)(MCH_BASE_ADDRESS + x)) +#define MCHBAR16(x) (*(volatile u16 *)(MCH_BASE_ADDRESS + x)) +#define MCHBAR32(x) (*(volatile u32 *)(MCH_BASE_ADDRESS + x)) #define MCHBAR_PEI_VERSION 0x5034 #define BIOS_RESET_CPL 0x5da8 @@ -115,8 +108,6 @@ #define MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL 0x909 #define MAILBOX_BIOS_CMD_READ_PCH_POWER 0xa #define MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT 0xb -#define MAILBOX_BIOS_CMD_READ_C9C10_VOLTAGE 0x26 -#define MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE 0x27 /* Errors are returned back in bits 7:0. */ #define MAILBOX_BIOS_ERROR_NONE 0 #define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1 diff --git a/src/soc/intel/skylake/include/soc/xhci.h b/src/soc/intel/skylake/include/soc/xhci.h index 2b899a3d75..8830ede865 100644 --- a/src/soc/intel/skylake/include/soc/xhci.h +++ b/src/soc/intel/skylake/include/soc/xhci.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,11 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_XHCI_H_ -#define _BROADWELL_XHCI_H_ +#ifndef _SOC_XHCI_H_ +#define _SOC_XHCI_H_ + +#include <rules.h> /* XHCI PCI Registers */ #define XHCI_PWR_CTL_STS 0x74 @@ -39,14 +42,14 @@ #define XHCI_USB3PDO 0xe8 /* XHCI Memory Registers */ -#define XHCI_USB3_PORTSC(port) (0x530 + (port * 0x10)) +#define XHCI_USB3_PORTSC(port) (0x510 + (port * 0x10)) #define XHCI_USB3_PORTSC_CHST (0x7f << 17) #define XHCI_USB3_PORTSC_WCE (1 << 25) /* Wake on Connect */ #define XHCI_USB3_PORTSC_WDE (1 << 26) /* Wake on Disconnect */ #define XHCI_USB3_PORTSC_WOE (1 << 27) /* Wake on Overcurrent */ #define XHCI_USB3_PORTSC_WRC (1 << 19) /* Warm Reset Complete */ -#define XHCI_USB3_PORTSC_LWS (1 << 16) /* Link Write Strobe */ -#define XHCI_USB3_PORTSC_PED (1 << 1) /* Port Enabled/Disabled */ +#define XHCI_USB3_PORTSC_LWS (1 << 16) /* Link Write Strobe */ +#define XHCI_USB3_PORTSC_PED (1 << 1) /* Port Enabled/Disabled */ #define XHCI_USB3_PORTSC_WPR (1 << 31) /* Warm Port Reset */ #define XHCI_USB3_PORTSC_PLS (0xf << 5) /* Port Link State */ #define XHCI_PLSR_DISABLED (4 << 5) /* Port is disabled */ @@ -54,7 +57,7 @@ #define XHCI_PLSR_POLLING (7 << 5) /* Port is polling */ #define XHCI_PLSW_ENABLE (5 << 5) /* Transition from disabled */ -#ifdef __SMM__ +#if ENV_SMM void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ); #endif diff --git a/src/soc/intel/skylake/iobp.c b/src/soc/intel/skylake/iobp.c deleted file mode 100644 index 870f6af597..0000000000 --- a/src/soc/intel/skylake/iobp.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <delay.h> -#include <arch/io.h> -#include <soc/iobp.h> -#include <soc/rcba.h> - -#define IOBP_RETRY 1000 - -static inline int iobp_poll(void) -{ - unsigned try; - - for (try = IOBP_RETRY; try > 0; try--) { - u16 status = RCBA16(IOBPS); - if ((status & IOBPS_READY) == 0) - return 1; - udelay(10); - } - - printk(BIOS_ERR, "IOBP: timeout waiting for transaction to complete\n"); - return 0; -} - -u32 pch_iobp_read(u32 address) -{ - u16 status; - - if (!iobp_poll()) - return 0; - - /* Set the address */ - RCBA32(IOBPIRI) = address; - - /* READ OPCODE */ - status = RCBA16(IOBPS); - status &= ~IOBPS_MASK; - status |= IOBPS_READ; - RCBA16(IOBPS) = status; - - /* Undocumented magic */ - RCBA16(IOBPU) = IOBPU_MAGIC; - - /* Set ready bit */ - status = RCBA16(IOBPS); - status |= IOBPS_READY; - RCBA16(IOBPS) = status; - - if (!iobp_poll()) - return 0; - - /* Check for successful transaction */ - status = RCBA16(IOBPS); - if (status & IOBPS_TX_MASK) { - printk(BIOS_ERR, "IOBP: read 0x%08x failed\n", address); - return 0; - } - - /* Read IOBP data */ - return RCBA32(IOBPD); -} - -void pch_iobp_write(u32 address, u32 data) -{ - u16 status; - - if (!iobp_poll()) - return; - - /* Set the address */ - RCBA32(IOBPIRI) = address; - - /* WRITE OPCODE */ - status = RCBA16(IOBPS); - status &= ~IOBPS_MASK; - status |= IOBPS_WRITE; - RCBA16(IOBPS) = status; - - RCBA32(IOBPD) = data; - - /* Undocumented magic */ - RCBA16(IOBPU) = IOBPU_MAGIC; - - /* Set ready bit */ - status = RCBA16(IOBPS); - status |= IOBPS_READY; - RCBA16(IOBPS) = status; - - if (!iobp_poll()) - return; - - /* Check for successful transaction */ - status = RCBA16(IOBPS); - if (status & IOBPS_TX_MASK) - printk(BIOS_ERR, "IOBP: write 0x%08x failed\n", address); -} - -void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue) -{ - u32 data = pch_iobp_read(address); - - /* Update the data */ - data &= andvalue; - data |= orvalue; - - pch_iobp_write(address, data); -} - -void pch_iobp_exec(u32 addr, u16 op_code, u8 route_id, u32 *data, u8 *resp) -{ - if (!data || !resp) - return; - - *resp = -1; - if (!iobp_poll()) - return; - - /* RCBA2330[31:0] = Address */ - RCBA32(IOBPIRI) = addr; - /* RCBA2338[15:8] = opcode */ - RCBA16(IOBPS) = (RCBA16(IOBPS) & 0x00ff) | op_code; - /* RCBA233A[15:8] = 0xf0 RCBA233A[7:0] = Route ID */ - RCBA16(IOBPU) = IOBPU_MAGIC | route_id; - - RCBA32(IOBPD) = *data; - /* Set RCBA2338[0] to trigger IOBP transaction*/ - RCBA16(IOBPS) = RCBA16(IOBPS) | 0x1; - - if (!iobp_poll()) - return; - - *resp = (RCBA16(IOBPS) & IOBPS_TX_MASK) >> 1; - *data = RCBA32(IOBPD); -} diff --git a/src/soc/intel/skylake/lpc.c b/src/soc/intel/skylake/lpc.c index 6cc11165c3..64dfa22a9c 100644 --- a/src/soc/intel/skylake/lpc.c +++ b/src/soc/intel/skylake/lpc.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,15 +16,16 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <arch/acpigen.h> +#include "chip.h" #include <console/console.h> #include <delay.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> -#include <pc80/mc146818rtc.h> #include <pc80/isa-dma.h> #include <pc80/i8259.h> #include <arch/io.h> @@ -34,21 +36,17 @@ #include <cbmem.h> #include <reg_script.h> #include <string.h> +#include <soc/acpi.h> #include <soc/gpio.h> -#include <soc/iobp.h> #include <soc/iomap.h> #include <soc/lpc.h> #include <soc/nvs.h> #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/pm.h> +#include <soc/pmc.h> #include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/intel/broadwell/chip.h> -#include <arch/acpi.h> -#include <arch/acpigen.h> -#include <cpu/cpu.h> - +#include <soc/pcr.h> #if IS_ENABLED(CONFIG_CHROMEOS) #include <vendorcode/google/chromeos/chromeos.h> #endif @@ -57,25 +55,26 @@ static void pch_enable_ioapic(struct device *dev) { u32 reg32; - set_ioapic_id(VIO_APIC_VADDR, 0x02); + set_ioapic_id((void *)IO_APIC_ADDR, 0x02); /* affirm full set of redirection table entries ("write once") */ - reg32 = io_apic_read(VIO_APIC_VADDR, 0x01); + reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01); /* PCH-LP has 39 redirection entries */ reg32 &= ~0x00ff0000; reg32 |= 0x00270000; - io_apic_write(VIO_APIC_VADDR, 0x01, reg32); + io_apic_write((void *)IO_APIC_ADDR, 0x01, reg32); /* * Select Boot Configuration register (0x03) and * use Processor System Bus (0x01) to deliver interrupts. */ - io_apic_write(VIO_APIC_VADDR, 0x03, 0x01); + io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01); } -/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control +/* + * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control * 0x00 - 0000 = Reserved * 0x01 - 0001 = Reserved * 0x02 - 0010 = Reserved @@ -101,18 +100,17 @@ static void pch_pirq_init(device_t dev) device_t irq_dev; config_t *config = dev->chip_info; - pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing); - pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing); - pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing); - pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQA_ROUT, config->pirqa_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQB_ROUT, config->pirqb_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQC_ROUT, config->pirqc_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQD_ROUT, config->pirqd_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQE_ROUT, config->pirqe_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQF_ROUT, config->pirqf_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQG_ROUT, config->pirqg_routing); + pcr_write8(PID_ITSS, R_PCH_PCR_ITSS_PIRQH_ROUT, config->pirqh_routing); - pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing); - pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing); - pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing); - pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing); - - for(irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { - u8 int_pin=0, int_line=0; + for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { + u8 int_pin = 0, int_line = 0; if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI) continue; @@ -120,10 +118,18 @@ static void pch_pirq_init(device_t dev) int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN); switch (int_pin) { - case 1: /* INTA# */ int_line = config->pirqa_routing; break; - case 2: /* INTB# */ int_line = config->pirqb_routing; break; - case 3: /* INTC# */ int_line = config->pirqc_routing; break; - case 4: /* INTD# */ int_line = config->pirqd_routing; break; + case 1: /* INTA# */ + int_line = config->pirqa_routing; + break; + case 2: /* INTB# */ + int_line = config->pirqb_routing; + break; + case 3: /* INTC# */ + int_line = config->pirqc_routing; + break; + case 4: /* INTD# */ + int_line = config->pirqd_routing; + break; } if (!int_line) @@ -133,336 +139,26 @@ static void pch_pirq_init(device_t dev) } } -static void pch_power_options(device_t dev) -{ - u16 reg16; - const char *state; - /* Get the chip configuration */ - config_t *config = dev->chip_info; - int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; - - /* Which state do we want to goto after g3 (power restored)? - * 0 == S0 Full On - * 1 == S5 Soft Off - * - * If the option is not existent (Laptops), use Kconfig setting. - */ - get_option(&pwr_on, "power_on_after_fail"); - - reg16 = pci_read_config16(dev, GEN_PMCON_3); - reg16 &= 0xfffe; - switch (pwr_on) { - case MAINBOARD_POWER_OFF: - reg16 |= 1; - state = "off"; - break; - case MAINBOARD_POWER_ON: - reg16 &= ~1; - state = "on"; - break; - case MAINBOARD_POWER_KEEP: - reg16 &= ~1; - state = "state keep"; - break; - default: - state = "undefined"; - } - pci_write_config16(dev, GEN_PMCON_3, reg16); - printk(BIOS_INFO, "Set power %s after power failure.\n", state); - - /* GPE setup based on device tree configuration */ - enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, - config->gpe0_en_3, config->gpe0_en_4); - - /* SMI setup based on device tree configuration */ - enable_alt_smi(config->alt_gp_smi_en); -} - -#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) -/* - * Preserve Vboot NV data when clearing CMOS as it will - * have been re-initialized already by Vboot firmware init. - */ -static void pch_cmos_init_preserve(int reset) -{ - uint8_t vbnv[CONFIG_VBNV_SIZE]; - - if (reset) - read_vbnv(vbnv); - - cmos_init(reset); - - if (reset) - save_vbnv(vbnv); -} -#endif - -static void pch_rtc_init(struct device *dev) -{ - u8 reg8; - int rtc_failed; - - reg8 = pci_read_config8(dev, GEN_PMCON_3); - rtc_failed = reg8 & RTC_BATTERY_DEAD; - if (rtc_failed) { - reg8 &= ~RTC_BATTERY_DEAD; - pci_write_config8(dev, GEN_PMCON_3, reg8); - printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed); - } - -#if IS_ENABLED(CONFIG_CHROMEOS) && IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) - pch_cmos_init_preserve(rtc_failed); -#else - cmos_init(rtc_failed); -#endif -} static const struct reg_script pch_misc_init_script[] = { - /* Setup SLP signal assertion, SLP_S4=4s, SLP_S3=50ms */ - REG_PCI_RMW16(GEN_PMCON_3, ~((3 << 4)|(1 << 10)), - (1 << 3)|(1 << 11)|(1 << 12)), - /* Prepare sleep mode */ - REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN), /* Setup NMI on errors, disable SERR */ REG_IO_RMW8(0x61, ~0xf0, (1 << 2)), /* Disable NMI sources */ REG_IO_OR8(0x70, (1 << 7)), - /* Indicate DRAM init done for MRC */ - REG_PCI_OR8(GEN_PMCON_2, (1 << 7)), /* Enable BIOS updates outside of SMM */ REG_PCI_RMW8(0xdc, ~(1 << 5), 0), - /* Clear status bits to prevent unexpected wake */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x3310, 0x0000002f), - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x3f02, ~0x0000000f, 0), - /* Enable PCIe Releaxed Order */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x2314, (1 << 31) | (1 << 7)), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x1114, (1 << 15) | (1 << 14)), /* Setup SERIRQ, enable continuous mode */ REG_PCI_OR8(SERIRQ_CNTL, (1 << 7) | (1 << 6)), -#if !CONFIG_SERIRQ_CONTINUOUS_MODE +#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE) REG_PCI_RMW8(SERIRQ_CNTL, ~(1 << 6), 0), #endif REG_SCRIPT_END }; -/* Magic register settings for power management */ -static const struct reg_script pch_pm_init_script[] = { - REG_PCI_WRITE8(0xa9, 0x46), - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x232c, ~1, 0), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x1100, 0x0000c13f), - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x2320, ~0x60, 0x10), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3314, 0x00012fff), - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x3318, ~0x000f0330, 0x0dcf0400), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3324, 0x04000000), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3368, 0x00041400), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3388, 0x3f8ddbff), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33ac, 0x00007001), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33b0, 0x00181900), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33c0, 0x00060A00), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33d0, 0x06200840), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a28, 0x01010101), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a2c, 0x040c0404), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a9c, 0x9000000a), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b1c, 0x03808033), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b34, 0x80000009), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3348, 0x022ddfff), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x334c, 0x00000001), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3358, 0x0001c000), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3380, 0x3f8ddbff), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3384, 0x0001c7e1), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x338c, 0x0001c7e1), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3398, 0x0001c000), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33a8, 0x00181900), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33dc, 0x00080000), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33e0, 0x00000001), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a20, 0x0000040c), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a24, 0x01010101), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a30, 0x01010101), - REG_PCI_RMW32(0xac, ~0x00200000, 0), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x0410, 0x00000003), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x2618, 0x08000000), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x2300, 0x00000002), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x2600, 0x00000008), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x33b4, 0x00007001), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3350, 0x022ddfff), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3354, 0x00000001), - /* Power Optimizer */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x33d4, 0x08000000), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x33c8, 0x08000080), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b10, 0x0000883c), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b14, 0x1e0a4616), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b24, 0x40000005), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x2b20, 0x0005db01), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a80, 0x05145005), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x3a84, 0x00001005), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x33d4, 0x2fff2fb1), - REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x33c8, 0x00008000), - REG_SCRIPT_END -}; - -static void pch_enable_mphy(void) -{ - u32 gpio71_native = gpio_is_native(71); - u32 data_and = 0xffffffff; - u32 data_or = (1 << 14) | (1 << 13) | (1 << 12); - - if (gpio71_native) { - data_or |= (1 << 0); - if (pch_is_wpt()) { - data_and &= ~((1 << 7) | (1 << 6) | (1 << 3)); - data_or |= (1 << 5) | (1 << 4); - - if (pch_is_wpt_ulx()) { - /* Check if SATA and USB3 MPHY are enabled */ - u32 strap19 = pch_read_soft_strap(19); - strap19 &= ((1 << 31) | (1 << 30)); - strap19 >>= 30; - if (strap19 == 3) { - data_or |= (1 << 3); - printk(BIOS_DEBUG, "Enable ULX MPHY PG " - "control in single domain\n"); - } else if (strap19 == 0) { - printk(BIOS_DEBUG, "Enable ULX MPHY PG " - "control in split domains\n"); - } else { - printk(BIOS_DEBUG, "Invalid PCH Soft " - "Strap 19 configuration\n"); - } - } else { - data_or |= (1 << 3); - } - } - } - - pch_iobp_update(0xCF000000, data_and, data_or); -} - -static void pch_init_deep_sx(struct device *dev) -{ - config_t *config = dev->chip_info; - - if (config->deep_sx_enable_ac) { - RCBA32_OR(DEEP_S3_POL, DEEP_S3_EN_AC); - RCBA32_OR(DEEP_S5_POL, DEEP_S5_EN_AC); - } - - if (config->deep_sx_enable_dc) { - RCBA32_OR(DEEP_S3_POL, DEEP_S3_EN_DC); - RCBA32_OR(DEEP_S5_POL, DEEP_S5_EN_DC); - } - - if (config->deep_sx_enable_ac || config->deep_sx_enable_dc) - RCBA32_OR(DEEP_SX_CONFIG, - DEEP_SX_WAKE_PIN_EN | DEEP_SX_GP27_PIN_EN); -} - -/* Power Management init */ -static void pch_pm_init(struct device *dev) -{ - printk(BIOS_DEBUG, "PCH PM init\n"); - - pch_init_deep_sx(dev); - - pch_enable_mphy(); - - reg_script_run_on_dev(dev, pch_pm_init_script); - - if (pch_is_wpt()) { - RCBA32_OR(0x33e0, (1 << 4) | (1 << 1)); - RCBA32_OR(0x2b1c, (1 << 22) | (1 << 14) | (1 << 13)); - RCBA32(0x33e4) = 0x16bf0002; - RCBA32_OR(0x33e4, 0x1); - } - - pch_iobp_update(0xCA000000, ~0UL, 0x00000009); - - /* Set RCBA 0x2b1c[29]=1 if DSP disabled */ - if (RCBA32(FD) & PCH_DISABLE_ADSPD) - RCBA32_OR(0x2b1c, (1 << 29)); - -} - -static void pch_cg_init(device_t dev) -{ - u32 reg32; - u16 reg16; - - /* DMI */ - RCBA32_OR(0x2234, 0xf); - - reg16 = pci_read_config16(dev, GEN_PMCON_1); - reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */ - if (pch_is_wpt()) - reg16 &= ~(1 << 11); - else - reg16 |= (1 << 11); - reg16 |= (1 << 5) | (1 << 6) | (1 << 7) | (1 << 12); - reg16 |= (1 << 2); // PCI CLKRUN# Enable - pci_write_config16(dev, GEN_PMCON_1, reg16); - - /* - * RCBA + 0x2614[27:25,14:13,10,8] = 101,11,1,1 - * RCBA + 0x2614[23:16] = 0x20 - * RCBA + 0x2614[30:28] = 0x0 - * RCBA + 0x2614[26] = 1 (IF 0:2.0@0x08 >= 0x0b) - */ - RCBA32_AND_OR(0x2614, ~0x64ff0000, 0x0a206500); - - /* Check for 0:2.0@0x08 >= 0x0b */ - if (pch_is_wpt() || pci_read_config8(SA_DEV_IGD, 0x8) >= 0x0b) - RCBA32_OR(0x2614, (1 << 26)); - - RCBA32_OR(0x900, 0x0000031f); - - reg32 = RCBA32(CG); - if (RCBA32(0x3454) & (1 << 4)) - reg32 &= ~(1 << 29); // LPC Dynamic - else - reg32 |= (1 << 29); // LPC Dynamic - reg32 |= (1 << 31); // LP LPC - reg32 |= (1 << 30); // LP BLA - if (RCBA32(0x3454) & (1 << 4)) - reg32 &= ~(1 << 29); - else - reg32 |= (1 << 29); - reg32 |= (1 << 28); // GPIO Dynamic - reg32 |= (1 << 27); // HPET Dynamic - reg32 |= (1 << 26); // Generic Platform Event Clock - if (RCBA32(BUC) & PCH_DISABLE_GBE) - reg32 |= (1 << 23); // GbE Static - if (RCBA32(FD) & PCH_DISABLE_HD_AUDIO) - reg32 |= (1 << 21); // HDA Static - reg32 |= (1 << 22); // HDA Dynamic - RCBA32(CG) = reg32; - - /* PCH-LP LPC */ - if (pch_is_wpt()) - RCBA32_AND_OR(0x3434, ~0x1f, 0x17); - else - RCBA32_OR(0x3434, 0x7); - - /* SPI */ - RCBA32_OR(0x38c0, 0x3c07); - - pch_iobp_update(0xCE00C000, ~1UL, 0x00000000); -} - -static void pch_set_acpi_mode(void) -{ -#if CONFIG_HAVE_SMI_HANDLER - if (!acpi_is_wakeup_s3()) { - printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n"); - outb(APM_CNT_ACPI_DISABLE, APM_CNT); - printk(BIOS_DEBUG, "done.\n"); - } -#endif /* CONFIG_HAVE_SMI_HANDLER */ -} - static void lpc_init(struct device *dev) { /* Legacy initialization */ isa_dma_init(); - pch_rtc_init(dev); reg_script_run_on_dev(dev, pch_misc_init_script); /* Interrupt configuration */ @@ -470,39 +166,25 @@ static void lpc_init(struct device *dev) pch_pirq_init(dev); setup_i8259(); i8259_configure_irq_trigger(9, 1); - - /* Initialize power management */ - pch_power_options(dev); - pch_pm_init(dev); - pch_cg_init(dev); - - pch_set_acpi_mode(); } static void pch_lpc_add_mmio_resources(device_t dev) { u32 reg; struct resource *res; - const u32 default_decode_base = IO_APIC_ADDR; - /* - * Just report all resources from IO-APIC base to 4GiB. Don't mark - * them reserved as that may upset the OS if this range is marked - * as reserved in the e820. + * As per the BWG, Chapter 5.9.1. "PCH BIOS component will reserve + * certain memory range as reserved range for BIOS usage. + * For this SOC, the range will be from 0FD000000h till FE7FFFFFh" + * Hence, use FD000000h as PCR_BASE */ - res = new_resource(dev, OIC); + const u32 default_decode_base = PCH_PCR_BASE_ADDRESS; + + res = new_resource(dev, PCI_BASE_ADDRESS_0); res->base = default_decode_base; res->size = 0 - default_decode_base; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - - /* RCBA */ - if (RCBA_BASE_ADDRESS < default_decode_base) { - res = new_resource(dev, RCBA); - res->base = RCBA_BASE_ADDRESS; - res->size = 16 * 1024; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED | IORESOURCE_RESERVE; - } + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; /* Check LPC Memory Decode register. */ reg = pci_read_config32(dev, LGMR); @@ -513,7 +195,7 @@ static void pch_lpc_add_mmio_resources(device_t dev) res->base = reg; res->size = 16 * 1024; res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED | IORESOURCE_RESERVE; + IORESOURCE_FIXED | IORESOURCE_RESERVE; } } } @@ -558,7 +240,7 @@ static void pch_lpc_add_gen_io_resources(device_t dev, int reg_value, int index) { /* * Check if the register is enabled. If so and the base exceeds the - * device's default claim range add the resource. + * device's deafult claim range add the resoure. */ if (reg_value & 1) { u16 base = reg_value & 0xfffc; @@ -578,13 +260,6 @@ static void pch_lpc_add_io_resources(device_t dev) res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER; res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - /* GPIOBASE */ - pch_lpc_add_io_resource(dev, GPIO_BASE_ADDRESS, - GPIO_BASE_SIZE, GPIO_BASE); - - /* PMBASE */ - pch_lpc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, PMBASE); - /* LPC Generic IO Decode range. */ pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC); pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC); @@ -611,55 +286,22 @@ static void pch_lpc_read_resources(device_t dev) memset(gnvs, 0, sizeof(global_nvs_t)); } -static void southcluster_inject_dsdt(void) -{ - global_nvs_t *gnvs; - - gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); - if (!gnvs) { - gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof (*gnvs)); - if (gnvs) - memset(gnvs, 0, sizeof(*gnvs)); - } - - if (gnvs) { - memset(gnvs, 0, sizeof(*gnvs)); - acpi_create_gnvs(gnvs); - acpi_save_gnvs((unsigned long)gnvs); - /* And tell SMI about it */ - smm_setup_structures(gnvs, NULL, NULL); - - /* Add it to DSDT. */ - acpigen_write_scope("\\"); - acpigen_write_name_dword("NVSA", (u32) gnvs); - acpigen_pop_len(); - } -} - static struct device_operations device_ops = { .read_resources = &pch_lpc_read_resources, .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, .acpi_inject_dsdt_generator = southcluster_inject_dsdt, - .write_acpi_tables = acpi_write_hpet, + .write_acpi_tables = southcluster_write_acpi_tables, .init = &lpc_init, - .scan_bus = &scan_static_bus, - .ops_pci = &broadwell_pci_ops, + .scan_bus = &scan_lpc_bus, + .ops_pci = &soc_pci_ops, }; static const unsigned short pci_device_ids[] = { - PCH_LPT_LP_SAMPLE, - PCH_LPT_LP_PREMIUM, - PCH_LPT_LP_MAINSTREAM, - PCH_LPT_LP_VALUE, - PCH_WPT_HSW_U_SAMPLE, - PCH_WPT_BDW_U_SAMPLE, - PCH_WPT_BDW_U_PREMIUM, - PCH_WPT_BDW_U_BASE, - PCH_WPT_BDW_Y_SAMPLE, - PCH_WPT_BDW_Y_PREMIUM, - PCH_WPT_BDW_Y_BASE, - PCH_WPT_BDW_H, + PCH_SPT_LP_SAMPLE, + PCH_SPT_LP_U_BASE, + PCH_SPT_LP_U_PREMIUM, + PCH_SPT_LP_Y_PREMIUM, 0 }; diff --git a/src/soc/intel/skylake/me.c b/src/soc/intel/skylake/me.c deleted file mode 100644 index 3cac120ecb..0000000000 --- a/src/soc/intel/skylake/me.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * This is a ramstage driver for the Intel Management Engine found in the - * southbridge. It handles the required boot-time messages over the - * MMIO-based Management Engine Interface to tell the ME that the BIOS is - * finished with POST. Additional messages are defined for debug but are - * not used unless the console loglevel is high enough. - */ - -#include <arch/acpi.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_def.h> -#include <string.h> -#include <delay.h> -#include <elog.h> -#include <soc/me.h> -#include <soc/lpc.h> -#include <soc/pch.h> -#include <soc/pci_devs.h> -#include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/intel/broadwell/chip.h> - -#if CONFIG_CHROMEOS -#include <vendorcode/google/chromeos/chromeos.h> -#include <vendorcode/google/chromeos/gnvs.h> -#endif - -/* Path that the BIOS should take based on ME state */ -static const char *me_bios_path_values[] = { - [ME_NORMAL_BIOS_PATH] = "Normal", - [ME_S3WAKE_BIOS_PATH] = "S3 Wake", - [ME_ERROR_BIOS_PATH] = "Error", - [ME_RECOVERY_BIOS_PATH] = "Recovery", - [ME_DISABLE_BIOS_PATH] = "Disable", - [ME_FIRMWARE_UPDATE_BIOS_PATH] = "Firmware Update", -}; - -/* MMIO base address for MEI interface */ -static u8 *mei_base_address; - -#if CONFIG_DEBUG_INTEL_ME -static void mei_dump(void *ptr, int dword, int offset, const char *type) -{ - struct mei_csr *csr; - - printk(BIOS_SPEW, "%-9s[%02x] : ", type, offset); - - switch (offset) { - case MEI_H_CSR: - case MEI_ME_CSR_HA: - csr = ptr; - if (!csr) { - printk(BIOS_SPEW, "ERROR: 0x%08x\n", dword); - break; - } - printk(BIOS_SPEW, "cbd=%u cbrp=%02u cbwp=%02u ready=%u " - "reset=%u ig=%u is=%u ie=%u\n", csr->buffer_depth, - csr->buffer_read_ptr, csr->buffer_write_ptr, - csr->ready, csr->reset, csr->interrupt_generate, - csr->interrupt_status, csr->interrupt_enable); - break; - case MEI_ME_CB_RW: - case MEI_H_CB_WW: - printk(BIOS_SPEW, "CB: 0x%08x\n", dword); - break; - default: - printk(BIOS_SPEW, "0x%08x\n", offset); - break; - } -} -#else -# define mei_dump(ptr,dword,offset,type) do {} while (0) -#endif - -/* - * ME/MEI access helpers using memcpy to avoid aliasing. - */ - -static inline void mei_read_dword_ptr(void *ptr, int offset) -{ - u32 dword = read32(mei_base_address + offset); - memcpy(ptr, &dword, sizeof(dword)); - mei_dump(ptr, dword, offset, "READ"); -} - -static inline void mei_write_dword_ptr(void *ptr, int offset) -{ - u32 dword = 0; - memcpy(&dword, ptr, sizeof(dword)); - write32(mei_base_address + offset, dword); - mei_dump(ptr, dword, offset, "WRITE"); -} - -static inline void pci_read_dword_ptr(device_t dev, void *ptr, int offset) -{ - u32 dword = pci_read_config32(dev, offset); - memcpy(ptr, &dword, sizeof(dword)); - mei_dump(ptr, dword, offset, "PCI READ"); -} - -static inline void read_host_csr(struct mei_csr *csr) -{ - mei_read_dword_ptr(csr, MEI_H_CSR); -} - -static inline void write_host_csr(struct mei_csr *csr) -{ - mei_write_dword_ptr(csr, MEI_H_CSR); -} - -static inline void read_me_csr(struct mei_csr *csr) -{ - mei_read_dword_ptr(csr, MEI_ME_CSR_HA); -} - -static inline void write_cb(u32 dword) -{ - write32(mei_base_address + MEI_H_CB_WW, dword); - mei_dump(NULL, dword, MEI_H_CB_WW, "WRITE"); -} - -static inline u32 read_cb(void) -{ - u32 dword = read32(mei_base_address + MEI_ME_CB_RW); - mei_dump(NULL, dword, MEI_ME_CB_RW, "READ"); - return dword; -} - -/* Wait for ME ready bit to be asserted */ -static int mei_wait_for_me_ready(void) -{ - struct mei_csr me; - unsigned try = ME_RETRY; - - while (try--) { - read_me_csr(&me); - if (me.ready) - return 0; - udelay(ME_DELAY); - } - - printk(BIOS_ERR, "ME: failed to become ready\n"); - return -1; -} - -static void mei_reset(void) -{ - struct mei_csr host; - - if (mei_wait_for_me_ready() < 0) - return; - - /* Reset host and ME circular buffers for next message */ - read_host_csr(&host); - host.reset = 1; - host.interrupt_generate = 1; - write_host_csr(&host); - - if (mei_wait_for_me_ready() < 0) - return; - - /* Re-init and indicate host is ready */ - read_host_csr(&host); - host.interrupt_generate = 1; - host.ready = 1; - host.reset = 0; - write_host_csr(&host); -} - -static int mei_send_packet(struct mei_header *mei, void *req_data) -{ - struct mei_csr host; - unsigned ndata, n; - u32 *data; - - /* Number of dwords to write */ - ndata = mei->length >> 2; - - /* Pad non-dword aligned request message length */ - if (mei->length & 3) - ndata++; - if (!ndata) { - printk(BIOS_DEBUG, "ME: request has no data\n"); - return -1; - } - ndata++; /* Add MEI header */ - - /* - * Make sure there is still room left in the circular buffer. - * Reset the buffer pointers if the requested message will not fit. - */ - read_host_csr(&host); - if ((host.buffer_depth - host.buffer_write_ptr) < ndata) { - printk(BIOS_ERR, "ME: circular buffer full, resetting...\n"); - mei_reset(); - read_host_csr(&host); - } - - /* Ensure the requested length will fit in the circular buffer. */ - if ((host.buffer_depth - host.buffer_write_ptr) < ndata) { - printk(BIOS_ERR, "ME: message (%u) too large for buffer (%u)\n", - ndata + 2, host.buffer_depth); - return -1; - } - - /* Write MEI header */ - mei_write_dword_ptr(mei, MEI_H_CB_WW); - ndata--; - - /* Write message data */ - data = req_data; - for (n = 0; n < ndata; ++n) - write_cb(*data++); - - /* Generate interrupt to the ME */ - read_host_csr(&host); - host.interrupt_generate = 1; - write_host_csr(&host); - - /* Make sure ME is ready after sending request data */ - return mei_wait_for_me_ready(); -} - -static int mei_send_data(u8 me_address, u8 host_address, - void *req_data, int req_bytes) -{ - struct mei_header header = { - .client_address = me_address, - .host_address = host_address, - }; - struct mei_csr host; - int current = 0; - u8 *req_ptr = req_data; - - while (!header.is_complete) { - int remain = req_bytes - current; - int buf_len; - - read_host_csr(&host); - buf_len = host.buffer_depth - host.buffer_write_ptr; - - if (buf_len > remain) { - /* Send all remaining data as final message */ - header.length = req_bytes - current; - header.is_complete = 1; - } else { - /* Send as much data as the buffer can hold */ - header.length = buf_len; - } - - mei_send_packet(&header, req_ptr); - - req_ptr += header.length; - current += header.length; - } - - return 0; -} - -static int mei_send_header(u8 me_address, u8 host_address, - void *header, int header_len, int complete) -{ - struct mei_header mei = { - .client_address = me_address, - .host_address = host_address, - .length = header_len, - .is_complete = complete, - }; - return mei_send_packet(&mei, header); -} - -static int mei_recv_msg(void *header, int header_bytes, - void *rsp_data, int rsp_bytes) -{ - struct mei_header mei_rsp; - struct mei_csr me, host; - unsigned ndata, n; - unsigned expected; - u32 *data; - - /* Total number of dwords to read from circular buffer */ - expected = (rsp_bytes + sizeof(mei_rsp) + header_bytes) >> 2; - if (rsp_bytes & 3) - expected++; - - if (mei_wait_for_me_ready() < 0) - return -1; - - /* - * The interrupt status bit does not appear to indicate that the - * message has actually been received. Instead we wait until the - * expected number of dwords are present in the circular buffer. - */ - for (n = ME_RETRY; n; --n) { - read_me_csr(&me); - if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected) - break; - udelay(ME_DELAY); - } - if (!n) { - printk(BIOS_ERR, "ME: timeout waiting for data: expected " - "%u, available %u\n", expected, - me.buffer_write_ptr - me.buffer_read_ptr); - return -1; - } - - /* Read and verify MEI response header from the ME */ - mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW); - if (!mei_rsp.is_complete) { - printk(BIOS_ERR, "ME: response is not complete\n"); - return -1; - } - - /* Handle non-dword responses and expect at least the header */ - ndata = mei_rsp.length >> 2; - if (mei_rsp.length & 3) - ndata++; - if (ndata != (expected - 1)) { - printk(BIOS_ERR, "ME: response is missing data %d != %d\n", - ndata, (expected - 1)); - return -1; - } - - /* Read response header from the ME */ - data = header; - for (n = 0; n < (header_bytes >> 2); ++n) - *data++ = read_cb(); - ndata -= header_bytes >> 2; - - /* Make sure caller passed a buffer with enough space */ - if (ndata != (rsp_bytes >> 2)) { - printk(BIOS_ERR, "ME: not enough room in response buffer: " - "%u != %u\n", ndata, rsp_bytes >> 2); - return -1; - } - - /* Read response data from the circular buffer */ - data = rsp_data; - for (n = 0; n < ndata; ++n) - *data++ = read_cb(); - - /* Tell the ME that we have consumed the response */ - read_host_csr(&host); - host.interrupt_status = 1; - host.interrupt_generate = 1; - write_host_csr(&host); - - return mei_wait_for_me_ready(); -} - -static inline int mei_sendrecv_mkhi(struct mkhi_header *mkhi, - void *req_data, int req_bytes, - void *rsp_data, int rsp_bytes) -{ - struct mkhi_header mkhi_rsp; - - /* Send header */ - if (mei_send_header(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS, - mkhi, sizeof(*mkhi), req_bytes ? 0 : 1) < 0) - return -1; - - /* Send data if available */ - if (req_bytes && mei_send_data(MEI_ADDRESS_MKHI, MEI_HOST_ADDRESS, - req_data, req_bytes) < 0) - return -1; - - /* Return now if no response expected */ - if (!rsp_bytes) - return 0; - - /* Read header and data */ - if (mei_recv_msg(&mkhi_rsp, sizeof(mkhi_rsp), - rsp_data, rsp_bytes) < 0) - return -1; - - if (!mkhi_rsp.is_response || - mkhi->group_id != mkhi_rsp.group_id || - mkhi->command != mkhi_rsp.command) { - printk(BIOS_ERR, "ME: invalid response, group %u ?= %u," - "command %u ?= %u, is_response %u\n", mkhi->group_id, - mkhi_rsp.group_id, mkhi->command, mkhi_rsp.command, - mkhi_rsp.is_response); - return -1; - } - - return 0; -} - -static inline int mei_sendrecv_icc(struct icc_header *icc, - void *req_data, int req_bytes, - void *rsp_data, int rsp_bytes) -{ - struct icc_header icc_rsp; - - /* Send header */ - if (mei_send_header(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS, - icc, sizeof(*icc), req_bytes ? 0 : 1) < 0) - return -1; - - /* Send data if available */ - if (req_bytes && mei_send_data(MEI_ADDRESS_ICC, MEI_HOST_ADDRESS, - req_data, req_bytes) < 0) - return -1; - - /* Read header and data, if needed */ - if (rsp_bytes && mei_recv_msg(&icc_rsp, sizeof(icc_rsp), - rsp_data, rsp_bytes) < 0) - return -1; - - return 0; -} - -/* - * mbp give up routine. This path is taken if hfs.mpb_rdy is 0 or the read - * state machine on the BIOS end doesn't match the ME's state machine. - */ -static void intel_me_mbp_give_up(device_t dev) -{ - struct mei_csr csr; - - pci_write_config32(dev, PCI_ME_H_GS2, PCI_ME_MBP_GIVE_UP); - - read_host_csr(&csr); - csr.reset = 1; - csr.interrupt_generate = 1; - write_host_csr(&csr); -} - -/* - * mbp clear routine. This will wait for the ME to indicate that - * the MBP has been read and cleared. - */ -static void intel_me_mbp_clear(device_t dev) -{ - int count; - struct me_hfs2 hfs2; - - /* Wait for the mbp_cleared indicator */ - for (count = ME_RETRY; count > 0; --count) { - pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); - if (hfs2.mbp_cleared) - break; - udelay(ME_DELAY); - } - - if (count == 0) { - printk(BIOS_WARNING, "ME: Timeout waiting for mbp_cleared\n"); - intel_me_mbp_give_up(dev); - } else { - printk(BIOS_INFO, "ME: MBP cleared\n"); - } -} - -static void me_print_fw_version(mbp_fw_version_name *vers_name) -{ - if (!vers_name) { - printk(BIOS_ERR, "ME: mbp missing version report\n"); - return; - } - - printk(BIOS_DEBUG, "ME: found version %d.%d.%d.%d\n", - vers_name->major_version, vers_name->minor_version, - vers_name->hotfix_version, vers_name->build_version); -} - -#if CONFIG_DEBUG_INTEL_ME -static inline void print_cap(const char *name, int state) -{ - printk(BIOS_DEBUG, "ME Capability: %-41s : %sabled\n", - name, state ? " en" : "dis"); -} - -/* Get ME Firmware Capabilities */ -static int mkhi_get_fwcaps(mbp_mefwcaps *cap) -{ - u32 rule_id = 0; - struct me_fwcaps cap_msg; - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_FWCAPS, - .command = MKHI_FWCAPS_GET_RULE, - }; - - /* Send request and wait for response */ - if (mei_sendrecv_mkhi(&mkhi, &rule_id, sizeof(u32), - &cap_msg, sizeof(cap_msg)) < 0) { - printk(BIOS_ERR, "ME: GET FWCAPS message failed\n"); - return -1; - } - *cap = cap_msg.caps_sku; - return 0; -} - -/* Get ME Firmware Capabilities */ -static void me_print_fwcaps(mbp_mefwcaps *cap) -{ - mbp_mefwcaps local_caps; - if (!cap) { - cap = &local_caps; - printk(BIOS_ERR, "ME: mbp missing fwcaps report\n"); - if (mkhi_get_fwcaps(cap)) - return; - } - - print_cap("Full Network manageability", cap->full_net); - print_cap("Regular Network manageability", cap->std_net); - print_cap("Manageability", cap->manageability); - print_cap("IntelR Anti-Theft (AT)", cap->intel_at); - print_cap("IntelR Capability Licensing Service (CLS)", cap->intel_cls); - print_cap("IntelR Power Sharing Technology (MPC)", cap->intel_mpc); - print_cap("ICC Over Clocking", cap->icc_over_clocking); - print_cap("Protected Audio Video Path (PAVP)", cap->pavp); - print_cap("IPV6", cap->ipv6); - print_cap("KVM Remote Control (KVM)", cap->kvm); - print_cap("Outbreak Containment Heuristic (OCH)", cap->och); - print_cap("Virtual LAN (VLAN)", cap->vlan); - print_cap("TLS", cap->tls); - print_cap("Wireless LAN (WLAN)", cap->wlan); -} -#endif - -/* Send END OF POST message to the ME */ -static int mkhi_end_of_post(void) -{ - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_GEN, - .command = MKHI_END_OF_POST, - }; - u32 eop_ack; - - /* Send request and wait for response */ - if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &eop_ack, sizeof(eop_ack)) < 0) { - printk(BIOS_ERR, "ME: END OF POST message failed\n"); - return -1; - } - - printk(BIOS_INFO, "ME: END OF POST message successful (%d)\n", eop_ack); - return 0; -} - -/* Send END OF POST message to the ME */ -static int mkhi_end_of_post_noack(void) -{ - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_GEN, - .command = MKHI_END_OF_POST_NOACK, - }; - - /* Send request, do not wait for response */ - if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) { - printk(BIOS_ERR, "ME: END OF POST NOACK message failed\n"); - return -1; - } - - printk(BIOS_INFO, "ME: END OF POST NOACK message successful\n"); - return 0; -} - -/* Send HMRFPO LOCK message to the ME */ -static int mkhi_hmrfpo_lock(void) -{ - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_HMRFPO, - .command = MKHI_HMRFPO_LOCK, - }; - u32 ack; - - /* Send request and wait for response */ - if (mei_sendrecv_mkhi(&mkhi, NULL, 0, &ack, sizeof(ack)) < 0) { - printk(BIOS_ERR, "ME: HMRFPO LOCK message failed\n"); - return -1; - } - - printk(BIOS_INFO, "ME: HMRPFO LOCK message successful (%d)\n", ack); - return 0; -} - -/* Send HMRFPO LOCK message to the ME, do not wait for response */ -static int mkhi_hmrfpo_lock_noack(void) -{ - struct mkhi_header mkhi = { - .group_id = MKHI_GROUP_ID_HMRFPO, - .command = MKHI_HMRFPO_LOCK_NOACK, - }; - - /* Send request, do not wait for response */ - if (mei_sendrecv_mkhi(&mkhi, NULL, 0, NULL, 0) < 0) { - printk(BIOS_ERR, "ME: HMRFPO LOCK NOACK message failed\n"); - return -1; - } - - printk(BIOS_INFO, "ME: HMRPFO LOCK NOACK message successful\n"); - return 0; -} - -static void intel_me_finalize(device_t dev) -{ - u32 reg32; - - /* S3 path will have hidden this device already */ - if (!mei_base_address || mei_base_address == (u8*) 0xfffffff0) - return; - - /* Make sure IO is disabled */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~(PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | PCI_COMMAND_IO); - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Hide the PCI device */ - RCBA32_OR(FD2, PCH_DISABLE_MEI1); - RCBA32(FD2); -} - -static int me_icc_set_clock_enables(u32 mask) -{ - struct icc_clock_enables_msg clk = { - .clock_enables = 0, /* Turn off specified clocks */ - .clock_mask = mask, - .no_response = 1, /* Do not expect response */ - }; - struct icc_header icc = { - .api_version = ICC_API_VERSION_LYNXPOINT, - .icc_command = ICC_SET_CLOCK_ENABLES, - .length = sizeof(clk), - }; - - /* Send request and wait for response */ - if (mei_sendrecv_icc(&icc, &clk, sizeof(clk), NULL, 0) < 0) { - printk(BIOS_ERR, "ME: ICC SET CLOCK ENABLES message failed\n"); - return -1; - } else { - printk(BIOS_INFO, "ME: ICC SET CLOCK ENABLES 0x%08x\n", mask); - } - - return 0; -} - -/* Determine the path that we should take based on ME status */ -static me_bios_path intel_me_path(device_t dev) -{ - me_bios_path path = ME_DISABLE_BIOS_PATH; - struct me_hfs hfs; - struct me_hfs2 hfs2; - - /* Check and dump status */ - intel_me_status(); - - pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); - pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); - - /* Check Current Working State */ - switch (hfs.working_state) { - case ME_HFS_CWS_NORMAL: - path = ME_NORMAL_BIOS_PATH; - break; - case ME_HFS_CWS_REC: - path = ME_RECOVERY_BIOS_PATH; - break; - default: - path = ME_DISABLE_BIOS_PATH; - break; - } - - /* Check Current Operation Mode */ - switch (hfs.operation_mode) { - case ME_HFS_MODE_NORMAL: - break; - case ME_HFS_MODE_DEBUG: - case ME_HFS_MODE_DIS: - case ME_HFS_MODE_OVER_JMPR: - case ME_HFS_MODE_OVER_MEI: - default: - path = ME_DISABLE_BIOS_PATH; - break; - } - - /* Check for any error code and valid firmware and MBP */ - if (hfs.error_code || hfs.fpt_bad) - path = ME_ERROR_BIOS_PATH; - - /* Check if the MBP is ready */ - if (!hfs2.mbp_rdy) { - printk(BIOS_CRIT, "%s: mbp is not ready!\n", - __FUNCTION__); - path = ME_ERROR_BIOS_PATH; - } - -#if CONFIG_ELOG - if (path != ME_NORMAL_BIOS_PATH) { - struct elog_event_data_me_extended data = { - .current_working_state = hfs.working_state, - .operation_state = hfs.operation_state, - .operation_mode = hfs.operation_mode, - .error_code = hfs.error_code, - .progress_code = hfs2.progress_code, - .current_pmevent = hfs2.current_pmevent, - .current_state = hfs2.current_state, - }; - elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, path); - elog_add_event_raw(ELOG_TYPE_MANAGEMENT_ENGINE_EXT, - &data, sizeof(data)); - } -#endif - - return path; -} - -/* Prepare ME for MEI messages */ -static int intel_mei_setup(device_t dev) -{ - struct resource *res; - struct mei_csr host; - u32 reg32; - - /* Find the MMIO base for the ME interface */ - res = find_resource(dev, PCI_BASE_ADDRESS_0); - if (!res || res->base == 0 || res->size == 0) { - printk(BIOS_DEBUG, "ME: MEI resource not present!\n"); - return -1; - } - mei_base_address = res2mmio(res, 0, 0); - - /* Ensure Memory and Bus Master bits are set */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Clean up status for next message */ - read_host_csr(&host); - host.interrupt_generate = 1; - host.ready = 1; - host.reset = 0; - write_host_csr(&host); - - return 0; -} - -/* Read the Extend register hash of ME firmware */ -static int intel_me_extend_valid(device_t dev) -{ - struct me_heres status; - u32 extend[8] = {0}; - int i, count = 0; - - pci_read_dword_ptr(dev, &status, PCI_ME_HERES); - if (!status.extend_feature_present) { - printk(BIOS_ERR, "ME: Extend Feature not present\n"); - return -1; - } - - if (!status.extend_reg_valid) { - printk(BIOS_ERR, "ME: Extend Register not valid\n"); - return -1; - } - - switch (status.extend_reg_algorithm) { - case PCI_ME_EXT_SHA1: - count = 5; - printk(BIOS_DEBUG, "ME: Extend SHA-1: "); - break; - case PCI_ME_EXT_SHA256: - count = 8; - printk(BIOS_DEBUG, "ME: Extend SHA-256: "); - break; - default: - printk(BIOS_ERR, "ME: Extend Algorithm %d unknown\n", - status.extend_reg_algorithm); - return -1; - } - - for (i = 0; i < count; ++i) { - extend[i] = pci_read_config32(dev, PCI_ME_HER(i)); - printk(BIOS_DEBUG, "%08x", extend[i]); - } - printk(BIOS_DEBUG, "\n"); - -#if CONFIG_CHROMEOS - /* Save hash in NVS for the OS to verify */ - chromeos_set_me_hash(extend, count); -#endif - - return 0; -} - -static void intel_me_print_mbp(me_bios_payload *mbp_data) -{ - me_print_fw_version(mbp_data->fw_version_name); - -#if CONFIG_DEBUG_INTEL_ME - me_print_fwcaps(mbp_data->fw_capabilities); -#endif - - if (mbp_data->plat_time) { - printk(BIOS_DEBUG, "ME: Wake Event to ME Reset: %u ms\n", - mbp_data->plat_time->wake_event_mrst_time_ms); - printk(BIOS_DEBUG, "ME: ME Reset to Platform Reset: %u ms\n", - mbp_data->plat_time->mrst_pltrst_time_ms); - printk(BIOS_DEBUG, "ME: Platform Reset to CPU Reset: %u ms\n", - mbp_data->plat_time->pltrst_cpurst_time_ms); - } -} - -static u32 me_to_host_words_pending(void) -{ - struct mei_csr me; - read_me_csr(&me); - if (!me.ready) - return 0; - return (me.buffer_write_ptr - me.buffer_read_ptr) & - (me.buffer_depth - 1); -} - -struct mbp_payload { - mbp_header header; - u32 data[0]; -}; - -/* - * Read and print ME MBP data - * - * Return -1 to indicate a problem (give up) - * Return 0 to indicate success (send LOCK+EOP) - * Return 1 to indicate success (send LOCK+EOP with NOACK) - */ -static int intel_me_read_mbp(me_bios_payload *mbp_data, device_t dev) -{ - mbp_header mbp_hdr; - u32 me2host_pending; - struct mei_csr host; - struct me_hfs2 hfs2; - struct mbp_payload *mbp; - int i; - int ret = 0; - - pci_read_dword_ptr(dev, &hfs2, PCI_ME_HFS2); - - if (!hfs2.mbp_rdy) { - printk(BIOS_ERR, "ME: MBP not ready\n"); - intel_me_mbp_give_up(dev); - return -1; - } - - me2host_pending = me_to_host_words_pending(); - if (!me2host_pending) { - printk(BIOS_ERR, "ME: no mbp data!\n"); - intel_me_mbp_give_up(dev); - return -1; - } - - /* we know for sure that at least the header is there */ - mei_read_dword_ptr(&mbp_hdr, MEI_ME_CB_RW); - - if ((mbp_hdr.num_entries > (mbp_hdr.mbp_size / 2)) || - (me2host_pending < mbp_hdr.mbp_size)) { - printk(BIOS_ERR, "ME: mbp of %d entries, total size %d words" - " buffer contains %d words\n", - mbp_hdr.num_entries, mbp_hdr.mbp_size, - me2host_pending); - intel_me_mbp_give_up(dev); - return -1; - } - mbp = malloc(mbp_hdr.mbp_size * sizeof(u32)); - if (!mbp) { - intel_me_mbp_give_up(dev); - return -1; - } - - mbp->header = mbp_hdr; - me2host_pending--; - - i = 0; - while (i != me2host_pending) { - mei_read_dword_ptr(&mbp->data[i], MEI_ME_CB_RW); - i++; - } - - read_host_csr(&host); - - /* Check that read and write pointers are equal. */ - if (host.buffer_read_ptr != host.buffer_write_ptr) { - printk(BIOS_INFO, "ME: MBP Read/Write pointer mismatch\n"); - printk(BIOS_INFO, "ME: MBP Waiting for MBP cleared flag\n"); - - /* Tell ME that the host has finished reading the MBP. */ - host.interrupt_generate = 1; - host.reset = 0; - write_host_csr(&host); - - /* Wait for the mbp_cleared indicator. */ - intel_me_mbp_clear(dev); - } else { - /* Indicate NOACK messages should be used. */ - ret = 1; - } - - /* Dump out the MBP contents. */ -#if CONFIG_DEBUG_INTEL_ME - printk(BIOS_INFO, "ME MBP: Header: items: %d, size dw: %d\n", - mbp->header.num_entries, mbp->header.mbp_size); - for (i = 0; i < mbp->header.mbp_size - 1; i++) { - printk(BIOS_INFO, "ME MBP: %04x: 0x%08x\n", i, mbp->data[i]); - } -#endif - -#define ASSIGN_FIELD_PTR(field_,val_) \ - { \ - mbp_data->field_ = (typeof(mbp_data->field_))(void *)val_; \ - break; \ - } - - /* Setup the pointers in the me_bios_payload structure. */ - for (i = 0; i < mbp->header.mbp_size - 1;) { - mbp_item_header *item = (void *)&mbp->data[i]; - - switch(MBP_MAKE_IDENT(item->app_id, item->item_id)) { - case MBP_IDENT(KERNEL, FW_VER): - ASSIGN_FIELD_PTR(fw_version_name, &mbp->data[i+1]); - - case MBP_IDENT(ICC, PROFILE): - ASSIGN_FIELD_PTR(icc_profile, &mbp->data[i+1]); - - case MBP_IDENT(INTEL_AT, STATE): - ASSIGN_FIELD_PTR(at_state, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, FW_CAP): - ASSIGN_FIELD_PTR(fw_capabilities, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, ROM_BIST): - ASSIGN_FIELD_PTR(rom_bist_data, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, PLAT_KEY): - ASSIGN_FIELD_PTR(platform_key, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, FW_TYPE): - ASSIGN_FIELD_PTR(fw_plat_type, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, MFS_FAILURE): - ASSIGN_FIELD_PTR(mfsintegrity, &mbp->data[i+1]); - - case MBP_IDENT(KERNEL, PLAT_TIME): - ASSIGN_FIELD_PTR(plat_time, &mbp->data[i+1]); - - case MBP_IDENT(NFC, SUPPORT_DATA): - ASSIGN_FIELD_PTR(nfc_data, &mbp->data[i+1]); - } - i += item->length; - } - #undef ASSIGN_FIELD_PTR - - return ret; -} - -/* Check whether ME is present and do basic init */ -static void intel_me_init(device_t dev) -{ - config_t *config = dev->chip_info; - me_bios_path path = intel_me_path(dev); - me_bios_payload mbp_data; - int mbp_ret; - struct me_hfs hfs; - struct mei_csr csr; - - /* Do initial setup and determine the BIOS path */ - printk(BIOS_NOTICE, "ME: BIOS path: %s\n", me_bios_path_values[path]); - - if (path == ME_NORMAL_BIOS_PATH) { - /* Validate the extend register */ - intel_me_extend_valid(dev); -} - - memset(&mbp_data, 0, sizeof(mbp_data)); - - /* - * According to the ME9 BWG, BIOS is required to fetch MBP data in - * all boot flows except S3 Resume. - */ - - /* Prepare MEI MMIO interface */ - if (intel_mei_setup(dev) < 0) - return; - - /* Read ME MBP data */ - mbp_ret = intel_me_read_mbp(&mbp_data, dev); - if (mbp_ret < 0) - return; - intel_me_print_mbp(&mbp_data); - - /* Set clock enables according to devicetree */ - if (config && config->icc_clock_disable) - me_icc_set_clock_enables(config->icc_clock_disable); - - /* Make sure ME is in a mode that expects EOP */ - pci_read_dword_ptr(dev, &hfs, PCI_ME_HFS); - - /* Abort and leave device alone if not normal mode */ - if (hfs.fpt_bad || - hfs.working_state != ME_HFS_CWS_NORMAL || - hfs.operation_mode != ME_HFS_MODE_NORMAL) - return; - - if (mbp_ret) { - /* - * MBP Cleared wait is skipped, - * Do not expect ACK and reset when complete. - */ - - /* Send HMRFPO Lock command, no response */ - mkhi_hmrfpo_lock_noack(); - - /* Send END OF POST command, no response */ - mkhi_end_of_post_noack(); - - /* Assert reset and interrupt */ - read_host_csr(&csr); - csr.interrupt_generate = 1; - csr.reset = 1; - write_host_csr(&csr); - } else { - /* - * MBP Cleared wait was not skipped - */ - - /* Send HMRFPO LOCK command */ - mkhi_hmrfpo_lock(); - - /* Send EOP command so ME stops accepting other commands */ - mkhi_end_of_post(); - } -} - -static void intel_me_enable(device_t dev) -{ -#if CONFIG_HAVE_ACPI_RESUME - /* Avoid talking to the device in S3 path */ - if (acpi_slp_type == 3) { - dev->enabled = 0; - pch_disable_devfn(dev); - } -#endif -} - -static struct device_operations device_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .enable = &intel_me_enable, - .init = &intel_me_init, - .final = &intel_me_finalize, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c3a, /* Low Power */ - 0x9cba, /* WildcatPoint */ - 0 -}; - -static const struct pci_driver intel_me __pci_driver = { - .ops = &device_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/me_status.c b/src/soc/intel/skylake/me_status.c deleted file mode 100644 index 867a9a95d1..0000000000 --- a/src/soc/intel/skylake/me_status.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/io.h> -#include <console/console.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <stdlib.h> -#include <string.h> -#include <soc/pci_devs.h> -#include <soc/me.h> -#include <delay.h> - -static inline void me_read_dword_ptr(void *ptr, int offset) -{ - u32 dword = pci_read_config32(PCH_DEV_ME, offset); - memcpy(ptr, &dword, sizeof(dword)); -} - -#if (CONFIG_DEFAULT_CONSOLE_LOGLEVEL >= BIOS_DEBUG) - -/* HFS1[3:0] Current Working State Values */ -static const char *me_cws_values[] = { - [ME_HFS_CWS_RESET] = "Reset", - [ME_HFS_CWS_INIT] = "Initializing", - [ME_HFS_CWS_REC] = "Recovery", - [3] = "Unknown (3)", - [4] = "Unknown (4)", - [ME_HFS_CWS_NORMAL] = "Normal", - [ME_HFS_CWS_WAIT] = "Platform Disable Wait", - [ME_HFS_CWS_TRANS] = "OP State Transition", - [ME_HFS_CWS_INVALID] = "Invalid CPU Plugged In", - [9] = "Unknown (9)", - [10] = "Unknown (10)", - [11] = "Unknown (11)", - [12] = "Unknown (12)", - [13] = "Unknown (13)", - [14] = "Unknown (14)", - [15] = "Unknown (15)", -}; - -/* HFS1[8:6] Current Operation State Values */ -static const char *me_opstate_values[] = { - [ME_HFS_STATE_PREBOOT] = "Preboot", - [ME_HFS_STATE_M0_UMA] = "M0 with UMA", - [ME_HFS_STATE_M3] = "M3 without UMA", - [ME_HFS_STATE_M0] = "M0 without UMA", - [ME_HFS_STATE_BRINGUP] = "Bring up", - [ME_HFS_STATE_ERROR] = "M0 without UMA but with error" -}; - -/* HFS[19:16] Current Operation Mode Values */ -static const char *me_opmode_values[] = { - [ME_HFS_MODE_NORMAL] = "Normal", - [ME_HFS_MODE_DEBUG] = "Debug", - [ME_HFS_MODE_DIS] = "Soft Temporary Disable", - [ME_HFS_MODE_OVER_JMPR] = "Security Override via Jumper", - [ME_HFS_MODE_OVER_MEI] = "Security Override via MEI Message" -}; - -/* HFS[15:12] Error Code Values */ -static const char *me_error_values[] = { - [ME_HFS_ERROR_NONE] = "No Error", - [ME_HFS_ERROR_UNCAT] = "Uncategorized Failure", - [ME_HFS_ERROR_IMAGE] = "Image Failure", - [ME_HFS_ERROR_DEBUG] = "Debug Failure" -}; - -/* HFS2[31:28] ME Progress Code */ -static const char *me_progress_values[] = { - [ME_HFS2_PHASE_ROM] = "ROM Phase", - [ME_HFS2_PHASE_BUP] = "BUP Phase", - [ME_HFS2_PHASE_UKERNEL] = "uKernel Phase", - [ME_HFS2_PHASE_POLICY] = "Policy Module", - [ME_HFS2_PHASE_MODULE_LOAD] = "Module Loading", - [ME_HFS2_PHASE_UNKNOWN] = "Unknown", - [ME_HFS2_PHASE_HOST_COMM] = "Host Communication" -}; - -/* HFS2[27:24] Power Management Event */ -static const char *me_pmevent_values[] = { - [ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE] = - "Clean Moff->Mx wake", - [ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR] = - "Moff->Mx wake after an error", - [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET] = - "Clean global reset", - [ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR] = - "Global reset after an error", - [ME_HFS2_PMEVENT_CLEAN_ME_RESET] = - "Clean Intel ME reset", - [ME_HFS2_PMEVENT_ME_RESET_EXCEPTION] = - "Intel ME reset due to exception", - [ME_HFS2_PMEVENT_PSEUDO_ME_RESET] = - "Pseudo-global reset", - [ME_HFS2_PMEVENT_S0MO_SXM3] = - "S0/M0->Sx/M3", - [ME_HFS2_PMEVENT_SXM3_S0M0] = - "Sx/M3->S0/M0", - [ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET] = - "Non-power cycle reset", - [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3] = - "Power cycle reset through M3", - [ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF] = - "Power cycle reset through Moff", - [ME_HFS2_PMEVENT_SXMX_SXMOFF] = - "Sx/Mx->Sx/Moff" -}; - -/* Progress Code 0 states */ -static const char *me_progress_rom_values[] = { - [ME_HFS2_STATE_ROM_BEGIN] = "BEGIN", - [ME_HFS2_STATE_ROM_DISABLE] = "DISABLE" -}; - -/* Progress Code 1 states */ -static const char *me_progress_bup_values[] = { - [ME_HFS2_STATE_BUP_INIT] = - "Initialization starts", - [ME_HFS2_STATE_BUP_DIS_HOST_WAKE] = - "Disable the host wake event", - [ME_HFS2_STATE_BUP_FLOW_DET] = - "Flow determination start process", - [ME_HFS2_STATE_BUP_VSCC_ERR] = - "Error reading/matching the VSCC table in the descriptor", - [ME_HFS2_STATE_BUP_CHECK_STRAP] = - "Check to see if straps say ME DISABLED", - [ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT] = - "Timeout waiting for PWROK", - [ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP] = - "Possibly handle BUP manufacturing override strap", - [ME_HFS2_STATE_BUP_M3] = - "Bringup in M3", - [ME_HFS2_STATE_BUP_M0] = - "Bringup in M0", - [ME_HFS2_STATE_BUP_FLOW_DET_ERR] = - "Flow detection error", - [ME_HFS2_STATE_BUP_M3_CLK_ERR] = - "M3 clock switching error", - [ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING] = - "Host error - CPU reset timeout, DID timeout, memory missing", - [ME_HFS2_STATE_BUP_M3_KERN_LOAD] = - "M3 kernel load", - [ME_HFS2_STATE_BUP_T32_MISSING] = - "T34 missing - cannot program ICC", - [ME_HFS2_STATE_BUP_WAIT_DID] = - "Waiting for DID BIOS message", - [ME_HFS2_STATE_BUP_WAIT_DID_FAIL] = - "Waiting for DID BIOS message failure", - [ME_HFS2_STATE_BUP_DID_NO_FAIL] = - "DID reported no error", - [ME_HFS2_STATE_BUP_ENABLE_UMA] = - "Enabling UMA", - [ME_HFS2_STATE_BUP_ENABLE_UMA_ERR] = - "Enabling UMA error", - [ME_HFS2_STATE_BUP_SEND_DID_ACK] = - "Sending DID Ack to BIOS", - [ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR] = - "Sending DID Ack to BIOS error", - [ME_HFS2_STATE_BUP_M0_CLK] = - "Switching clocks in M0", - [ME_HFS2_STATE_BUP_M0_CLK_ERR] = - "Switching clocks in M0 error", - [ME_HFS2_STATE_BUP_TEMP_DIS] = - "ME in temp disable", - [ME_HFS2_STATE_BUP_M0_KERN_LOAD] = - "M0 kernel load", -}; - -/* Progress Code 3 states */ -static const char *me_progress_policy_values[] = { - [ME_HFS2_STATE_POLICY_ENTRY] = "Entry into Policy Module", - [ME_HFS2_STATE_POLICY_RCVD_S3] = "Received S3 entry", - [ME_HFS2_STATE_POLICY_RCVD_S4] = "Received S4 entry", - [ME_HFS2_STATE_POLICY_RCVD_S5] = "Received S5 entry", - [ME_HFS2_STATE_POLICY_RCVD_UPD] = "Received UPD entry", - [ME_HFS2_STATE_POLICY_RCVD_PCR] = "Received PCR entry", - [ME_HFS2_STATE_POLICY_RCVD_NPCR] = "Received NPCR entry", - [ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE] = "Received host wake", - [ME_HFS2_STATE_POLICY_RCVD_AC_DC] = "Received AC<>DC switch", - [ME_HFS2_STATE_POLICY_RCVD_DID] = "Received DRAM Init Done", - [ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND] = - "VSCC Data not found for flash device", - [ME_HFS2_STATE_POLICY_VSCC_INVALID] = - "VSCC Table is not valid", - [ME_HFS2_STATE_POLICY_FPB_ERR] = - "Flash Partition Boundary is outside address space", - [ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR] = - "ME cannot access the chipset descriptor region", - [ME_HFS2_STATE_POLICY_VSCC_NO_MATCH] = - "Required VSCC values for flash parts do not match", -}; - -void intel_me_status(void) -{ - struct me_hfs _hfs, *hfs = &_hfs; - struct me_hfs2 _hfs2, *hfs2 = &_hfs2; - - me_read_dword_ptr(hfs, PCI_ME_HFS); - me_read_dword_ptr(hfs2, PCI_ME_HFS2); - - /* Check Current States */ - printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", - hfs->fpt_bad ? "BAD" : "OK"); - printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n", - hfs->ft_bup_ld_flr ? "YES" : "NO"); - printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", - hfs->fw_init_complete ? "YES" : "NO"); - printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n", - hfs->mfg_mode ? "YES" : "NO"); - printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", - hfs->boot_options_present ? "YES" : "NO"); - printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", - hfs->update_in_progress ? "YES" : "NO"); - printk(BIOS_DEBUG, "ME: Current Working State : %s\n", - me_cws_values[hfs->working_state]); - printk(BIOS_DEBUG, "ME: Current Operation State : %s\n", - me_opstate_values[hfs->operation_state]); - printk(BIOS_DEBUG, "ME: Current Operation Mode : %s\n", - me_opmode_values[hfs->operation_mode]); - printk(BIOS_DEBUG, "ME: Error Code : %s\n", - me_error_values[hfs->error_code]); - printk(BIOS_DEBUG, "ME: Progress Phase : %s\n", - me_progress_values[hfs2->progress_code]); - printk(BIOS_DEBUG, "ME: Power Management Event : %s\n", - me_pmevent_values[hfs2->current_pmevent]); - - printk(BIOS_DEBUG, "ME: Progress Phase State : "); - switch (hfs2->progress_code) { - case ME_HFS2_PHASE_ROM: /* ROM Phase */ - printk(BIOS_DEBUG, "%s", - me_progress_rom_values[hfs2->current_state]); - break; - - case ME_HFS2_PHASE_UKERNEL: /* uKernel Phase */ - printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); - break; - - case ME_HFS2_PHASE_BUP: /* Bringup Phase */ - if (hfs2->current_state < ARRAY_SIZE(me_progress_bup_values) - && me_progress_bup_values[hfs2->current_state]) - printk(BIOS_DEBUG, "%s", - me_progress_bup_values[hfs2->current_state]); - else - printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); - break; - - case ME_HFS2_PHASE_POLICY: /* Policy Module Phase */ - if (hfs2->current_state < ARRAY_SIZE(me_progress_policy_values) - && me_progress_policy_values[hfs2->current_state]) - printk(BIOS_DEBUG, "%s", - me_progress_policy_values[hfs2->current_state]); - else - printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); - break; - - case ME_HFS2_PHASE_HOST_COMM: /* Host Communication Phase */ - if (!hfs2->current_state) - printk(BIOS_DEBUG, "Host communication established"); - else - printk(BIOS_DEBUG, "0x%02x", hfs2->current_state); - break; - - default: - printk(BIOS_DEBUG, "Unknown phase: 0x%02x state: 0x%02x", - hfs2->progress_code, hfs2->current_state); - } - printk(BIOS_DEBUG, "\n"); -} -#endif - -void intel_me_hsio_version(uint16_t *version, uint16_t *checksum) -{ - int count; - u32 hsiover; - struct me_hfs hfs; - - /* Query for HSIO version, overloads H_GS and HFS */ - pci_write_config32(PCH_DEV_ME, PCI_ME_H_GS, - ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); - - /* Must wait for ME acknowledgement */ - for (count = ME_RETRY; count > 0; --count) { - me_read_dword_ptr(&hfs, PCI_ME_HFS); - if (hfs.bios_msg_ack) - break; - udelay(ME_DELAY); - } - if (!count) { - printk(BIOS_ERR, "ERROR: ME failed to respond\n"); - return; - } - - /* HSIO version should be in HFS_5 */ - hsiover = pci_read_config32(PCH_DEV_ME, PCI_ME_HFS5); - *version = hsiover >> 16; - *checksum = hsiover & 0xffff; - - printk(BIOS_DEBUG, "ME: HSIO Version : %d (CRC 0x%04x)\n", - *version, *checksum); - - /* Reset registers to normal behavior */ - pci_write_config32(PCH_DEV_ME, PCI_ME_H_GS, - ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); -} diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c index 7b8df28f71..f8ef01a6df 100644 --- a/src/soc/intel/skylake/memmap.c +++ b/src/soc/intel/skylake/memmap.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,33 +15,87 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> #include <cbmem.h> #include <device/pci.h> #include <soc/pci_devs.h> +#include <soc/romstage.h> +#include <soc/smm.h> #include <soc/systemagent.h> -static uintptr_t dpr_region_start(void) +size_t mmap_region_granluarity(void) +{ + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) + /* Align to TSEG size when SMM is in use */ + if (CONFIG_SMM_TSEG_SIZE != 0) + return CONFIG_SMM_TSEG_SIZE; + + /* Make it 8MiB by default. */ + return 8 << 20; +} + +static void *smm_region_start(void) { /* - * Base of DPR is top of usable DRAM below 4GiB. The register has - * 1 MiB alignment and reports the TOP of the range, the base - * must be calculated from the size in MiB in bits 11:4. + * SMM base address matches the top of DPR. The DPR register has + * 1 MiB alignment and reports the TOP of the DPR range. */ - uintptr_t dpr = pci_read_config32(SA_DEV_ROOT, DPR); - uintptr_t tom = dpr & ~((1 << 20) - 1); - - /* Subtract DMA Protected Range size if enabled */ - if (dpr & DPR_EPM) - tom -= (dpr & DPR_SIZE_MASK) << 16; + uint32_t smm_base = pci_read_config32(SA_DEV_ROOT, DPR); + smm_base = ALIGN_DOWN(smm_base, 1 << 20); + return (void *)smm_base; +} - return tom; +void smm_region(void **start, size_t *size) +{ + *start = smm_region_start(); + *size = mmap_region_granluarity(); } void *cbmem_top(void) { - return (void *) dpr_region_start(); + /* + * +-------------------------+ Top of RAM (aligned) + * | System Management Mode | + * | code and data | Length: CONFIG_TSEG_SIZE + * | (TSEG) | + * +-------------------------+ SMM base (aligned) + * | | + * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE + * | | + * +-------------------------+ top_of_ram (aligned) + * | | + * | CBMEM Root | + * | | + * +-------------------------+ + * | | + * | FSP Reserved Memory | + * | | + * +-------------------------+ + * | | + * | Various CBMEM Entries | + * | | + * +-------------------------+ top_of_stack (8 byte aligned) + * | | + * | stack (CBMEM Entry) | + * | | + * +-------------------------+ + */ + + unsigned long top_of_ram = (unsigned long)smm_region_start(); + + /* + * Subtract DMA Protected Range size if enabled and align to a multiple + * of TSEG size. + */ + u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR); + if (dpr & DPR_EPM) { + top_of_ram -= (dpr & DPR_SIZE_MASK) << 16; + top_of_ram = ALIGN_DOWN(top_of_ram, mmap_region_granluarity()); + } + + return (void *)(top_of_ram - CONFIG_CHIPSET_RESERVED_MEM_BYTES); } + diff --git a/src/soc/intel/skylake/microcode/Makefile.inc b/src/soc/intel/skylake/microcode/Makefile.inc index bf9e345dbd..2356b8467e 100644 --- a/src/soc/intel/skylake/microcode/Makefile.inc +++ b/src/soc/intel/skylake/microcode/Makefile.inc @@ -1 +1,16 @@ -cpu_microcode-y += microcode_blob.c +# Add CPU uCode source to list of files to build. +cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c + +# Include path for addition microcode sources. +INCLUDES += -I$(CONFIG_EXTRA_MICROCODE_INCLUDE_PATH) + +# This section overrides the default build process for the microcode to place +# it at a known location in the CBFS. This only needs to be enabled if FSP is +# being used. +# Define the correct offset for the file in CBFS +fsp_ucode_cbfs_base = $(CONFIG_CPU_MICROCODE_CBFS_LOC) + +# Override the location that was supplied by the core code. +add-cpu-microcode-to-cbfs = \ + $(CBFSTOOL) $(1) add -n $(cpu_ucode_cbfs_name) -f $(cpu_ucode_cbfs_file) -t microcode -b $(fsp_ucode_cbfs_base) + diff --git a/src/soc/intel/skylake/microcode/microcode_blob.c b/src/soc/intel/skylake/microcode/microcode_blob.c index 4f06cb2266..511c899d6b 100644 --- a/src/soc/intel/skylake/microcode/microcode_blob.c +++ b/src/soc/intel/skylake/microcode/microcode_blob.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,10 +15,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -unsigned microcode[] = { -#include "../../../../../3rdparty/blobs/soc/intel/broadwell/microcode_blob.h" +unsigned int microcode[] = { +#include "microcode_blob.h" }; diff --git a/src/soc/intel/skylake/include/soc/reset.h b/src/soc/intel/skylake/microcode/microcode_blob.h index 6f21181a0c..4bca894446 100644 --- a/src/soc/intel/skylake/include/soc/reset.h +++ b/src/soc/intel/skylake/microcode/microcode_blob.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,12 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#ifndef _BROADWELL_RESET_H_ -#define _BROADWELL_RESET_H_ +#include "MC0406E2_00000017_00000018.h" -void reset_system(void); - -#endif + /* Dummy terminator */ + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, diff --git a/src/soc/intel/skylake/minihd.c b/src/soc/intel/skylake/minihd.c deleted file mode 100644 index ac5af8d77a..0000000000 --- a/src/soc/intel/skylake/minihd.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Advanced Micro Devices, Inc. - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <device/pci_ops.h> -#include <arch/io.h> -#include <delay.h> -#include <stdlib.h> -#include <soc/intel/common/hda_verb.h> -#include <soc/ramstage.h> - -static const u32 minihd_verb_table[] = { - /* coreboot specific header */ - 0x80862807, // Codec Vendor / Device ID: Intel Mini-HD - 0x00000000, // Subsystem ID - 0x00000004, // Number of jacks - - /* Enable 3rd Pin and Converter Widget */ - 0x00878101, - - /* Pin Widget 5 - PORT B */ - 0x00571C10, - 0x00571D00, - 0x00571E56, - 0x00571F18, - - /* Pin Widget 6 - PORT C */ - 0x00671C20, - 0x00671D00, - 0x00671E56, - 0x00671F18, - - /* Pin Widget 7 - PORT D */ - 0x00771C30, - 0x00771D00, - 0x00771E56, - 0x00771F18, - - /* Disable 3rd Pin and Converter Widget */ - 0x00878100, - - /* Dummy entries to fill out the table */ - 0x00878100, - 0x00878100, -}; - -static void minihd_init(struct device *dev) -{ - struct resource *res; - u8 *base, reg32; - int codec_mask, i; - - /* Find base address */ - res = find_resource(dev, PCI_BASE_ADDRESS_0); - if (!res) - return; - - base = res2mmio(res, 0, 0); - printk(BIOS_DEBUG, "Mini-HD: base = %p\n", base); - - /* Set Bus Master */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); - - /* Mini-HD configuration */ - reg32 = read32(base + 0x100c); - reg32 &= 0xfffc0000; - reg32 |= 0x4; - write32(base + 0x100c, reg32); - - reg32 = read32(base + 0x1010); - reg32 &= 0xfffc0000; - reg32 |= 0x4b; - write32(base + 0x1010, reg32); - - /* Init the codec and write the verb table */ - codec_mask = hda_codec_detect(base); - - if (codec_mask) { - for (i = 3; i >= 0; i--) { - if (codec_mask & (1 << i)) - hda_codec_init(base, i, - sizeof(minihd_verb_table), - minihd_verb_table); - } - } -} - -static struct device_operations minihd_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .init = &minihd_init, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x0a0c, /* Haswell */ - 0x160c, /* Broadwell */ - 0 -}; - -static const struct pci_driver minihd_driver __pci_driver = { - .ops = &minihd_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/monotonic_timer.c b/src/soc/intel/skylake/monotonic_timer.c index 39134ef20a..35ad911168 100644 --- a/src/soc/intel/skylake/monotonic_timer.c +++ b/src/soc/intel/skylake/monotonic_timer.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <stdint.h> @@ -30,8 +31,10 @@ static struct monotonic_counter { static inline uint32_t read_counter_msr(void) { - /* Even though the MSR is 64-bit it is assumed that the hardware - * is polled frequently enough to only use the lower 32-bits. */ + /* + * Even though the MSR is 64-bit it is assumed that the hardware + * is polled frequently enough to only use the lower 32-bits. + */ msr_t counter_msr; counter_msr = rdmsr(MSR_COUNTER_24_MHZ); diff --git a/src/soc/intel/skylake/pch.c b/src/soc/intel/skylake/pch.c index ab546e8d55..8657402ab8 100644 --- a/src/soc/intel/skylake/pch.c +++ b/src/soc/intel/skylake/pch.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <console/console.h> @@ -24,12 +25,9 @@ #include <device/device.h> #include <device/pci.h> #include <device/pci_def.h> -#include <soc/iobp.h> #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/serialio.h> #include <soc/spi.h> u8 pch_revision(void) @@ -42,160 +40,43 @@ u16 pch_type(void) return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID); } -/* Return 1 if PCH type is WildcatPoint */ -int pch_is_wpt(void) +void *get_spi_bar(void) { - return ((pch_type() & 0xfff0) == 0x9cc0) ? 1 : 0; -} - -/* Return 1 if PCH type is WildcatPoint ULX */ -int pch_is_wpt_ulx(void) -{ - u16 lpcid = pch_type(); - - switch (lpcid) { - case PCH_WPT_BDW_Y_SAMPLE: - case PCH_WPT_BDW_Y_PREMIUM: - case PCH_WPT_BDW_Y_BASE: - return 1; - } - - return 0; + device_t dev = PCH_DEV_SPI; + uint32_t bar; + + bar = pci_read_config32(dev, PCH_SPI_BASE_ADDRESS); + /* Bits 31-12 are the base address as per EDS for SPI 1F/5, + * Don't care about 0-11 bit + */ + return (void *)(bar & ~(B_PCH_SPI_BAR0_MASK)); } u32 pch_read_soft_strap(int id) { - u32 fdoc; + uint32_t fdoc; + void *spibar = get_spi_bar(); - fdoc = SPIBAR32(SPIBAR_FDOC); + fdoc = read32(spibar + SPIBAR_FDOC); fdoc &= ~0x00007ffc; - SPIBAR32(SPIBAR_FDOC) = fdoc; + write32(spibar + SPIBAR_FDOC, fdoc); fdoc |= 0x00004000; fdoc |= id * 4; - SPIBAR32(SPIBAR_FDOC) = fdoc; - - return SPIBAR32(SPIBAR_FDOD); -} - -#ifndef __PRE_RAM__ + write32(spibar + SPIBAR_FDOC, fdoc); -/* Put device in D3Hot Power State */ -static void pch_enable_d3hot(device_t dev) -{ - u32 reg32 = pci_read_config32(dev, PCH_PCS); - reg32 |= PCH_PCS_PS_D3HOT; - pci_write_config32(dev, PCH_PCS, reg32); -} - -/* RCBA function disable and posting read to flush the transaction */ -static void rcba_function_disable(u32 reg, u32 bit) -{ - RCBA32_OR(reg, bit); - RCBA32(reg); -} - -/* Set bit in Function Disable register to hide this device */ -void pch_disable_devfn(device_t dev) -{ - switch (dev->path.pci.devfn) { - case PCH_DEVFN_ADSP: /* Audio DSP */ - rcba_function_disable(FD, PCH_DISABLE_ADSPD); - break; - case PCH_DEVFN_XHCI: /* XHCI */ - rcba_function_disable(FD, PCH_DISABLE_XHCI); - break; - case PCH_DEVFN_SDMA: /* DMA */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_I2C0: /* I2C0 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_I2C1: /* I2C1 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_SPI0: /* SPI0 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_SPI1: /* SPI1 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_UART0: /* UART0 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_UART1: /* UART1 */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_ME: /* MEI #1 */ - rcba_function_disable(FD2, PCH_DISABLE_MEI1); - break; - case PCH_DEVFN_ME_2: /* MEI #2 */ - rcba_function_disable(FD2, PCH_DISABLE_MEI2); - break; - case PCH_DEVFN_ME_IDER: /* IDE-R */ - rcba_function_disable(FD2, PCH_DISABLE_IDER); - break; - case PCH_DEVFN_ME_KT: /* KT */ - rcba_function_disable(FD2, PCH_DISABLE_KT); - break; - case PCH_DEVFN_SDIO: /* SDIO */ - pch_enable_d3hot(dev); - pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS); - break; - case PCH_DEVFN_GBE: /* Gigabit Ethernet */ - rcba_function_disable(BUC, PCH_DISABLE_GBE); - break; - case PCH_DEVFN_HDA: /* HD Audio Controller */ - rcba_function_disable(FD, PCH_DISABLE_HD_AUDIO); - break; - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 0): /* PCI Express Root Port 1 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 1): /* PCI Express Root Port 2 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 2): /* PCI Express Root Port 3 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 3): /* PCI Express Root Port 4 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 4): /* PCI Express Root Port 5 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 5): /* PCI Express Root Port 6 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 6): /* PCI Express Root Port 7 */ - case PCI_DEVFN(PCH_DEV_SLOT_PCIE, 7): /* PCI Express Root Port 8 */ - rcba_function_disable(FD, - PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn))); - break; - case PCH_DEVFN_EHCI: /* EHCI #1 */ - rcba_function_disable(FD, PCH_DISABLE_EHCI1); - break; - case PCH_DEVFN_LPC: /* LPC */ - rcba_function_disable(FD, PCH_DISABLE_LPC); - break; - case PCH_DEVFN_SATA: /* SATA #1 */ - rcba_function_disable(FD, PCH_DISABLE_SATA1); - break; - case PCH_DEVFN_SMBUS: /* SMBUS */ - rcba_function_disable(FD, PCH_DISABLE_SMBUS); - break; - case PCH_DEVFN_SATA2: /* SATA #2 */ - rcba_function_disable(FD, PCH_DISABLE_SATA2); - break; - case PCH_DEVFN_THERMAL: /* Thermal Subsystem */ - rcba_function_disable(FD, PCH_DISABLE_THERMAL); - break; - } + return read32(spibar + SPIBAR_FDOD); } -void broadwell_pch_enable_dev(device_t dev) +#if ENV_RAMSTAGE +void pch_enable_dev(device_t dev) { + /* FSP should implement routines to disable PCH IPs */ u32 reg32; /* These devices need special enable/disable handling */ switch (PCI_SLOT(dev->path.pci.devfn)) { case PCH_DEV_SLOT_PCIE: - case PCH_DEV_SLOT_EHCI: - case PCH_DEV_SLOT_HDA: return; } @@ -209,7 +90,6 @@ void broadwell_pch_enable_dev(device_t dev) pci_write_config32(dev, PCI_COMMAND, reg32); /* Disable this device if possible */ - pch_disable_devfn(dev); } else { /* Enable SERR */ reg32 = pci_read_config32(dev, PCI_COMMAND); diff --git a/src/soc/intel/skylake/pcie.c b/src/soc/intel/skylake/pcie.c index 895df932a0..dbe119a27c 100644 --- a/src/soc/intel/skylake/pcie.c +++ b/src/soc/intel/skylake/pcie.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,9 +16,10 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <chip.h> #include <console/console.h> #include <device/device.h> #include <device/pci.h> @@ -26,582 +28,11 @@ #include <device/pci_ids.h> #include <soc/gpio.h> #include <soc/lpc.h> -#include <soc/iobp.h> #include <soc/pch.h> #include <soc/pci_devs.h> -#include <soc/rcba.h> -#include <soc/intel/broadwell/chip.h> #include <soc/cpu.h> #include <delay.h> -static void pcie_update_cfg8(device_t dev, int reg, u8 mask, u8 or); -static void pcie_update_cfg(device_t dev, int reg, u32 mask, u32 or); - -/* Low Power variant has 6 root ports. */ -#define NUM_ROOT_PORTS 6 - -struct root_port_config { - /* RPFN is a write-once register so keep a copy until it is written */ - u32 orig_rpfn; - u32 new_rpfn; - u32 pin_ownership; - u32 strpfusecfg1; - u32 strpfusecfg2; - u32 strpfusecfg3; - u32 b0d28f0_32c; - u32 b0d28f4_32c; - u32 b0d28f5_32c; - int coalesce; - int gbe_port; - int num_ports; - device_t ports[NUM_ROOT_PORTS]; -}; - -static struct root_port_config rpc; - -static inline int root_port_is_first(device_t dev) -{ - return PCI_FUNC(dev->path.pci.devfn) == 0; -} - -static inline int root_port_is_last(device_t dev) -{ - return PCI_FUNC(dev->path.pci.devfn) == (rpc.num_ports - 1); -} - -/* Root ports are numbered 1..N in the documentation. */ -static inline int root_port_number(device_t dev) -{ - return PCI_FUNC(dev->path.pci.devfn) + 1; -} - -static void root_port_config_update_gbe_port(void) -{ - /* Is the Gbe Port enabled? */ - if (!((rpc.strpfusecfg1 >> 19) & 1)) - return; - - switch ((rpc.strpfusecfg1 >> 16) & 0x7) { - case 0: - rpc.gbe_port = 3; - break; - case 1: - rpc.gbe_port = 4; - break; - case 2: - case 3: - case 4: - case 5: - /* Lanes 0-4 of Root Port 5. */ - rpc.gbe_port = 5; - break; - default: - printk(BIOS_DEBUG, "Invalid GbE Port Selection.\n"); - } -} - -static void pcie_iosf_port_grant_count(device_t dev) -{ - u8 update_val; - u32 rpcd = (pci_read_config32(dev, 0xfc) > 14) & 0x3; - - switch (rpcd) { - case 1: - case 3: - update_val = 0x02; - break; - case 2: - update_val = 0x22; - break; - default: - update_val = 0x00; - break; - } - - RCBA32(0x103C) = (RCBA32(0x103C) & (~0xff)) | update_val; -} - -static void root_port_init_config(device_t dev) -{ - int rp; - u32 data; - u8 resp, id; - - if (root_port_is_first(dev)) { - rpc.orig_rpfn = RCBA32(RPFN); - rpc.new_rpfn = rpc.orig_rpfn; - rpc.num_ports = NUM_ROOT_PORTS; - rpc.gbe_port = -1; - /* RP0 f5[3:0] = 0101b*/ - pcie_update_cfg8(dev, 0xf5, ~0xa, 0x5); - - pcie_iosf_port_grant_count(dev); - - rpc.pin_ownership = pci_read_config32(dev, 0x410); - root_port_config_update_gbe_port(); - - pcie_update_cfg8(dev, 0xe2, ~(3 << 4), (3 << 4)); - if (dev->chip_info != NULL) { - config_t *config = dev->chip_info; - rpc.coalesce = config->pcie_port_coalesce; - } - } - - rp = root_port_number(dev); - if (rp > rpc.num_ports) { - printk(BIOS_ERR, "Found Root Port %d, expecting %d\n", - rp, rpc.num_ports); - return; - } - - /* Read the fuse configuration and pin ownership. */ - switch (rp) { - case 1: - rpc.strpfusecfg1 = pci_read_config32(dev, 0xfc); - rpc.b0d28f0_32c = pci_read_config32(dev, 0x32c); - break; - case 5: - rpc.strpfusecfg2 = pci_read_config32(dev, 0xfc); - rpc.b0d28f4_32c = pci_read_config32(dev, 0x32c); - break; - case 6: - rpc.b0d28f5_32c = pci_read_config32(dev, 0x32c); - rpc.strpfusecfg3 = pci_read_config32(dev, 0xfc); - break; - default: - break; - } - - pcie_update_cfg(dev, 0x418, 0, 0x02000430); - - if (root_port_is_first(dev)) { - /* - * set RP0 PCICFG E2h[5:4] = 11b and E1h[6] = 1 - * before configuring ASPM - */ - id = 0xe0 + (u8)(RCBA32(RPFN) & 0x07); - pch_iobp_exec(0xE00000E0, IOBP_PCICFG_READ, id, &data, &resp); - data |= ((0x30 << 16) | (0x40 << 8)); - pch_iobp_exec(0xE00000E0, IOBP_PCICFG_WRITE, id, &data, &resp); - } - - /* Cache pci device. */ - rpc.ports[rp - 1] = dev; -} - -/* Update devicetree with new Root Port function number assignment */ -static void pch_pcie_device_set_func(int index, int pci_func) -{ - device_t dev; - unsigned new_devfn; - - dev = rpc.ports[index]; - - /* Set the new PCI function field for this Root Port. */ - rpc.new_rpfn &= ~RPFN_FNMASK(index); - rpc.new_rpfn |= RPFN_FNSET(index, pci_func); - - /* Determine the new devfn for this port */ - new_devfn = PCI_DEVFN(PCH_DEV_SLOT_PCIE, pci_func); - - if (dev->path.pci.devfn != new_devfn) { - printk(BIOS_DEBUG, - "PCH: PCIe map %02x.%1x -> %02x.%1x\n", - PCI_SLOT(dev->path.pci.devfn), - PCI_FUNC(dev->path.pci.devfn), - PCI_SLOT(new_devfn), PCI_FUNC(new_devfn)); - - dev->path.pci.devfn = new_devfn; - } -} - -static void pcie_enable_clock_gating(void) -{ - int i; - int enabled_ports = 0; - int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT); - - for (i = 0; i < rpc.num_ports; i++) { - device_t dev; - int rp; - - dev = rpc.ports[i]; - rp = root_port_number(dev); - - if (!dev->enabled) { - /* Configure shared resource clock gating. */ - if (rp == 1 || rp == 5 || rp == 6) - pcie_update_cfg8(dev, 0xe1, 0xc3, 0x3c); - - pcie_update_cfg8(dev, 0xe2, ~(3 << 4), (3 << 4)); - pcie_update_cfg(dev, 0x420, ~(1 << 31), (1 << 31)); - - /* Per-Port CLKREQ# handling. */ - if (gpio_is_native(18 + rp - 1)) - pcie_update_cfg(dev, 0x420, ~0, (3 << 29)); - - /* Enable static clock gating. */ - if (rp == 1 && !rpc.ports[1]->enabled && - !rpc.ports[2]->enabled && !rpc.ports[3]->enabled) { - pcie_update_cfg8(dev, 0xe2, ~1, 1); - pcie_update_cfg8(dev, 0xe1, 0x7f, 0x80); - } else if (rp == 5 || rp == 6) { - pcie_update_cfg8(dev, 0xe2, ~1, 1); - pcie_update_cfg8(dev, 0xe1, 0x7f, 0x80); - } - continue; - } - - enabled_ports++; - - /* Enable dynamic clock gating. */ - pcie_update_cfg8(dev, 0xe1, 0xfc, 0x03); - pcie_update_cfg8(dev, 0xe2, ~(1 << 6), (1 << 6)); - pcie_update_cfg8(dev, 0xe8, ~(3 << 2), (2 << 2)); - - /* Update PECR1 register. */ - pcie_update_cfg8(dev, 0xe8, ~0, 3); - if (is_broadwell) { - pcie_update_cfg(dev, 0x324, ~((1 << 5) | (1 << 14)), - ((1 << 5) | (1 << 14))); - } else { - pcie_update_cfg(dev, 0x324, ~(1 << 5), (1 << 5)); - } - /* Per-Port CLKREQ# handling. */ - if (gpio_is_native(18 + rp - 1)) - /* - * In addition to D28Fx PCICFG 420h[30:29] = 11b, - * set 420h[17] = 0b and 420[0] = 1b for L1 SubState. - */ - pcie_update_cfg(dev, 0x420, ~0x20000, (3 << 29) | 1); - - /* Configure shared resource clock gating. */ - if (rp == 1 || rp == 5 || rp == 6) - pcie_update_cfg8(dev, 0xe1, 0xc3, 0x3c); - - /* CLKREQ# VR Idle Enable */ - RCBA32_OR(0x2b1c, (1 << (16 + i))); - } - - if (!enabled_ports) - pcie_update_cfg8(rpc.ports[0], 0xe1, ~(1 << 6), (1 << 6)); -} - -static void root_port_commit_config(void) -{ - int i; - - /* If the first root port is disabled the coalesce ports. */ - if (!rpc.ports[0]->enabled) - rpc.coalesce = 1; - - /* Perform clock gating configuration. */ - pcie_enable_clock_gating(); - - for (i = 0; i < rpc.num_ports; i++) { - device_t dev; - u32 reg32; - int n = 0; - - dev = rpc.ports[i]; - - if (dev == NULL) { - printk(BIOS_ERR, "Root Port %d device is NULL?\n", i+1); - continue; - } - - if (dev->enabled) - continue; - - printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev)); - - /* 8.2 Configuration of PCI Express Root Ports */ - pcie_update_cfg(dev, 0x338, ~(1 << 26), 1 << 26); - - do { - reg32 = pci_read_config32(dev, 0x328); - n++; - if (((reg32 & 0xff000000) == 0x01000000) || (n > 50)) - break; - udelay(100); - } while (1); - - if (n > 50) - printk(BIOS_DEBUG, "%s: Timeout waiting for 328h\n", - dev_path(dev)); - - pcie_update_cfg(dev, 0x408, ~(1 << 27), 1 << 27); - - /* Disable this device if possible */ - pch_disable_devfn(dev); - } - - if (rpc.coalesce) { - int current_func; - - /* For all Root Ports N enabled ports get assigned the lower - * PCI function number. The disabled ones get upper PCI - * function numbers. */ - current_func = 0; - for (i = 0; i < rpc.num_ports; i++) { - if (!rpc.ports[i]->enabled) - continue; - pch_pcie_device_set_func(i, current_func); - current_func++; - } - - /* Allocate the disabled devices' PCI function number. */ - for (i = 0; i < rpc.num_ports; i++) { - if (rpc.ports[i]->enabled) - continue; - pch_pcie_device_set_func(i, current_func); - current_func++; - } - } - - printk(BIOS_SPEW, "PCH: RPFN 0x%08x -> 0x%08x\n", - rpc.orig_rpfn, rpc.new_rpfn); - RCBA32(RPFN) = rpc.new_rpfn; -} - -static void root_port_mark_disable(device_t dev) -{ - /* Mark device as disabled. */ - dev->enabled = 0; - /* Mark device to be hidden. */ - rpc.new_rpfn |= RPFN_HIDE(PCI_FUNC(dev->path.pci.devfn)); -} - -static void root_port_check_disable(device_t dev) -{ - int rp; - - /* Device already disabled. */ - if (!dev->enabled) { - root_port_mark_disable(dev); - return; - } - - rp = root_port_number(dev); - - /* Is the GbE port mapped to this Root Port? */ - if (rp == rpc.gbe_port) { - root_port_mark_disable(dev); - return; - } - - /* Check Root Port Configuration. */ - switch (rp) { - case 2: - /* Root Port 2 is disabled for all lane configurations - * but config 00b (4x1 links). */ - if ((rpc.strpfusecfg1 >> 14) & 0x3) { - root_port_mark_disable(dev); - return; - } - break; - case 3: - /* Root Port 3 is disabled in config 11b (1x4 links). */ - if (((rpc.strpfusecfg1 >> 14) & 0x3) == 0x3) { - root_port_mark_disable(dev); - return; - } - break; - case 4: - /* Root Port 4 is disabled in configs 11b (1x4 links) - * and 10b (2x2 links). */ - if ((rpc.strpfusecfg1 >> 14) & 0x2) { - root_port_mark_disable(dev); - return; - } - break; - } - - /* Check Pin Ownership. */ - switch (rp) { - case 1: - /* Bit 0 is Root Port 1 ownership. */ - if ((rpc.pin_ownership & 0x1) == 0) { - root_port_mark_disable(dev); - return; - } - break; - case 2: - /* Bit 2 is Root Port 2 ownership. */ - if ((rpc.pin_ownership & 0x4) == 0) { - root_port_mark_disable(dev); - return; - } - break; - case 6: - /* Bits 7:4 are Root Port 6 pin-lane ownership. */ - if ((rpc.pin_ownership & 0xf0) == 0) { - root_port_mark_disable(dev); - return; - } - break; - } -} - -static void pcie_update_cfg8(device_t dev, int reg, u8 mask, u8 or) -{ - u8 reg8; - - reg8 = pci_read_config8(dev, reg); - reg8 &= mask; - reg8 |= or; - pci_write_config8(dev, reg, reg8); -} - -static void pcie_update_cfg(device_t dev, int reg, u32 mask, u32 or) -{ - u32 reg32; - - reg32 = pci_read_config32(dev, reg); - reg32 &= mask; - reg32 |= or; - pci_write_config32(dev, reg, reg32); -} - -static void pcie_add_0x0202000_iobp(u32 reg) -{ - u32 reg32; - - reg32 = pch_iobp_read(reg); - reg32 += (0x2 << 16) | (0x2 << 8); - pch_iobp_write(reg, reg32); -} - -static void pch_pcie_early(struct device *dev) -{ - config_t *config = dev->chip_info; - int do_aspm = 0; - int rp = root_port_number(dev); - - switch (rp) { - case 1: - case 2: - case 3: - case 4: - /* - * Bits 31:28 of b0d28f0 0x32c register correspond to - * Root Ports 4:1. - */ - do_aspm = !!(rpc.b0d28f0_32c & (1 << (28 + rp - 1))); - break; - case 5: - /* - * Bit 28 of b0d28f4 0x32c register correspond to - * Root Ports 4:1. - */ - do_aspm = !!(rpc.b0d28f4_32c & (1 << 28)); - break; - case 6: - /* - * Bit 28 of b0d28f5 0x32c register correspond to - * Root Ports 4:1. - */ - do_aspm = !!(rpc.b0d28f5_32c & (1 << 28)); - break; - } - - /* Allow ASPM to be forced on in devicetree */ - if (config && (config->pcie_port_force_aspm & (1 << (rp - 1)))) - do_aspm = 1; - - printk(BIOS_DEBUG, "PCIe Root Port %d ASPM is %sabled\n", - rp, do_aspm ? "en" : "dis"); - - if (do_aspm) { - /* Set ASPM bits in MPC2 register. */ - pcie_update_cfg(dev, 0xd4, ~(0x3 << 2), (1 << 4) | (0x2 << 2)); - - /* Set unique clock exit latency in MPC register. */ - pcie_update_cfg(dev, 0xd8, ~(0x7 << 18), (0x7 << 18)); - - switch (rp) { - case 1: - pcie_add_0x0202000_iobp(0xe9002440); - break; - case 2: - pcie_add_0x0202000_iobp(0xe9002640); - break; - case 3: - pcie_add_0x0202000_iobp(0xe9000840); - break; - case 4: - pcie_add_0x0202000_iobp(0xe9000a40); - break; - case 5: - pcie_add_0x0202000_iobp(0xe9000c40); - pcie_add_0x0202000_iobp(0xe9000e40); - pcie_add_0x0202000_iobp(0xe9001040); - pcie_add_0x0202000_iobp(0xe9001240); - break; - case 6: - /* Update IOBP based on lane ownership. */ - if (rpc.pin_ownership & (1 << 4)) - pcie_add_0x0202000_iobp(0xea002040); - if (rpc.pin_ownership & (1 << 5)) - pcie_add_0x0202000_iobp(0xea002240); - if (rpc.pin_ownership & (1 << 6)) - pcie_add_0x0202000_iobp(0xea002440); - if (rpc.pin_ownership & (1 << 7)) - pcie_add_0x0202000_iobp(0xea002640); - break; - } - - pcie_update_cfg(dev, 0x338, ~(1 << 26), 0); - } - - /* Enable LTR in Root Port. Disable OBFF. */ - pcie_update_cfg(dev, 0x64, ~(1 << 11) & ~(3 << 18), (1 << 11)); - pcie_update_cfg(dev, 0x68, ~(1 << 10), (1 << 10)); - - pcie_update_cfg(dev, 0x318, ~(0xffff << 16), (0x1414 << 16)); - - /* Set L1 exit latency in LCAP register. */ - if (!do_aspm && (pci_read_config8(dev, 0xf5) & 0x1)) - pcie_update_cfg(dev, 0x4c, ~(0x7 << 15), (0x4 << 15)); - else - pcie_update_cfg(dev, 0x4c, ~(0x7 << 15), (0x2 << 15)); - - pcie_update_cfg(dev, 0x314, 0x0, 0x743a361b); - - /* Set Common Clock Exit Latency in MPC register. */ - pcie_update_cfg(dev, 0xd8, ~(0x7 << 15), (0x3 << 15)); - - pcie_update_cfg(dev, 0x33c, ~0x00ffffff, 0x854d74); - - /* Set Invalid Receive Range Check Enable in MPC register. */ - pcie_update_cfg(dev, 0xd8, ~0, (1 << 25)); - - pcie_update_cfg8(dev, 0xf5, 0x0f, 0); - - /* Set AER Extended Cap ID to 01h and Next Cap Pointer to 200h. */ - pcie_update_cfg(dev, 0x100, ~(1 << 29) & ~0xfffff, (1 << 29) | 0x10001); - - /* Set L1 Sub-State Cap ID to 1Eh and Next Cap Pointer to None. */ - pcie_update_cfg(dev, 0x200, ~0xffff, 0x001e); - - pcie_update_cfg(dev, 0x320, ~(3 << 20) & ~(7 << 6), - (1 << 20) | (3 << 6)); - /* Enable Relaxed Order from Root Port. */ - pcie_update_cfg(dev, 0x320, ~(3 << 23), (3 << 23)); - - if (rp == 1 || rp == 5 || rp == 6) - pcie_update_cfg8(dev, 0xf7, ~0xc, 0); - - /* Set EOI forwarding disable. */ - pcie_update_cfg(dev, 0xd4, ~0, (1 << 1)); - - /* Read and write back write-once capability registers. */ - pcie_update_cfg(dev, 0x34, ~0, 0); - pcie_update_cfg(dev, 0x40, ~0, 0); - pcie_update_cfg(dev, 0x80, ~0, 0); - pcie_update_cfg(dev, 0x90, ~0, 0); -} - static void pch_pcie_init(struct device *dev) { u16 reg16; @@ -645,43 +76,13 @@ static void pch_pcie_init(struct device *dev) pci_write_config16(dev, 0x1e, reg16); } -static void pch_pcie_enable(device_t dev) -{ - /* Add this device to the root port config structure. */ - root_port_init_config(dev); - - /* Check to see if this Root Port should be disabled. */ - root_port_check_disable(dev); - - /* Power Management init before enumeration */ - if (dev->enabled) - pch_pcie_early(dev); - - /* - * When processing the last PCIe root port we can now - * update the Root Port Function Number and Hide register. - */ - if (root_port_is_last(dev)) - root_port_commit_config(); -} - -static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device) -{ - /* NOTE: This is not the default position! */ - if (!vendor || !device) - pci_write_config32(dev, 0x94, pci_read_config32(dev, 0)); - else - pci_write_config32(dev, 0x94, (device << 16) | vendor); -} - static void pcie_set_L1_ss_max_latency(device_t dev, unsigned int off) { - /* Set max snoop and non-snoop latency for Broadwell */ + /* Set max snoop and non-snoop latency for the SOC */ pci_mmio_write_config32(dev, off, 0x10031003); } static struct pci_operations pcie_ops = { - .set_subsystem = pcie_set_subsystem, .set_L1_ss_latency = pcie_set_L1_ss_max_latency, }; @@ -690,16 +91,15 @@ static struct device_operations device_ops = { .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, .init = pch_pcie_init, - .enable = pch_pcie_enable, + .enable = NULL, .scan_bus = pciexp_scan_bridge, .ops_pci = &pcie_ops, }; static const unsigned short pcie_device_ids[] = { - /* Lynxpoint-LP */ - 0x9c10, 0x9c12, 0x9c14, 0x9c16, 0x9c18, 0x9c1a, - /* WildcatPoint */ - 0x9c90, 0x9c92, 0x9c94, 0x9c96, 0x9c98, 0x9c9a, 0x2448, + /* Sunrisepoint-LP */ + 0x9d10, 0x9d11, 0x9d12, 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17, + 0x9d18, 0x9d19, 0x9d1a, 0x9d1b, 0 }; diff --git a/src/soc/intel/skylake/pcr.c b/src/soc/intel/skylake/pcr.c new file mode 100644 index 0000000000..33d6cd12f5 --- /dev/null +++ b/src/soc/intel/skylake/pcr.c @@ -0,0 +1,162 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <soc/pcr.h> +#include <soc/iomap.h> +#include <console/console.h> + +/* + * Read PCR register. (This is internal function) + * It returns PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pch_pcr_read(PCH_SBI_PID pid, u16 offset, u32 size, void *data) +{ + if ((offset & (size - 1)) != 0) { + printk(BIOS_DEBUG, + "PchPcrRead error. Invalid Offset: %x Size: %x", + offset, size); + return -1; + } + switch (size) { + case 4: + *(u32 *) data = read32(PCH_PCR_ADDRESS(pid, offset)); + break; + case 2: + *(u16 *) data = read16(PCH_PCR_ADDRESS(pid, offset)); + break; + case 1: + *(u8 *) data = read8(PCH_PCR_ADDRESS(pid, offset)); + break; + default: + break; + } + return 0; +} + +u8 pcr_read32(PCH_SBI_PID pid, u16 offset, u32 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u32), (u32 *)outdata); +} + +u8 pcr_read16(PCH_SBI_PID pid, u16 offset, u16 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u16), (u32 *)outdata); +} + +u8 pcr_read8(PCH_SBI_PID pid, u16 offset, u8 *outdata) +{ + return pch_pcr_read(pid, offset, sizeof(u8), (u32 *)outdata); +} + +/* + * Write PCR register. (This is internal function) + * It returns PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pch_pcr_write(PCH_SBI_PID pid, u16 offset, u32 size, u32 data) +{ + if ((offset & (size - 1)) != 0) { + printk(BIOS_DEBUG, + "PchPcrWrite error. Invalid Offset: %x Size: %x", + offset, size); + return -1; + } + /* Write the PCR register with provided data + * Then read back PCR register to prevent from back to back write. + */ + switch (size) { + case 4: + write32(PCH_PCR_ADDRESS(pid, offset), (u32) data); + break; + case 2: + write16(PCH_PCR_ADDRESS(pid, offset), (u16) data); + break; + case 1: + write8(PCH_PCR_ADDRESS(pid, offset), (u8) data); + break; + default: + break; + } + read32(PCH_PCR_ADDRESS(PID_LPC, R_PCH_PCR_LPC_GCFD)); + + return 0; +} + +u8 pcr_write32(PCH_SBI_PID pid, u16 offset, u32 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u32), indata); +} + +u8 pcr_write16(PCH_SBI_PID pid, u16 offset, u16 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u16), indata); +} + +u8 pcr_write8(PCH_SBI_PID pid, u16 offset, u8 indata) +{ + return pch_pcr_write(pid, offset, sizeof(u8), indata); +} + +/* + * Write PCR register. (This is internal function) + * It programs PCR register and size in 1/2/4 bytes. + * The offset should not exceed 0xFFFF and must be aligned with size + * + * PCH_SBI_PID defines as 8 bit Port ID that will be used when sending + * transaction to sideband. + */ +static u8 pcr_and_then_or(PCH_SBI_PID pid, u16 offset, u32 size, u32 anddata, + u32 ordata) +{ + u8 status; + u32 data32; + + status = pch_pcr_read(pid, offset, size, &data32); + if (status != 0) + return -1; + + data32 &= anddata; + data32 |= ordata; + + status = pch_pcr_write(pid, offset, size, data32); + return status; +} + +u8 pcr_andthenor32(PCH_SBI_PID pid, u16 offset, u32 anddata, u32 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u32), anddata, ordata); +} + +u8 pcr_andthenor16(PCH_SBI_PID pid, u16 offset, u16 anddata, u16 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u16), anddata, ordata); +} + +u8 pcr_andthenor8(PCH_SBI_PID pid, u16 offset, u8 anddata, u8 ordata) +{ + return pcr_and_then_or(pid, offset, sizeof(u8), anddata, ordata); +} diff --git a/src/soc/intel/skylake/pei_data.c b/src/soc/intel/skylake/pei_data.c index 180f0caf8e..b943224cdc 100644 --- a/src/soc/intel/skylake/pei_data.c +++ b/src/soc/intel/skylake/pei_data.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,12 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ +#include <console/console.h> +#include <console/streams.h> #include <stdlib.h> #include <stdint.h> -#include <console/streams.h> #include <soc/iomap.h> #include <soc/pei_data.h> #include <soc/pei_wrapper.h> @@ -30,18 +32,15 @@ static void ABI_X86 send_to_console(unsigned char b) console_tx_byte(b); } -void broadwell_fill_pei_data(struct pei_data *pei_data) +void soc_fill_pei_data(struct pei_data *pei_data) { pei_data->pei_version = PEI_VERSION; pei_data->board_type = BOARD_TYPE_ULT; - pei_data->usbdebug = CONFIG_USBDEBUG; pei_data->pciexbar = MCFG_BASE_ADDRESS; pei_data->smbusbar = SMBUS_BASE_ADDRESS; - pei_data->ehcibar = EARLY_EHCI_BAR; pei_data->xhcibar = EARLY_XHCI_BAR; pei_data->gttbar = EARLY_GTT_BAR; pei_data->pmbase = ACPI_BASE_ADDRESS; - pei_data->gpiobase = GPIO_BASE_ADDRESS; pei_data->tseg_size = smm_region_size(); pei_data->temp_mmio_base = EARLY_TEMP_MMIO; pei_data->tx_byte = &send_to_console; diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c new file mode 100644 index 0000000000..934c1300af --- /dev/null +++ b/src/soc/intel/skylake/pmc.c @@ -0,0 +1,254 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <chip.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <cpu/cpu.h> +#include <pc80/mc146818rtc.h> +#include <reg_script.h> +#include <string.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pmc.h> +#include <soc/pm.h> +#include <cpu/x86/smm.h> +#include <soc/pcr.h> +#include <soc/ramstage.h> +#if IS_ENABLED(CONFIG_CHROMEOS) +#include <vendorcode/google/chromeos/chromeos.h> +#endif + +static const struct reg_script pch_pmc_misc_init_script[] = { + /* Setup SLP signal assertion, SLP_S4=4s, SLP_S3=50ms */ + REG_PCI_RMW16(GEN_PMCON_B, ~((3 << 4)|(1 << 10)), + (1 << 3)|(1 << 11)|(1 << 12)), + REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN), + /* Indicate DRAM init done for MRC */ + REG_PCI_OR8(GEN_PMCON_A, (1 << 23)), + REG_SCRIPT_END +}; + +static void pch_pmc_add_mmio_resources(device_t dev) +{ + struct resource *res; + const u32 default_decode_base = PCH_PCR_BASE_ADDRESS; + + /* + * Till PCI enumeration happens we need to allocate the PMC base + * statically. Above the PCR base. + */ + if (PCH_PWRM_BASE_ADDRESS < default_decode_base) { + res = new_resource(dev, PWRMBASE); + res->base = PCH_PWRM_BASE_ADDRESS; + /* 64KB PMC size */ + res->size = 0x10000; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + } +} + +static void pch_pmc_add_io_resource(device_t dev, u16 base, u16 size, int index) +{ + struct resource *res; + res = new_resource(dev, index); + res->base = base; + res->size = size; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void pch_pmc_add_io_resources(device_t dev) +{ + /* PMBASE */ + pch_pmc_add_io_resource(dev, ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, ABASE); +} + +static void pch_pmc_read_resources(device_t dev) +{ + /* Get the normal PCI resources of this device. */ + pci_dev_read_resources(dev); + + /* Add non-standard MMIO resources. */ + pch_pmc_add_mmio_resources(dev); + + /* Add IO resources. */ + pch_pmc_add_io_resources(dev); +} + +static void pch_set_acpi_mode(void) +{ + if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) && acpi_slp_type != 3) { + printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n"); + outb(APM_CNT_ACPI_DISABLE, APM_CNT); + printk(BIOS_DEBUG, "done.\n"); + } +} + +#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) +/* + * Preserve Vboot NV data when clearing CMOS as it will + * have been re-initialized already by Vboot firmware init. + */ +static void pch_cmos_init_preserve(int reset) +{ + uint8_t vbnv[CONFIG_VBNV_SIZE]; + if (reset) + read_vbnv(vbnv); + + cmos_init(reset); + + if (reset) + save_vbnv(vbnv); +} +#endif + +static void pch_rtc_init(void) +{ + u8 reg8; + int rtc_failed; + /*PMC Controller Device 0x1F, Func 02*/ + device_t dev = PCH_DEV_PMC; + reg8 = pci_read_config8(dev, GEN_PMCON_B); + rtc_failed = reg8 & RTC_BATTERY_DEAD; + if (rtc_failed) { + reg8 &= ~RTC_BATTERY_DEAD; + pci_write_config8(dev, GEN_PMCON_B, reg8); + printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed); + } + +#if IS_ENABLED(CONFIG_CHROMEOS_VBNV_CMOS) + pch_cmos_init_preserve(rtc_failed); +#else + cmos_init(rtc_failed); +#endif +} + +static void pch_power_options(void) +{ + u16 reg16; + const char *state; + /*PMC Controller Device 0x1F, Func 02*/ + device_t dev = PCH_DEV_PMC; + /* Get the chip configuration */ + config_t *config = dev->chip_info; + int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + + /* + * Which state do we want to goto after g3 (power restored)? + * 0 == S0 Full On + * 1 == S5 Soft Off + * + * If the option is not existent (Laptops), use Kconfig setting. + */ + /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/ + //get_option(&pwr_on, "power_on_after_fail"); + pwr_on = MAINBOARD_POWER_ON; + reg16 = pci_read_config16(dev, GEN_PMCON_B); + reg16 &= 0xfffe; + switch (pwr_on) { + case MAINBOARD_POWER_OFF: + reg16 |= 1; + state = "off"; + break; + case MAINBOARD_POWER_ON: + reg16 &= ~1; + state = "on"; + break; + case MAINBOARD_POWER_KEEP: + reg16 &= ~1; + state = "state keep"; + break; + default: + state = "undefined"; + } + pci_write_config16(dev, GEN_PMCON_B, reg16); + printk(BIOS_INFO, "Set power %s after power failure.\n", state); + /* GPE setup based on device tree configuration */ + enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, + config->gpe0_en_3, config->gpe0_en_4); + + /* SMI setup based on device tree configuration */ + enable_alt_smi(config->ec_smi_gpio, config->alt_gp_smi_en); +} + +static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + printk(BIOS_DEBUG, "%sabling Deep S%c\n", + enable ? "En" : "Dis", sx + '0'); + reg = read32(pmcbase + offset); + if (enable) + reg |= mask; + else + reg &= ~mask; + write32(pmcbase + offset, reg); +} + +static void config_deep_s5(int on) +{ + /* Treat S4 the same as S5. */ + config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS | S4AC_GATE_SUS, 4, on); + config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS | S5AC_GATE_SUS, 5, on); +} + +static void config_deep_s3(int on) +{ + config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS | S3AC_GATE_SUS, 3, on); +} + +static void pmc_init(struct device *dev) +{ + config_t *config = dev->chip_info; + + pch_rtc_init(); + + /* Initialize power management */ + pch_power_options(); + + reg_script_run_on_dev(dev, pch_pmc_misc_init_script); + pch_set_acpi_mode(); + + config_deep_s3(config->deep_s3_enable); + config_deep_s5(config->deep_s5_enable); +} + +static struct device_operations device_ops = { + .read_resources = &pch_pmc_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .init = &pmc_init, + .scan_bus = &scan_lpc_bus, + .ops_pci = &soc_pci_ops, +}; + +static const unsigned short pci_device_ids[] = { + 0x9d21, + 0 +}; + +static const struct pci_driver pch_lpc __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; diff --git a/src/soc/intel/skylake/pmutil.c b/src/soc/intel/skylake/pmutil.c index 7686387f97..c22a12083b 100644 --- a/src/soc/intel/skylake/pmutil.c +++ b/src/soc/intel/skylake/pmutil.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ /* @@ -27,11 +28,14 @@ #include <device/pci.h> #include <device/pci_def.h> #include <console/console.h> +#include <stdlib.h> +#include <soc/gpio.h> #include <soc/iomap.h> #include <soc/lpc.h> #include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/gpio.h> +#include <soc/pmc.h> +#include <soc/smbus.h> /* Print status bits with descriptive names */ static void print_status_bits(u32 status, const char *bit_names[]) @@ -41,7 +45,7 @@ static void print_status_bits(u32 status, const char *bit_names[]) if (!status) return; - for (i=31; i>=0; i--) { + for (i = 31; i >= 0; i--) { if (status & (1 << i)) { if (bit_names[i]) printk(BIOS_DEBUG, "%s ", bit_names[i]); @@ -59,7 +63,7 @@ static void print_gpio_status(u32 status, int start) if (!status) return; - for (i=31; i>=0; i--) { + for (i = 31; i >= 0; i--) { if (status & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", start + i); } @@ -212,49 +216,53 @@ void disable_smi(u32 mask) */ /* Clear GPIO SMI status and return events that are enabled and active */ -static u32 reset_alt_smi_status(void) +void reset_alt_smi_status(void) { - u32 alt_sts, alt_en; - - /* Low Power variant moves this to GPIO region as dword */ - alt_sts = inl(GPIO_BASE_ADDRESS + GPIO_ALT_GPI_SMI_STS); - outl(alt_sts, GPIO_BASE_ADDRESS + GPIO_ALT_GPI_SMI_STS); - alt_en = inl(GPIO_BASE_ADDRESS + GPIO_ALT_GPI_SMI_EN); - - /* Only report enabled events */ - return alt_sts & alt_en; + /*Clear GPIO SMI Status*/ + clear_all_smi(); } /* Print GPIO SMI status bits */ -static u32 print_alt_smi_status(u32 alt_sts) +static u32 print_alt_smi_status(void) { - if (!alt_sts) - return 0; + u32 alt_sts[GPIO_COMMUNITY_MAX]; + int gpio_index; + /* GPIO Communities GPP_A ~ E support SMI */ + const char gpiowell[] = { + [0] = 'A', + [1] = 'B', + [2] = 'C', + [3] = 'D', + [4] = 'E' + }; printk(BIOS_DEBUG, "ALT_STS: "); - - /* First 16 events are GPIO 32-47 */ - print_gpio_status(alt_sts & 0xffff, 32); + get_smi_status(alt_sts); + /* GPP_A to GPP_E GPIO has Status and Enable functionality*/ + for (gpio_index = 0; gpio_index < ARRAY_SIZE(gpiowell); + gpio_index++) { + printk(BIOS_DEBUG, "GPIO Group_%c\n", + gpiowell[gpio_index]); + print_gpio_status(alt_sts[gpio_index], 0); + } printk(BIOS_DEBUG, "\n"); - return alt_sts; + return 0; } /* Print, clear, and return GPIO SMI status */ u32 clear_alt_smi_status(void) { - return print_alt_smi_status(reset_alt_smi_status()); + reset_alt_smi_status(); + return print_alt_smi_status(); } /* Enable GPIO SMI events */ -void enable_alt_smi(u32 mask) +void enable_alt_smi(int gpionum, u32 mask) { - u32 alt_en; - - alt_en = inl(GPIO_BASE_ADDRESS + GPIO_ALT_GPI_SMI_EN); - alt_en |= mask; - outl(alt_en, GPIO_BASE_ADDRESS + GPIO_ALT_GPI_SMI_EN); + /*Set GPIO EN Status*/ + enable_gpio_groupsmi(gpionum, mask); } @@ -265,18 +273,25 @@ void enable_alt_smi(u32 mask) /* Clear TCO status and return events that are enabled and active */ static u32 reset_tco_status(void) { - u32 tcobase = ACPI_BASE_ADDRESS + 0x60; - u32 tco_sts = inl(tcobase + 0x04); - u32 tco_en = inl(ACPI_BASE_ADDRESS + 0x68); + u16 tco1_sts; + u16 tco2_sts; + u16 tcobase; + + tcobase = pmc_tco_regs(); + + /* TCO Status 2 register*/ + tco2_sts = inw(tcobase + TCO2_STS); + tco2_sts |= (TCO2_STS_SECOND_TO | TCO2_STS_BOOT); + outw(tco2_sts, tcobase + TCO2_STS); - /* Don't clear BOOT_STS before SECOND_TO_STS */ - outl(tco_sts & ~(1 << 18), tcobase + 0x04); + /* TCO Status 1 register*/ + tco1_sts = inw(tcobase + TCO1_STS); - /* Clear BOOT_STS */ - if (tco_sts & (1 << 18)) - outl(tco_sts & (1 << 18), tcobase + 0x04); + /* Clear SECOND_TO_STS bit */ + if (tco2_sts & TCO2_STS_SECOND_TO) + outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS); - return tco_sts & tco_en; + return (tco2_sts << 16) | tco1_sts; } /* Print TCO status bits */ @@ -319,7 +334,7 @@ u32 clear_tco_status(void) void enable_tco_sci(void) { /* Clear pending events */ - outl(ACPI_BASE_ADDRESS + GPE0_STS(3), TCOSCI_STS); + outl(TCOSCI_STS, ACPI_BASE_ADDRESS + GPE0_STS(3)); /* Enable TCO SCI events */ enable_gpe(TCOSCI_EN); @@ -425,7 +440,7 @@ void disable_gpe(u32 mask) int acpi_sci_irq(void) { - int scis = pci_read_config32(PCH_DEV_LPC, ACPI_CNTL) & SCI_IRQ_SEL; + int scis = pci_read_config32(PCH_DEV_PMC, ACTL) & SCI_IRQ_SEL; int sci_irq = 9; /* Determine how SCI is routed. */ @@ -450,3 +465,26 @@ int acpi_sci_irq(void) printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq); return sci_irq; } + +uint8_t *pmc_mmio_regs(void) +{ + uint32_t reg32; + + reg32 = pci_read_config32(PCH_DEV_PMC, PWRMBASE); + + /* 4KiB alignment. */ + reg32 &= ~0xfff; + + return (void *)(uintptr_t)reg32; +} + +uint16_t pmc_tco_regs(void) +{ + uint16_t reg16; + + reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE); + + reg16 &= ~0x1f; + + return reg16; +} diff --git a/src/soc/intel/skylake/ramstage.c b/src/soc/intel/skylake/ramstage.c index eaa28d02f1..51e9b31d65 100644 --- a/src/soc/intel/skylake/ramstage.c +++ b/src/soc/intel/skylake/ramstage.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,87 +15,17 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#include <arch/acpi.h> -#include <cbmem.h> +#include <bootstate.h> #include <console/console.h> -#include <device/device.h> -#include <stdlib.h> -#include <string.h> -#include <soc/nvs.h> -#include <soc/pm.h> +#include <fsp_util.h> #include <soc/ramstage.h> -#include <soc/intel/broadwell/chip.h> +#include <soc/intel/common/ramstage.h> -/* Save bit index for PM1_STS and GPE_STS for ACPI _SWS */ -static void save_acpi_wake_source(global_nvs_t *gnvs) +void soc_init_pre_device(void *chip_info) { - struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); - uint16_t pm1; - int gpe_reg; - - if (!ps) - return; - - pm1 = ps->pm1_sts & ps->pm1_en; - - /* Scan for first set bit in PM1 */ - for (gnvs->pm1i = 0; gnvs->pm1i < 16; gnvs->pm1i++) { - if (pm1 & 1) - break; - pm1 >>= 1; - } - - /* If unable to determine then return -1 */ - if (gnvs->pm1i >= 16) - gnvs->pm1i = -1; - - /* Scan for first set bit in GPE registers */ - gnvs->gpei = -1; - for (gpe_reg = 0; gpe_reg < GPE0_REG_MAX; gpe_reg++) { - u32 gpe = ps->gpe0_sts[gpe_reg] & ps->gpe0_en[gpe_reg]; - int start = gpe_reg * GPE0_REG_SIZE; - int end = start + GPE0_REG_SIZE; - - if (gpe == 0) { - if (!gnvs->gpei) - gnvs->gpei = end; - continue; - } - - for (gnvs->gpei = start; gnvs->gpei < end; gnvs->gpei++) { - if (gpe & 1) - break; - gpe >>= 1; - } - } - - /* If unable to determine then return -1 */ - if (gnvs->gpei >= (GPE0_REG_MAX * GPE0_REG_SIZE)) - gnvs->gpei = -1; - - printk(BIOS_DEBUG, "ACPI _SWS is PM1 Index %lld GPE Index %lld\n", - gnvs->pm1i, gnvs->gpei); -} - -static void s3_resume_prepare(void) -{ - global_nvs_t *gnvs; - - gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t)); - if (gnvs == NULL) - return; - - if (!acpi_is_wakeup_s3()) - memset(gnvs, 0, sizeof(global_nvs_t)); - else - save_acpi_wake_source(gnvs); -} - -void broadwell_init_pre_device(void *chip_info) -{ - s3_resume_prepare(); - broadwell_run_reference_code(); + /* Perform silicon specific init. */ + intel_silicon_init(); } diff --git a/src/soc/intel/skylake/refcode.c b/src/soc/intel/skylake/refcode.c deleted file mode 100644 index 201825a93b..0000000000 --- a/src/soc/intel/skylake/refcode.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> -#include <arch/acpi.h> -#include <cbmem.h> -#include <console/console.h> -#include <console/streams.h> -#include <cpu/x86/tsc.h> -#include <program_loading.h> -#include <rmodule.h> -#include <stage_cache.h> -#include <string.h> -#if IS_ENABLED(CONFIG_CHROMEOS) -#include <vendorcode/google/chromeos/vboot_handoff.h> -#endif -#include <soc/pei_data.h> -#include <soc/pei_wrapper.h> -#include <soc/ramstage.h> - -static pei_wrapper_entry_t load_refcode_from_cache(void) -{ - struct prog refcode; - - printk(BIOS_DEBUG, "refcode loading from cache.\n"); - - stage_cache_load_stage(STAGE_REFCODE, &refcode); - - return (pei_wrapper_entry_t)prog_entry(&refcode); -} - -static void cache_refcode(const struct rmod_stage_load *rsl) -{ - stage_cache_add(STAGE_REFCODE, rsl->prog); -} - -#if IS_ENABLED(CONFIG_CHROMEOS) -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - struct vboot_handoff *vboot_handoff; - const struct firmware_component *fwc; - struct cbfs_stage *stage; - - vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF); - fwc = &vboot_handoff->components[CONFIG_VBOOT_REFCODE_INDEX]; - - if (vboot_handoff == NULL || - vboot_handoff->selected_firmware == VB_SELECT_FIRMWARE_READONLY || - CONFIG_VBOOT_REFCODE_INDEX >= MAX_PARSED_FW_COMPONENTS || - fwc->size == 0 || fwc->address == 0) - return -1; - - printk(BIOS_DEBUG, "refcode loading from vboot rw area.\n"); - stage = (void *)(uintptr_t)fwc->address; - - if (rmodule_stage_load(refcode, stage)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - return 0; -} -#else -static int load_refcode_from_vboot(struct rmod_stage_load *refcode) -{ - return -1; -} -#endif - -static int load_refcode_from_cbfs(struct rmod_stage_load *refcode) -{ - printk(BIOS_DEBUG, "refcode loading from cbfs.\n"); - - if (rmodule_stage_load_from_cbfs(refcode)) { - printk(BIOS_DEBUG, "Error loading reference code.\n"); - return -1; - } - - return 0; -} - -static pei_wrapper_entry_t load_reference_code(void) -{ - struct prog prog = { - .name = CONFIG_CBFS_PREFIX "/refcode", - }; - struct rmod_stage_load refcode = { - .cbmem_id = CBMEM_ID_REFCODE, - .prog = &prog, - }; - - if (acpi_is_wakeup_s3()) { - return load_refcode_from_cache(); - } - - if (load_refcode_from_vboot(&refcode) || - load_refcode_from_cbfs(&refcode)) - return NULL; - - /* Cache loaded reference code. */ - cache_refcode(&refcode); - - return prog_entry(&prog); -} - -void broadwell_run_reference_code(void) -{ - int ret, dummy; - struct pei_data pei_data; - pei_wrapper_entry_t entry; - - memset(&pei_data, 0, sizeof(pei_data)); - mainboard_fill_pei_data(&pei_data); - broadwell_fill_pei_data(&pei_data); - - pei_data.boot_mode = acpi_slp_type; - pei_data.saved_data = (void *) &dummy; - - entry = load_reference_code(); - if (entry == NULL) { - printk(BIOS_ERR, "Reference code not found\n"); - return; - } - - /* Call into reference code. */ - ret = entry(&pei_data); - if (ret != 0) { - printk(BIOS_ERR, "Reference code returned %d\n", ret); - return; - } -} diff --git a/src/soc/intel/skylake/reset.c b/src/soc/intel/skylake/reset.c deleted file mode 100644 index a56ec24df0..0000000000 --- a/src/soc/intel/skylake/reset.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/io.h> -#include <halt.h> -#include <reset.h> -#include <soc/reset.h> - -/* - * Soft reset (INIT# to cpu) - write 0x1 to I/O 0x92 - * Soft reset (INIT# to cpu)- write 0x4 to I/0 0xcf9 - * Cold reset (S0->S5->S0) - write 0xe to I/0 0xcf9 - * Warm reset (PLTRST# assertion) - write 0x6 to I/O 0xcf9 - * Global reset (S0->S5->S0 with ME reset) - write 0x6 or 0xe to 0xcf9 but - * with ETR[20] set. - */ - -void soft_reset(void) -{ - outb(0x04, 0xcf9); -} - -void hard_reset(void) -{ - outb(0x06, 0xcf9); -} - -void reset_system(void) -{ - hard_reset(); - halt(); -} diff --git a/src/soc/intel/skylake/romstage/Makefile.inc b/src/soc/intel/skylake/romstage/Makefile.inc index ae0f9806fd..52029fcf78 100644 --- a/src/soc/intel/skylake/romstage/Makefile.inc +++ b/src/soc/intel/skylake/romstage/Makefile.inc @@ -1,13 +1,9 @@ -cpu_incs += $(src)/soc/intel/broadwell/romstage/cache_as_ram.inc - romstage-y += cpu.c romstage-y += pch.c romstage-y += power_state.c -romstage-y += raminit.c romstage-y += report_platform.c romstage-y += romstage.c romstage-y += smbus.c romstage-y += spi.c -romstage-y += stack.c romstage-y += systemagent.c -romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart.c +romstage-$(CONFIG_INTEL_PCH_UART_CONSOLE) += uart.c diff --git a/src/soc/intel/skylake/romstage/cache_as_ram.inc b/src/soc/intel/skylake/romstage/cache_as_ram.inc deleted file mode 100644 index a10ca4ca1b..0000000000 --- a/src/soc/intel/skylake/romstage/cache_as_ram.inc +++ /dev/null @@ -1,341 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com> - * Copyright (C) 2007-2008 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cpu/x86/mtrr.h> -#include <cpu/x86/cache.h> -#include <cpu/x86/post_code.h> -#include <cbmem.h> - -/* The full cache-as-ram size includes the cache-as-ram portion from coreboot - * and the space used by the reference code. These 2 values combined should - * be a power of 2 because the MTRR setup assumes that. */ -#define CACHE_AS_RAM_SIZE \ - (CONFIG_DCACHE_RAM_SIZE + CONFIG_DCACHE_RAM_MRC_VAR_SIZE) -#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE -#define CACHE_AS_RAM_LIMIT (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) -#define USBDEBUG_VAR_SIZE 36 /* sizeof(struct ehci_debug_info) */ - -/* Cache 4GB - MRC_SIZE_KB for MRC */ -#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1) -#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES) -#define CACHE_MRC_MASK (~CACHE_MRC_BYTES) - -#define CPU_MAXPHYSADDR CONFIG_CPU_ADDR_BITS -#define CPU_PHYSMASK_HI (1 << (CPU_MAXPHYSADDR - 32) - 1) - -#define NoEvictMod_MSR 0x2e0 - - /* Save the BIST result. */ - movl %eax, %ebp - -cache_as_ram: - post_code(0x20) - - /* Send INIT IPI to all excluding ourself. */ - movl $0x000C4500, %eax - movl $0xFEE00300, %esi - movl %eax, (%esi) - - /* All CPUs need to be in Wait for SIPI state */ -wait_for_sipi: - movl (%esi), %eax - bt $12, %eax - jc wait_for_sipi - - post_code(0x21) - /* Zero out all fixed range and variable range MTRRs. */ - movl $mtrr_table, %esi - movl $((mtrr_table_end - mtrr_table) / 2), %edi - xorl %eax, %eax - xorl %edx, %edx -clear_mtrrs: - movw (%esi), %bx - movzx %bx, %ecx - wrmsr - add $2, %esi - dec %edi - jnz clear_mtrrs - - post_code(0x22) - /* Configure the default memory type to uncacheable. */ - movl $MTRRdefType_MSR, %ecx - rdmsr - andl $(~0x00000cff), %eax - wrmsr - - post_code(0x23) - /* Set Cache-as-RAM base address. */ - movl $(MTRRphysBase_MSR(0)), %ecx - movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax - xorl %edx, %edx - wrmsr - - post_code(0x24) - /* Set Cache-as-RAM mask. */ - movl $(MTRRphysMask_MSR(0)), %ecx - movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax - movl $CPU_PHYSMASK_HI, %edx - wrmsr - - post_code(0x25) - - /* Enable MTRR. */ - movl $MTRRdefType_MSR, %ecx - rdmsr - orl $MTRRdefTypeEn, %eax - wrmsr - - /* Enable cache (CR0.CD = 0, CR0.NW = 0). */ - movl %cr0, %eax - andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax - invd - movl %eax, %cr0 - - /* enable the 'no eviction' mode */ - movl $NoEvictMod_MSR, %ecx - rdmsr - orl $1, %eax - andl $~2, %eax - wrmsr - - /* Clear the cache memory region. This will also fill up the cache */ - movl $CACHE_AS_RAM_BASE, %esi - movl %esi, %edi - movl $(CACHE_AS_RAM_SIZE / 4), %ecx - xorl %eax, %eax - rep stosl - - /* enable the 'no eviction run' state */ - movl $NoEvictMod_MSR, %ecx - rdmsr - orl $3, %eax - wrmsr - - post_code(0x26) - /* Enable Cache-as-RAM mode by disabling cache. */ - movl %cr0, %eax - orl $CR0_CacheDisable, %eax - movl %eax, %cr0 - - /* Enable cache for our code in Flash because we do XIP here */ - movl $MTRRphysBase_MSR(1), %ecx - xorl %edx, %edx - /* - * IMPORTANT: The following calculation _must_ be done at runtime. See - * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html - */ - movl $copy_and_run, %eax - andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax - orl $MTRR_TYPE_WRPROT, %eax - wrmsr - - movl $MTRRphysMask_MSR(1), %ecx - movl $CPU_PHYSMASK_HI, %edx - movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax - wrmsr - - post_code(0x27) -#if CONFIG_CACHE_MRC_BIN - /* Enable caching for ram init code to run faster */ - movl $MTRRphysBase_MSR(2), %ecx - movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax - xorl %edx, %edx - wrmsr - movl $MTRRphysMask_MSR(2), %ecx - movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax - movl $CPU_PHYSMASK_HI, %edx - wrmsr -#endif - - post_code(0x28) - /* Enable cache. */ - movl %cr0, %eax - andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax - movl %eax, %cr0 - - /* Setup the stack. */ - movl $(CACHE_AS_RAM_LIMIT), %eax -#if CONFIG_USBDEBUG - sub $(USBDEBUG_VAR_SIZE), %eax -#endif - movl %eax, %esp - - /* Restore the BIST result. */ - movl %ebp, %eax - - /* Build the call frame. */ - movl %esp, %ebp - movd %mm1, %ebx - pushl %ebx - movd %mm0, %ebx - pushl %ebx - pushl %eax - -before_romstage: - post_code(0x29) - /* Call romstage.c main function. */ - call romstage_main - /* Save return value from romstage_main. It contains the stack to use - * after cache-as-ram is torn down. It also contains the information - * for setting up MTRRs. */ - movl %eax, %ebx - - post_code(0x2f) - - /* Copy global variable space (for USBDEBUG) to memory */ -#if CONFIG_USBDEBUG - cld - movl $(CACHE_AS_RAM_LIMIT - USBDEBUG_VAR_SIZE), %esi - movl $(CONFIG_RAMTOP - USBDEBUG_VAR_SIZE), %edi - movl $USBDEBUG_VAR_SIZE, %ecx - rep movsb -#endif - - post_code(0x30) - - /* Disable cache. */ - movl %cr0, %eax - orl $CR0_CacheDisable, %eax - movl %eax, %cr0 - - post_code(0x31) - - /* Disable MTRR. */ - movl $MTRRdefType_MSR, %ecx - rdmsr - andl $(~MTRRdefTypeEn), %eax - wrmsr - - post_code(0x31) - - /* Disable the no eviction run state */ - movl $NoEvictMod_MSR, %ecx - rdmsr - andl $~2, %eax - wrmsr - - invd - - /* Disable the no eviction mode */ - rdmsr - andl $~1, %eax - wrmsr - -#if CONFIG_CACHE_MRC_BIN - /* Clear MTRR that was used to cache MRC */ - xorl %eax, %eax - xorl %edx, %edx - movl $MTRRphysBase_MSR(2), %ecx - wrmsr - movl $MTRRphysMask_MSR(2), %ecx - wrmsr -#endif - - post_code(0x33) - - /* Enable cache. */ - movl %cr0, %eax - andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax - movl %eax, %cr0 - - post_code(0x36) - - /* Disable cache. */ - movl %cr0, %eax - orl $CR0_CacheDisable, %eax - movl %eax, %cr0 - - post_code(0x38) - - /* Setup stack as indicated by return value from ramstage_main(). */ - movl %ebx, %esp - - /* Get number of MTRRs. */ - popl %ebx - movl $MTRRphysBase_MSR(0), %ecx -1: - testl %ebx, %ebx - jz 1f - - /* Low 32 bits of MTRR base. */ - popl %eax - /* Upper 32 bits of MTRR base. */ - popl %edx - /* Write MTRR base. */ - wrmsr - inc %ecx - /* Low 32 bits of MTRR mask. */ - popl %eax - /* Upper 32 bits of MTRR mask. */ - popl %edx - /* Write MTRR mask. */ - wrmsr - inc %ecx - - dec %ebx - jmp 1b -1: - post_code(0x39) - - /* And enable cache again after setting MTRRs. */ - movl %cr0, %eax - andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax - movl %eax, %cr0 - - post_code(0x3a) - - /* Enable MTRR. */ - movl $MTRRdefType_MSR, %ecx - rdmsr - orl $MTRRdefTypeEn, %eax - wrmsr - - post_code(0x3b) - - /* Invalidate the cache again. */ - invd - - post_code(0x3c) - -__main: - post_code(POST_PREPARE_RAMSTAGE) - cld /* Clear direction flag. */ - call romstage_after_car - -.Lhlt: - post_code(POST_DEAD_CODE) - hlt - jmp .Lhlt - -mtrr_table: - /* Fixed MTRRs */ - .word 0x250, 0x258, 0x259 - .word 0x268, 0x269, 0x26A - .word 0x26B, 0x26C, 0x26D - .word 0x26E, 0x26F - /* Variable MTRRs */ - .word 0x200, 0x201, 0x202, 0x203 - .word 0x204, 0x205, 0x206, 0x207 - .word 0x208, 0x209, 0x20A, 0x20B - .word 0x20C, 0x20D, 0x20E, 0x20F - .word 0x210, 0x211, 0x212, 0x213 -mtrr_table_end: - diff --git a/src/soc/intel/skylake/romstage/cpu.c b/src/soc/intel/skylake/romstage/cpu.c index af175be86f..ba472a9d78 100644 --- a/src/soc/intel/skylake/romstage/cpu.c +++ b/src/soc/intel/skylake/romstage/cpu.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/cpu.h> @@ -34,7 +35,7 @@ void set_max_freq(void) { msr_t msr, perf_ctl, platform_info; - /* Check for configurable TDP option */ + /* Check for configurable TDP option */ platform_info = rdmsr(MSR_PLATFORM_INFO); if ((platform_info.hi >> 1) & 3) { @@ -51,5 +52,5 @@ void set_max_freq(void) wrmsr(IA32_PERF_CTL, perf_ctl); printk(BIOS_DEBUG, "CPU: frequency set to %d MHz\n", - ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); } diff --git a/src/soc/intel/skylake/romstage/pch.c b/src/soc/intel/skylake/romstage/pch.c index 6fa6c395e2..9ca83b3aaa 100644 --- a/src/soc/intel/skylake/romstage/pch.c +++ b/src/soc/intel/skylake/romstage/pch.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,10 +15,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> +#include <chip.h> #include <console/console.h> #include <device/device.h> #include <device/pci_def.h> @@ -25,97 +27,25 @@ #include <soc/iomap.h> #include <soc/lpc.h> #include <soc/pch.h> +#include <soc/pcr.h> #include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/rcba.h> +#include <soc/pmc.h> #include <soc/romstage.h> #include <soc/smbus.h> -#include <soc/intel/broadwell/chip.h> - -const struct reg_script pch_early_init_script[] = { - /* Setup southbridge BARs */ - REG_PCI_WRITE32(RCBA, RCBA_BASE_ADDRESS | 1), - REG_PCI_WRITE32(PMBASE, ACPI_BASE_ADDRESS | 1), - REG_PCI_WRITE8(ACPI_CNTL, ACPI_EN), - REG_PCI_WRITE32(GPIO_BASE, GPIO_BASE_ADDRESS | 1), - REG_PCI_WRITE8(GPIO_CNTL, GPIO_EN), - - /* Set COM1/COM2 decode range */ - REG_PCI_WRITE16(LPC_IO_DEC, 0x0010), - /* Enable legacy decode ranges */ - REG_PCI_WRITE16(LPC_EN, CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | - COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN), - - /* Enable IOAPIC */ - REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + OIC, 0x0100), - /* Read back for posted write */ - REG_MMIO_READ16(RCBA_BASE_ADDRESS + OIC), - - /* Set HPET address and enable it */ - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + HPTC, ~3, (1 << 7)), - /* Read back for posted write */ - REG_MMIO_READ32(RCBA_BASE_ADDRESS + HPTC), - /* Enable HPET to start counter */ - REG_MMIO_OR32(HPET_BASE_ADDRESS + 0x10, (1 << 0)), - - /* Disable reset */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + GCS, (1 << 5)), - /* TCO timer halt */ - REG_IO_OR16(ACPI_BASE_ADDRESS + TCO1_CNT, TCO_TMR_HLT), - - /* Enable upper 128 bytes of CMOS */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + RC, (1 << 2)), - - /* Disable unused device (always) */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + FD, PCH_DISABLE_ALWAYS), - - REG_SCRIPT_END -}; -const struct reg_script pch_interrupt_init_script[] = { - /* - * GFX INTA -> PIRQA (MSI) - * D28IP_P1IP PCIE INTA -> PIRQA - * D29IP_E1P EHCI INTA -> PIRQD - * D20IP_XHCI XHCI INTA -> PIRQC (MSI) - * D31IP_SIP SATA INTA -> PIRQF (MSI) - * D31IP_SMIP SMBUS INTB -> PIRQG - * D31IP_TTIP THRT INTC -> PIRQA - * D27IP_ZIP HDA INTA -> PIRQG (MSI) - */ - - /* Device interrupt pin register (board specific) */ - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D31IP, - (INTC << D31IP_TTIP) | (NOINT << D31IP_SIP2) | - (INTB << D31IP_SMIP) | (INTA << D31IP_SIP)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D29IP, (INTA << D29IP_E1P)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D28IP, - (INTA << D28IP_P1IP) | (INTC << D28IP_P3IP) | - (INTB << D28IP_P4IP)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D27IP, (INTA << D27IP_ZIP)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D26IP, (INTA << D26IP_E2P)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D22IP, (NOINT << D22IP_MEI1IP)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D20IP, (INTA << D20IP_XHCI)), - - /* Device interrupt route registers */ - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D31IR, /* LPC */ - DIR_ROUTE(PIRQG, PIRQC, PIRQB, PIRQA)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D29IR, /* EHCI */ - DIR_ROUTE(PIRQD, PIRQD, PIRQD, PIRQD)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D28IR, /* PCIE */ - DIR_ROUTE(PIRQA, PIRQB, PIRQC, PIRQD)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D27IR, /* HDA */ - DIR_ROUTE(PIRQG, PIRQG, PIRQG, PIRQG)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D22IR, /* ME */ - DIR_ROUTE(PIRQA, PIRQA, PIRQA, PIRQA)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D21IR, /* SIO */ - DIR_ROUTE(PIRQE, PIRQF, PIRQF, PIRQF)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D20IR, /* XHCI */ - DIR_ROUTE(PIRQC, PIRQC, PIRQC, PIRQC)), - REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + D23IR, /* SDIO */ - DIR_ROUTE(PIRQH, PIRQH, PIRQH, PIRQH)), - - REG_SCRIPT_END +/* Max PXRC registers in ITSS*/ +#define MAX_PXRC_CONFIG 0x08 + +static const u8 pch_interrupt_routing[] = { + 11, /* PARC: PIRQA -> IRQ11 */ + 10, /* PBRC: PIRQB -> IRQ10 */ + 11, /* PCRC: PIRQC -> IRQ11 */ + 11, /* PDRC: PIRQD -> IRQ11 */ + 11, /* PERC: PIRQE -> IRQ11 */ + 11, /* PFRC: PIRQF -> IRQ11 */ + 11, /* PGRC: PIRQG -> IRQ11 */ + 11 /* PHRC: PIRQH -> IRQ11 */ }; static void pch_enable_lpc(void) @@ -123,39 +53,85 @@ static void pch_enable_lpc(void) /* Lookup device tree in romstage */ const struct device *dev; const config_t *config; + u16 lpc_en; + + /* IO Decode Range */ + lpc_en = COMA_RANGE | (COMB_RANGE << 4); + pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, lpc_en); + pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOD, lpc_en); + + /* IO Decode Enable */ + lpc_en = CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | GAMEH_LPC_EN | + COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_en); + pcr_write16(PID_DMI, R_PCH_PCR_DMI_LPCIOE, lpc_en); dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); if (!dev || !dev->chip_info) return; config = dev->chip_info; + /* Set in PCI generic decode range registers */ pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); pci_write_config32(PCH_DEV_LPC, LPC_GEN3_DEC, config->gen3_dec); pci_write_config32(PCH_DEV_LPC, LPC_GEN4_DEC, config->gen4_dec); + + /* Mirror these same settings in DMI PCR */ + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR1, config->gen1_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR2, config->gen2_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR3, config->gen3_dec); + pcr_write32(PID_DMI, R_PCH_PCR_DMI_LPCLGIR4, config->gen4_dec); } -static void pcie_update_cfg(device_t dev, int reg, u32 mask, u32 or) +static void pch_device_init(void) { + device_t dev; u32 reg32; + u16 tcobase; + u16 tcocnt; + + dev = PCH_DEV_PMC; - reg32 = pci_read_config32(dev, reg); - reg32 &= mask; - reg32 |= or; - pci_write_config32(dev, reg, reg32); + /* Enable ACPI and PMC mmio regs in PMC Config */ + reg32 = pci_read_config32(dev, ACTL); + reg32 |= ACPI_EN | PWRM_EN; + pci_write_config32(dev, ACTL, reg32); + + /* TCO timer halt */ + tcobase = pmc_tco_regs(); + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_TMR_HLT; + outw(tcocnt, tcobase + TCO1_CNT); + + /* Enable upper 128 bytes of CMOS */ + pcr_andthenor32(PID_RTC, R_PCH_PCR_RTC_CONF, (u32)~0, + B_PCH_PCR_RTC_CONF_UCMOS_EN); +} + +static void pch_interrupt_init(void) +{ + u8 index = 0; + + for (index = 0; index < MAX_PXRC_CONFIG; index++) { + if (pch_interrupt_routing[index] < 16 && + pch_interrupt_routing[index] > 2 && + pch_interrupt_routing[index] != 8 && + pch_interrupt_routing[index] != 13) { + pcr_write8(PID_ITSS, + (R_PCH_PCR_ITSS_PIRQA_ROUT + index), + pch_interrupt_routing[index]); + } + } } void pch_early_init(void) { - reg_script_run_on_dev(PCH_DEV_LPC, pch_early_init_script); - reg_script_run_on_dev(PCH_DEV_LPC, pch_interrupt_init_script); + pch_device_init(); + + pch_interrupt_init(); pch_enable_lpc(); enable_smbus(); - - /* 8.14 Additional PCI Express Programming Steps, step #1 */ - pcie_update_cfg(_PCH_DEV(PCIE, 0), 0xf4, ~0x60, 0); - pcie_update_cfg(_PCH_DEV(PCIE, 0), 0xf4, ~0x80, 0x80); - pcie_update_cfg(_PCH_DEV(PCIE, 0), 0xe2, ~0x30, 0x30); } diff --git a/src/soc/intel/skylake/romstage/power_state.c b/src/soc/intel/skylake/romstage/power_state.c index bdb3da9c3b..7a6c8b3960 100644 --- a/src/soc/intel/skylake/romstage/power_state.c +++ b/src/soc/intel/skylake/romstage/power_state.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/early_variables.h> @@ -29,14 +30,14 @@ #include <stdlib.h> #include <string.h> #include <soc/iomap.h> -#include <soc/lpc.h> +#include <soc/pmc.h> #include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/romstage.h> static struct chipset_power_state power_state CAR_GLOBAL; -static void migrate_power_state(void) +static void migrate_power_state(int is_recovery) { struct chipset_power_state *ps_cbmem; struct chipset_power_state *ps_car; @@ -50,7 +51,7 @@ static void migrate_power_state(void) } memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem)); } -CAR_MIGRATE(migrate_power_state); +ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state) /* Return 0, 3, or 5 to indicate the previous sleep state. */ static int prev_sleep_state(struct chipset_power_state *ps) @@ -60,7 +61,7 @@ static int prev_sleep_state(struct chipset_power_state *ps) if (ps->pm1_sts & WAK_STS) { switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) { -#if CONFIG_HAVE_ACPI_RESUME +#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) case SLP_TYP_S3: prev_sleep_state = SLEEP_STATE_S3; break; @@ -73,7 +74,7 @@ static int prev_sleep_state(struct chipset_power_state *ps) outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); } - if (ps->gen_pmcon3 & (PWR_FLR | SUS_PWR_FLR)) + if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)) prev_sleep_state = SLEEP_STATE_S5; return prev_sleep_state; @@ -94,8 +95,8 @@ static void dump_power_state(struct chipset_power_state *ps) ps->gpe0_en[0], ps->gpe0_en[1], ps->gpe0_en[2], ps->gpe0_en[3]); - printk(BIOS_DEBUG, "GEN_PMCON: %04x %04x %04x\n", - ps->gen_pmcon1, ps->gen_pmcon2, ps->gen_pmcon3); + printk(BIOS_DEBUG, "GEN_PMCON: %04x %04x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); printk(BIOS_DEBUG, "Previous Sleep State: S%d\n", ps->prev_sleep_state); @@ -104,13 +105,16 @@ static void dump_power_state(struct chipset_power_state *ps) /* Fill power state structure from ACPI PM registers */ struct chipset_power_state *fill_power_state(void) { + uint16_t tcobase; struct chipset_power_state *ps = car_get_var_ptr(&power_state); + tcobase = pmc_tco_regs(); + ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN); ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); - ps->tco1_sts = inw(ACPI_BASE_ADDRESS + TCO1_STS); - ps->tco2_sts = inw(ACPI_BASE_ADDRESS + TCO2_STS); + ps->tco1_sts = inw(tcobase + TCO1_STS); + ps->tco2_sts = inw(tcobase + TCO2_STS); ps->gpe0_sts[0] = inl(ACPI_BASE_ADDRESS + GPE0_STS(0)); ps->gpe0_sts[1] = inl(ACPI_BASE_ADDRESS + GPE0_STS(1)); ps->gpe0_sts[2] = inl(ACPI_BASE_ADDRESS + GPE0_STS(2)); @@ -120,9 +124,8 @@ struct chipset_power_state *fill_power_state(void) ps->gpe0_en[2] = inl(ACPI_BASE_ADDRESS + GPE0_EN(2)); ps->gpe0_en[3] = inl(ACPI_BASE_ADDRESS + GPE0_EN(3)); - ps->gen_pmcon1 = pci_read_config16(PCH_DEV_LPC, GEN_PMCON_1); - ps->gen_pmcon2 = pci_read_config16(PCH_DEV_LPC, GEN_PMCON_2); - ps->gen_pmcon3 = pci_read_config16(PCH_DEV_LPC, GEN_PMCON_3); + ps->gen_pmcon_a = pci_read_config16(PCH_DEV_PMC, GEN_PMCON_A); + ps->gen_pmcon_b = pci_read_config16(PCH_DEV_PMC, GEN_PMCON_B); ps->prev_sleep_state = prev_sleep_state(ps); diff --git a/src/soc/intel/skylake/romstage/raminit.c b/src/soc/intel/skylake/romstage/raminit.c deleted file mode 100644 index 52ea49100d..0000000000 --- a/src/soc/intel/skylake/romstage/raminit.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/cbfs.h> -#include <arch/io.h> -#include <cbfs.h> -#include <cbmem.h> -#include <console/console.h> -#include <device/pci_def.h> -#include <lib.h> -#include <string.h> -#if CONFIG_EC_GOOGLE_CHROMEEC -#include <ec/google/chromeec/ec.h> -#include <ec/google/chromeec/ec_commands.h> -#endif -#include <stage_cache.h> -#include <vendorcode/google/chromeos/chromeos.h> -#include <soc/intel/common/mrc_cache.h> -#include <soc/iomap.h> -#include <soc/pei_data.h> -#include <soc/pei_wrapper.h> -#include <soc/pm.h> -#include <soc/reset.h> -#include <soc/romstage.h> -#include <soc/smm.h> -#include <soc/systemagent.h> - -/* - * Find PEI executable in coreboot filesystem and execute it. - */ -void raminit(struct pei_data *pei_data) -{ - const struct mrc_saved_data *cache; - struct memory_info* mem_info; - pei_wrapper_entry_t entry; - int ret; - - broadwell_fill_pei_data(pei_data); - - if (recovery_mode_enabled()) { - /* Recovery mode does not use MRC cache */ - printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n"); - } else if (!mrc_cache_get_current(&cache)) { - /* MRC cache found */ - pei_data->saved_data_size = cache->size; - pei_data->saved_data = &cache->data[0]; - } else if (pei_data->boot_mode == SLEEP_STATE_S3) { - /* Waking from S3 and no cache. */ - printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n"); - post_code(POST_RESUME_FAILURE); - reset_system(); - } else { - printk(BIOS_DEBUG, "No MRC cache found.\n"); -#if CONFIG_EC_GOOGLE_CHROMEEC - if (pei_data->boot_mode == SLEEP_STATE_S0) { - /* Ensure EC is running RO firmware. */ - google_chromeec_check_ec_image(EC_IMAGE_RO); - } -#endif - } - - /* - * Do not use saved pei data. Can be set by mainboard romstage - * to force a full train of memory on every boot. - */ - if (pei_data->disable_saved_data) { - printk(BIOS_DEBUG, "Disabling PEI saved data by request\n"); - pei_data->saved_data = NULL; - pei_data->saved_data_size = 0; - } - - /* Determine if mrc.bin is in the cbfs. */ - entry = (pei_wrapper_entry_t)cbfs_get_file_content( - CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC, NULL); - if (entry == NULL) { - printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); - return; - } - - printk(BIOS_DEBUG, "Starting Memory Reference Code\n"); - - ret = entry(pei_data); - if (ret < 0) - die("pei_data version mismatch\n"); - - /* Print the MRC version after executing the UEFI PEI stage. */ - u32 version = MCHBAR32(MCHBAR_PEI_VERSION); - printk(BIOS_DEBUG, "MRC Version %d.%d.%d Build %d\n", - version >> 24 , (version >> 16) & 0xff, - (version >> 8) & 0xff, version & 0xff); - - report_memory_config(); - - /* Basic memory sanity test */ - quick_ram_check(); - - if (pei_data->boot_mode != SLEEP_STATE_S3) { - cbmem_initialize_empty(); - stage_cache_create_empty(); - } else { - stage_cache_recover(); - if (cbmem_initialize()) { -#if CONFIG_HAVE_ACPI_RESUME - printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n"); - /* Failed S3 resume, reset to come up cleanly */ - reset_system(); -#endif - } - } - - printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save, - pei_data->data_to_save_size); - - if (pei_data->data_to_save != NULL && pei_data->data_to_save_size > 0) - mrc_cache_stash_data(pei_data->data_to_save, - pei_data->data_to_save_size); - - printk(BIOS_DEBUG, "create cbmem for dimm information\n"); - mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info)); - memcpy(mem_info, &pei_data->meminfo, sizeof(struct memory_info)); - -} diff --git a/src/soc/intel/skylake/romstage/report_platform.c b/src/soc/intel/skylake/romstage/report_platform.c index 713b3e7abf..fe1a785d22 100644 --- a/src/soc/intel/skylake/romstage/report_platform.c +++ b/src/soc/intel/skylake/romstage/report_platform.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,77 +15,55 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/cpu.h> #include <arch/io.h> #include <console/console.h> -#include <device/pci.h> -#include <string.h> #include <cpu/x86/msr.h> +#include <device/pci.h> #include <soc/cpu.h> #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/romstage.h> #include <soc/systemagent.h> +#include <string.h> static struct { u32 cpuid; const char *name; } cpu_table[] = { - { CPUID_HASWELL_A0, "Haswell A0" }, - { CPUID_HASWELL_B0, "Haswell B0" }, - { CPUID_HASWELL_C0, "Haswell C0" }, - { CPUID_HASWELL_ULT_B0, "Haswell ULT B0" }, - { CPUID_HASWELL_ULT, "Haswell ULT C0 or D0" }, - { CPUID_HASWELL_HALO, "Haswell Perf Halo" }, - { CPUID_BROADWELL_C0, "Broadwell C0" }, - { CPUID_BROADWELL_D0, "Broadwell D0" }, - { CPUID_BROADWELL_E0, "Broadwell E0 or F0" }, + { CPUID_SKYLAKE_C0, "Skylake C0" }, + { CPUID_SKYLAKE_D0, "Skylake D0" }, }; static struct { - u8 revid; + u16 mchid; const char *name; -} mch_rev_table[] = { - { MCH_BROADWELL_REV_D0, "Broadwell D0" }, - { MCH_BROADWELL_REV_E0, "Broadwell E0" }, - { MCH_BROADWELL_REV_F0, "Broadwell F0" }, +} mch_table[] = { + { MCH_SKYLAKE_ID_U, "Skylake-U" }, + { MCH_SKYLAKE_ID_Y, "Skylake-Y" }, + { MCH_SKYLAKE_ID_ULX, "Skylake-ULX" }, }; static struct { u16 lpcid; const char *name; } pch_table[] = { - { PCH_LPT_LP_SAMPLE, "LynxPoint LP Sample" }, - { PCH_LPT_LP_PREMIUM, "LynxPoint LP Premium" }, - { PCH_LPT_LP_MAINSTREAM, "LynxPoint LP Mainstream" }, - { PCH_LPT_LP_VALUE, "LynxPoint LP Value" }, - { PCH_WPT_HSW_U_SAMPLE, "Haswell U Sample" }, - { PCH_WPT_BDW_U_SAMPLE, "Broadwell U Sample" }, - { PCH_WPT_BDW_U_PREMIUM, "Broadwell U Premium" }, - { PCH_WPT_BDW_U_BASE, "Broadwell U Base" }, - { PCH_WPT_BDW_Y_SAMPLE, "Broadwell Y Sample" }, - { PCH_WPT_BDW_Y_PREMIUM, "Broadwell Y Premium" }, - { PCH_WPT_BDW_Y_BASE, "Broadwell Y Base" }, - { PCH_WPT_BDW_H, "Broadwell H" }, + { PCH_SPT_LP_SAMPLE, "Skylake LP Sample" }, + { PCH_SPT_LP_U_BASE, "Skylake-U Base" }, + { PCH_SPT_LP_U_PREMIUM, "Skylake-U Premium" }, + { PCH_SPT_LP_Y_PREMIUM, "Skylake-Y Premium" }, }; static struct { u16 igdid; const char *name; } igd_table[] = { - { IGD_HASWELL_ULT_GT1, "Haswell ULT GT1" }, - { IGD_HASWELL_ULT_GT2, "Haswell ULT GT2" }, - { IGD_HASWELL_ULT_GT3, "Haswell ULT GT3" }, - { IGD_BROADWELL_U_GT1, "Broadwell U GT1" }, - { IGD_BROADWELL_U_GT2, "Broadwell U GT2" }, - { IGD_BROADWELL_U_GT3_15W, "Broadwell U GT3 (15W)" }, - { IGD_BROADWELL_U_GT3_28W, "Broadwell U GT3 (28W)" }, - { IGD_BROADWELL_Y_GT2, "Broadwell Y GT2" }, - { IGD_BROADWELL_H_GT2, "Broadwell U GT2" }, - { IGD_BROADWELL_H_GT3, "Broadwell U GT3" }, + { IGD_SKYLAKE_GT1_SULTM, "Skylake ULT GT1"}, + { IGD_SKYLAKE_GT2_SULXM, "Skylake ULX GT2" }, + { IGD_SKYLAKE_GT2_SULTM, "Skylake ULT GT2" }, }; static void report_cpu_info(void) @@ -102,8 +81,8 @@ static void report_cpu_info(void) if (cpuidr.eax < 0x80000004) { strcpy(cpu_string, "Platform info not available"); } else { - u32 *p = (u32*) cpu_string; - for (i = 2; i <= 4 ; i++) { + u32 *p = (u32 *) cpu_string; + for (i = 2; i <= 4; i++) { cpuidr = cpuid(index + i); *p++ = cpuidr.eax; *p++ = cpuidr.ebx; @@ -136,29 +115,27 @@ static void report_cpu_info(void) aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0; txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0; vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0; - printk(BIOS_DEBUG, "CPU: AES %ssupported, TXT %ssupported, " - "VT %ssupported\n", mode[aes], mode[txt], mode[vt]); + printk(BIOS_DEBUG, + "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n", + mode[aes], mode[txt], mode[vt]); } static void report_mch_info(void) { int i; - u16 mch_device = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID); + u16 mchid = pci_read_config16(SA_DEV_ROOT, PCI_DEVICE_ID); u8 mch_revision = pci_read_config8(SA_DEV_ROOT, PCI_REVISION_ID); const char *mch_type = "Unknown"; - /* Look for string to match the revision for Broadwell U/Y */ - if (mch_device == MCH_BROADWELL_ID_U_Y) { - for (i = 0; i < ARRAY_SIZE(mch_rev_table); i++) { - if (mch_rev_table[i].revid == mch_revision) { - mch_type = mch_rev_table[i].name; - break; - } + for (i = 0; i < ARRAY_SIZE(mch_table); i++) { + if (mch_table[i].mchid == mchid) { + mch_type = mch_table[i].name; + break; } } printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n", - mch_device, mch_revision, mch_type); + mchid, mch_revision, mch_type); } static void report_pch_info(void) diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index c026004eaf..e8bb877230 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <stddef.h> @@ -24,141 +25,542 @@ #include <arch/cbfs.h> #include <arch/stages.h> #include <arch/early_variables.h> -#include <console/console.h> -#include <cbfs.h> #include <cbmem.h> +#include <chip.h> +#include <console/console.h> #include <cpu/x86/mtrr.h> +#include <device/device.h> +#include <device/pci_def.h> #include <elog.h> +#include <reset.h> #include <romstage_handoff.h> -#include <stage_cache.h> -#include <timestamp.h> -#include <soc/me.h> -#include <soc/pei_data.h> +#include <soc/pci_devs.h> +#include <soc/pei_wrapper.h> #include <soc/pm.h> -#include <soc/reset.h> +#include <soc/serialio.h> #include <soc/romstage.h> #include <soc/spi.h> +#include <stage_cache.h> +#include <timestamp.h> #include <vendorcode/google/chromeos/chromeos.h> -/* Entry from cache-as-ram.inc. */ -void * asmlinkage romstage_main(unsigned long bist, - uint32_t tsc_low, uint32_t tsc_hi) +/* SOC initialization before the console is enabled */ +void soc_pre_console_init(struct romstage_params *params) { - struct romstage_params rp = { - .bist = bist, - .pei_data = NULL, - }; - - post_code(0x30); - - /* Save initial timestamp from bootblock. */ - timestamp_init((((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low); - - /* Save romstage begin */ - timestamp_add_now(TS_START_ROMSTAGE); - /* System Agent Early Initialization */ systemagent_early_init(); - /* PCH Early Initialization */ - pch_early_init(); - - /* Call into mainboard pre console init. Needed to enable serial port - on IT8772 */ - mainboard_pre_console_init(); - - /* Start console drivers */ - console_init(); - - /* Get power state */ - rp.power_state = fill_power_state(); - - /* Print useful platform information */ - report_platform_info(); - - /* Set CPU frequency to maximum */ - set_max_freq(); - - /* Call into mainboard. */ - mainboard_romstage_entry(&rp); - -#if CONFIG_CHROMEOS - save_chromeos_gpios(); -#endif - - return setup_stack_and_mttrs(); + if (IS_ENABLED(CONFIG_INTEL_PCH_UART_CONSOLE)) + pch_uart_init(); } -static inline void chromeos_init(int prev_sleep_state) +/* SOC initialization before RAM is enabled */ +void soc_pre_ram_init(struct romstage_params *params) { -#if CONFIG_CHROMEOS - /* Normalize the sleep state to what init_chromeos() wants for S3: 2 */ - init_chromeos(prev_sleep_state == SLEEP_STATE_S3 ? 2 : 0); -#endif + /* Prepare to initialize memory */ + soc_fill_pei_data(params->pei_data); } -/* Entry from the mainboard. */ -void romstage_common(struct romstage_params *params) +void soc_romstage_init(struct romstage_params *params) { - struct romstage_handoff *handoff; - - post_code(0x32); - - timestamp_add_now(TS_BEFORE_INITRAM); - - params->pei_data->boot_mode = params->power_state->prev_sleep_state; - -#if CONFIG_ELOG_BOOT_COUNT - if (params->power_state->prev_sleep_state != SLEEP_STATE_S3) - boot_count_increment(); -#endif - - /* Print ME state before MRC */ - intel_me_status(); - - /* Save ME HSIO version */ - intel_me_hsio_version(¶ms->power_state->hsio_version, - ¶ms->power_state->hsio_checksum); - - /* Initialize RAM */ - raminit(params->pei_data); - - timestamp_add_now(TS_AFTER_INITRAM); - - handoff = romstage_handoff_find_or_add(); - if (handoff != NULL) - handoff->s3_resume = (params->power_state->prev_sleep_state == - SLEEP_STATE_S3); - else - printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); - - chromeos_init(params->power_state->prev_sleep_state); + pch_early_init(); } -void asmlinkage romstage_after_car(void) +#if IS_ENABLED(CONFIG_CHROMEOS) +int vboot_get_sw_write_protect(void) { - timestamp_add_now(TS_END_ROMSTAGE); + u8 status; - /* Load the ramstage. */ - copy_and_run(); - while (1); + /* Return unprotected status if status read fails. */ + return early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80); } +#endif -void ramstage_cache_invalid(void) +/* UPD parameters to be initialized before MemoryInit */ +void soc_memory_init_params(MEMORY_INIT_UPD *params) { -#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE - /* Perform cold reset on invalid ramstage cache. */ - reset_system(); -#endif + const struct device *dev; + const struct soc_intel_skylake_config *config; + int i; + + /* Set the parameters for MemoryInit */ + dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0)); + config = dev->chip_info; + + for (i = 0; i < PchSerialIoIndexMax; i++) + params->SerialIoDevMode[i] = config->SerialIoDevMode[i]; + + params->MmioSize = 0x800; /* 2GB in MB */ + params->TsegSize = CONFIG_SMM_TSEG_SIZE; + params->IedSize = config->IedSize; + params->ProbelessTrace = config->ProbelessTrace; + params->EnableLan = config->EnableLan; + params->EnableSata = config->EnableSata; + params->SataMode = config->SataMode; + params->SataSalpSupport = config->SataSalpSupport; + params->SataPortsEnable[0] = config->SataPortsEnable[0]; + params->SsicPortEnable = config->SsicPortEnable; + params->EnableTraceHub = config->EnableTraceHub; + params->SmbusEnable = config->SmbusEnable; + params->Cio2Enable = config->Cio2Enable; + params->ScsEmmcEnabled = config->ScsEmmcEnabled; + params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled; + params->ScsSdCardEnabled = config->ScsSdCardEnabled; + params->IshEnable = 0; + params->EnableAzalia = config->EnableAzalia; + params->IoBufferOwnership = config->IoBufferOwnership; + params->DspEnable = config->DspEnable; + params->XdciEnable = config->XdciEnable; } -#if CONFIG_CHROMEOS -int vboot_get_sw_write_protect(void) +void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, + MEMORY_INIT_UPD *new) { - u8 status; - /* Return unprotected status if status read fails. */ - return (early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80)); + /* Display the parameters for MemoryInit */ + printk(BIOS_SPEW, "UPD values for MemoryInit:\n"); + + soc_display_upd_value("PlatformMemorySize", 8, + old->PlatformMemorySize, new->PlatformMemorySize); + soc_display_upd_value("MemorySpdPtr00", 4, old->MemorySpdPtr00, + new->MemorySpdPtr00); + soc_display_upd_value("MemorySpdPtr01", 4, old->MemorySpdPtr01, + new->MemorySpdPtr01); + soc_display_upd_value("MemorySpdPtr10", 4, old->MemorySpdPtr10, + new->MemorySpdPtr10); + soc_display_upd_value("MemorySpdPtr11", 4, old->MemorySpdPtr11, + new->MemorySpdPtr11); + soc_display_upd_value("MemorySpdDataLen", 2, old->MemorySpdDataLen, + new->MemorySpdDataLen); + soc_display_upd_value("DqByteMapCh0[0]", 1, old->DqByteMapCh0[0], + new->DqByteMapCh0[0]); + soc_display_upd_value("DqByteMapCh0[1]", 1, old->DqByteMapCh0[1], + new->DqByteMapCh0[1]); + soc_display_upd_value("DqByteMapCh0[2]", 1, old->DqByteMapCh0[2], + new->DqByteMapCh0[2]); + soc_display_upd_value("DqByteMapCh0[3]", 1, old->DqByteMapCh0[3], + new->DqByteMapCh0[3]); + soc_display_upd_value("DqByteMapCh0[4]", 1, old->DqByteMapCh0[4], + new->DqByteMapCh0[4]); + soc_display_upd_value("DqByteMapCh0[5]", 1, old->DqByteMapCh0[5], + new->DqByteMapCh0[5]); + soc_display_upd_value("DqByteMapCh0[6]", 1, old->DqByteMapCh0[6], + new->DqByteMapCh0[6]); + soc_display_upd_value("DqByteMapCh0[7]", 1, old->DqByteMapCh0[7], + new->DqByteMapCh0[7]); + soc_display_upd_value("DqByteMapCh0[8]", 1, old->DqByteMapCh0[8], + new->DqByteMapCh0[8]); + soc_display_upd_value("DqByteMapCh0[9]", 1, old->DqByteMapCh0[9], + new->DqByteMapCh0[9]); + soc_display_upd_value("DqByteMapCh0[10]", 1, old->DqByteMapCh0[10], + new->DqByteMapCh0[10]); + soc_display_upd_value("DqByteMapCh0[11]", 1, old->DqByteMapCh0[11], + new->DqByteMapCh0[11]); + soc_display_upd_value("DqByteMapCh1[0]", 1, old->DqByteMapCh1[0], + new->DqByteMapCh1[0]); + soc_display_upd_value("DqByteMapCh1[1]", 1, old->DqByteMapCh1[1], + new->DqByteMapCh1[1]); + soc_display_upd_value("DqByteMapCh1[2]", 1, old->DqByteMapCh1[2], + new->DqByteMapCh1[2]); + soc_display_upd_value("DqByteMapCh1[3]", 1, old->DqByteMapCh1[3], + new->DqByteMapCh1[3]); + soc_display_upd_value("DqByteMapCh1[4]", 1, old->DqByteMapCh1[4], + new->DqByteMapCh1[4]); + soc_display_upd_value("DqByteMapCh1[5]", 1, old->DqByteMapCh1[5], + new->DqByteMapCh1[5]); + soc_display_upd_value("DqByteMapCh1[6]", 1, old->DqByteMapCh1[6], + new->DqByteMapCh1[6]); + soc_display_upd_value("DqByteMapCh1[7]", 1, old->DqByteMapCh1[7], + new->DqByteMapCh1[7]); + soc_display_upd_value("DqByteMapCh1[8]", 1, old->DqByteMapCh1[8], + new->DqByteMapCh1[8]); + soc_display_upd_value("DqByteMapCh1[9]", 1, old->DqByteMapCh1[9], + new->DqByteMapCh1[9]); + soc_display_upd_value("DqByteMapCh1[10]", 1, old->DqByteMapCh1[10], + new->DqByteMapCh1[10]); + soc_display_upd_value("DqByteMapCh1[11]", 1, old->DqByteMapCh1[11], + new->DqByteMapCh1[11]); + soc_display_upd_value("DqsMapCpu2DramCh0[0]", 1, + old->DqsMapCpu2DramCh0[0], new->DqsMapCpu2DramCh0[0]); + soc_display_upd_value("DqsMapCpu2DramCh0[1]", 1, + old->DqsMapCpu2DramCh0[1], new->DqsMapCpu2DramCh0[1]); + soc_display_upd_value("DqsMapCpu2DramCh0[2]", 1, + old->DqsMapCpu2DramCh0[2], new->DqsMapCpu2DramCh0[2]); + soc_display_upd_value("DqsMapCpu2DramCh0[3]", 1, + old->DqsMapCpu2DramCh0[3], new->DqsMapCpu2DramCh0[3]); + soc_display_upd_value("DqsMapCpu2DramCh0[4]", 1, + old->DqsMapCpu2DramCh0[4], new->DqsMapCpu2DramCh0[4]); + soc_display_upd_value("DqsMapCpu2DramCh0[5]", 1, + old->DqsMapCpu2DramCh0[5], new->DqsMapCpu2DramCh0[5]); + soc_display_upd_value("DqsMapCpu2DramCh0[6]", 1, + old->DqsMapCpu2DramCh0[6], new->DqsMapCpu2DramCh0[6]); + soc_display_upd_value("DqsMapCpu2DramCh0[7]", 1, + old->DqsMapCpu2DramCh0[7], new->DqsMapCpu2DramCh0[7]); + soc_display_upd_value("DqsMapCpu2DramCh1[0]", 1, + old->DqsMapCpu2DramCh1[0], new->DqsMapCpu2DramCh1[0]); + soc_display_upd_value("DqsMapCpu2DramCh1[1]", 1, + old->DqsMapCpu2DramCh1[1], new->DqsMapCpu2DramCh1[1]); + soc_display_upd_value("DqsMapCpu2DramCh1[2]", 1, + old->DqsMapCpu2DramCh1[2], new->DqsMapCpu2DramCh1[2]); + soc_display_upd_value("DqsMapCpu2DramCh1[3]", 1, + old->DqsMapCpu2DramCh1[3], new->DqsMapCpu2DramCh1[3]); + soc_display_upd_value("DqsMapCpu2DramCh1[4]", 1, + old->DqsMapCpu2DramCh1[4], new->DqsMapCpu2DramCh1[4]); + soc_display_upd_value("DqsMapCpu2DramCh1[5]", 1, + old->DqsMapCpu2DramCh1[5], new->DqsMapCpu2DramCh1[5]); + soc_display_upd_value("DqsMapCpu2DramCh1[6]", 1, + old->DqsMapCpu2DramCh1[6], new->DqsMapCpu2DramCh1[6]); + soc_display_upd_value("DqsMapCpu2DramCh1[7]", 1, + old->DqsMapCpu2DramCh1[7], new->DqsMapCpu2DramCh1[7]); + soc_display_upd_value("DqPinsInterleaved", 1, + old->DqPinsInterleaved, new->DqPinsInterleaved); + soc_display_upd_value("RcompResistor[0]", 2, old->RcompResistor[0], + new->RcompResistor[0]); + soc_display_upd_value("RcompResistor[1]", 2, old->RcompResistor[1], + new->RcompResistor[1]); + soc_display_upd_value("RcompResistor[2]", 2, old->RcompResistor[2], + new->RcompResistor[2]); + soc_display_upd_value("RcompTarget[0]", 1, old->RcompTarget[0], + new->RcompTarget[0]); + soc_display_upd_value("RcompTarget[1]", 1, old->RcompTarget[1], + new->RcompTarget[1]); + soc_display_upd_value("RcompTarget[2]", 1, old->RcompTarget[2], + new->RcompTarget[2]); + soc_display_upd_value("RcompTarget[3]", 1, old->RcompTarget[3], + new->RcompTarget[3]); + soc_display_upd_value("RcompTarget[4]", 1, old->RcompTarget[4], + new->RcompTarget[4]); + soc_display_upd_value("CaVrefConfig", 1, old->CaVrefConfig, + new->CaVrefConfig); + soc_display_upd_value("SmramMask", 1, old->SmramMask, new->SmramMask); + soc_display_upd_value("MrcFastBoot", 1, old->MrcFastBoot, + new->MrcFastBoot); + soc_display_upd_value("IedSize", 4, old->IedSize, new->IedSize); + soc_display_upd_value("TsegSize", 4, old->TsegSize, new->TsegSize); + soc_display_upd_value("MmioSize", 2, old->MmioSize, new->MmioSize); + soc_display_upd_value("ProbelessTrace", 1, old->ProbelessTrace, + new->ProbelessTrace); + soc_display_upd_value("EnableLan", 1, old->EnableLan, new->EnableLan); + soc_display_upd_value("EnableSata", 1, old->EnableSata, + new->EnableSata); + soc_display_upd_value("SataMode", 1, old->SataMode, new->SataMode); + soc_display_upd_value("SataSalpSupport", 1, old->SataSalpSupport, + new->SataSalpSupport); + soc_display_upd_value("SataPortsEnable[0]", 1, old->SataPortsEnable[0], + new->SataPortsEnable[0]); + soc_display_upd_value("SataPortsEnable[1]", 1, old->SataPortsEnable[1], + new->SataPortsEnable[1]); + soc_display_upd_value("SataPortsEnable[2]", 1, old->SataPortsEnable[2], + new->SataPortsEnable[2]); + soc_display_upd_value("SataPortsEnable[3]", 1, old->SataPortsEnable[3], + new->SataPortsEnable[3]); + soc_display_upd_value("SataPortsEnable[4]", 1, old->SataPortsEnable[4], + new->SataPortsEnable[4]); + soc_display_upd_value("SataPortsEnable[5]", 1, old->SataPortsEnable[5], + new->SataPortsEnable[5]); + soc_display_upd_value("SataPortsEnable[6]", 1, old->SataPortsEnable[6], + new->SataPortsEnable[6]); + soc_display_upd_value("SataPortsEnable[7]", 1, old->SataPortsEnable[7], + new->SataPortsEnable[7]); + soc_display_upd_value("SataPortsDevSlp[0]", 1, old->SataPortsDevSlp[0], + new->SataPortsDevSlp[0]); + soc_display_upd_value("SataPortsDevSlp[1]", 1, old->SataPortsDevSlp[1], + new->SataPortsDevSlp[1]); + soc_display_upd_value("SataPortsDevSlp[2]", 1, old->SataPortsDevSlp[2], + new->SataPortsDevSlp[2]); + soc_display_upd_value("SataPortsDevSlp[3]", 1, old->SataPortsDevSlp[3], + new->SataPortsDevSlp[3]); + soc_display_upd_value("SataPortsDevSlp[4]", 1, old->SataPortsDevSlp[4], + new->SataPortsDevSlp[4]); + soc_display_upd_value("SataPortsDevSlp[5]", 1, old->SataPortsDevSlp[5], + new->SataPortsDevSlp[5]); + soc_display_upd_value("SataPortsDevSlp[6]", 1, old->SataPortsDevSlp[6], + new->SataPortsDevSlp[6]); + soc_display_upd_value("SataPortsDevSlp[7]", 1, old->SataPortsDevSlp[7], + new->SataPortsDevSlp[7]); + soc_display_upd_value("EnableAzalia", 1, old->EnableAzalia, + new->EnableAzalia); + soc_display_upd_value("DspEnable", 1, old->DspEnable, new->DspEnable); + soc_display_upd_value("IoBufferOwnership", 1, old->IoBufferOwnership, + new->IoBufferOwnership); + soc_display_upd_value("EnableTraceHub", 1, old->EnableTraceHub, + new->EnableTraceHub); + soc_display_upd_value("PcieRpEnable[0]", 1, old->PcieRpEnable[0], + new->PcieRpEnable[0]); + soc_display_upd_value("PcieRpEnable[1]", 1, old->PcieRpEnable[1], + new->PcieRpEnable[1]); + soc_display_upd_value("PcieRpEnable[2]", 1, old->PcieRpEnable[2], + new->PcieRpEnable[2]); + soc_display_upd_value("PcieRpEnable[3]", 1, old->PcieRpEnable[3], + new->PcieRpEnable[3]); + soc_display_upd_value("PcieRpEnable[4]", 1, old->PcieRpEnable[4], + new->PcieRpEnable[4]); + soc_display_upd_value("PcieRpEnable[5]", 1, old->PcieRpEnable[5], + new->PcieRpEnable[5]); + soc_display_upd_value("PcieRpEnable[6]", 1, old->PcieRpEnable[6], + new->PcieRpEnable[6]); + soc_display_upd_value("PcieRpEnable[7]", 1, old->PcieRpEnable[7], + new->PcieRpEnable[7]); + soc_display_upd_value("PcieRpEnable[8]", 1, old->PcieRpEnable[8], + new->PcieRpEnable[8]); + soc_display_upd_value("PcieRpEnable[9]", 1, old->PcieRpEnable[9], + new->PcieRpEnable[9]); + soc_display_upd_value("PcieRpEnable[10]", 1, old->PcieRpEnable[10], + new->PcieRpEnable[10]); + soc_display_upd_value("PcieRpEnable[11]", 1, old->PcieRpEnable[11], + new->PcieRpEnable[11]); + soc_display_upd_value("PcieRpEnable[12]", 1, old->PcieRpEnable[12], + new->PcieRpEnable[12]); + soc_display_upd_value("PcieRpEnable[13]", 1, old->PcieRpEnable[13], + new->PcieRpEnable[13]); + soc_display_upd_value("PcieRpEnable[14]", 1, old->PcieRpEnable[14], + new->PcieRpEnable[14]); + soc_display_upd_value("PcieRpEnable[15]", 1, old->PcieRpEnable[15], + new->PcieRpEnable[15]); + soc_display_upd_value("PcieRpEnable[16]", 1, old->PcieRpEnable[16], + new->PcieRpEnable[16]); + soc_display_upd_value("PcieRpEnable[17]", 1, old->PcieRpEnable[17], + new->PcieRpEnable[17]); + soc_display_upd_value("PcieRpEnable[18]", 1, old->PcieRpEnable[18], + new->PcieRpEnable[18]); + soc_display_upd_value("PcieRpEnable[19]", 1, old->PcieRpEnable[19], + new->PcieRpEnable[19]); + soc_display_upd_value("PcieRpClkReqSupport[0]", 1, + old->PcieRpClkReqSupport[0], + new->PcieRpClkReqSupport[0]); + soc_display_upd_value("PcieRpClkReqSupport[1]", 1, + old->PcieRpClkReqSupport[1], + new->PcieRpClkReqSupport[1]); + soc_display_upd_value("PcieRpClkReqSupport[2]", 1, + old->PcieRpClkReqSupport[2], + new->PcieRpClkReqSupport[2]); + soc_display_upd_value("PcieRpClkReqSupport[3]", 1, + old->PcieRpClkReqSupport[3], + new->PcieRpClkReqSupport[3]); + soc_display_upd_value("PcieRpClkReqSupport[4]", 1, + old->PcieRpClkReqSupport[4], + new->PcieRpClkReqSupport[4]); + soc_display_upd_value("PcieRpClkReqSupport[5]", 1, + old->PcieRpClkReqSupport[5], + new->PcieRpClkReqSupport[5]); + soc_display_upd_value("PcieRpClkReqSupport[6]", 1, + old->PcieRpClkReqSupport[6], + new->PcieRpClkReqSupport[6]); + soc_display_upd_value("PcieRpClkReqSupport[7]", 1, + old->PcieRpClkReqSupport[7], + new->PcieRpClkReqSupport[7]); + soc_display_upd_value("PcieRpClkReqSupport[8]", 1, + old->PcieRpClkReqSupport[8], + new->PcieRpClkReqSupport[8]); + soc_display_upd_value("PcieRpClkReqSupport[9]", 1, + old->PcieRpClkReqSupport[9], + new->PcieRpClkReqSupport[9]); + soc_display_upd_value("PcieRpClkReqSupport[10]", 1, + old->PcieRpClkReqSupport[10], + new->PcieRpClkReqSupport[10]); + soc_display_upd_value("PcieRpClkReqSupport[11]", 1, + old->PcieRpClkReqSupport[11], + new->PcieRpClkReqSupport[11]); + soc_display_upd_value("PcieRpClkReqSupport[12]", 1, + old->PcieRpClkReqSupport[12], + new->PcieRpClkReqSupport[12]); + soc_display_upd_value("PcieRpClkReqSupport[13]", 1, + old->PcieRpClkReqSupport[13], + new->PcieRpClkReqSupport[13]); + soc_display_upd_value("PcieRpClkReqSupport[14]", 1, + old->PcieRpClkReqSupport[14], + new->PcieRpClkReqSupport[14]); + soc_display_upd_value("PcieRpClkReqSupport[15]", 1, + old->PcieRpClkReqSupport[15], + new->PcieRpClkReqSupport[15]); + soc_display_upd_value("PcieRpClkReqSupport[16]", 1, + old->PcieRpClkReqSupport[16], + new->PcieRpClkReqSupport[16]); + soc_display_upd_value("PcieRpClkReqSupport[17]", 1, + old->PcieRpClkReqSupport[17], + new->PcieRpClkReqSupport[17]); + soc_display_upd_value("PcieRpClkReqSupport[18]", 1, + old->PcieRpClkReqSupport[18], + new->PcieRpClkReqSupport[18]); + soc_display_upd_value("PcieRpClkReqSupport[19]", 1, + old->PcieRpClkReqSupport[19], + new->PcieRpClkReqSupport[19]); + soc_display_upd_value("PcieRpClkReqNumber[0]", 1, + old->PcieRpClkReqNumber[0], + new->PcieRpClkReqNumber[0]); + soc_display_upd_value("PcieRpClkReqNumber[1]", 1, + old->PcieRpClkReqNumber[1], + new->PcieRpClkReqNumber[1]); + soc_display_upd_value("PcieRpClkReqNumber[2]", 1, + old->PcieRpClkReqNumber[2], + new->PcieRpClkReqNumber[2]); + soc_display_upd_value("PcieRpClkReqNumber[3]", 1, + old->PcieRpClkReqNumber[3], + new->PcieRpClkReqNumber[3]); + soc_display_upd_value("PcieRpClkReqNumber[4]", 1, + old->PcieRpClkReqNumber[4], + new->PcieRpClkReqNumber[4]); + soc_display_upd_value("PcieRpClkReqNumber[5]", 1, + old->PcieRpClkReqNumber[5], + new->PcieRpClkReqNumber[5]); + soc_display_upd_value("PcieRpClkReqNumber[6]", 1, + old->PcieRpClkReqNumber[6], + new->PcieRpClkReqNumber[6]); + soc_display_upd_value("PcieRpClkReqNumber[7]", 1, + old->PcieRpClkReqNumber[7], + new->PcieRpClkReqNumber[7]); + soc_display_upd_value("PcieRpClkReqNumber[8]", 1, + old->PcieRpClkReqNumber[8], + new->PcieRpClkReqNumber[8]); + soc_display_upd_value("PcieRpClkReqNumber[9]", 1, + old->PcieRpClkReqNumber[9], + new->PcieRpClkReqNumber[9]); + soc_display_upd_value("PcieRpClkReqNumber[10]", 1, + old->PcieRpClkReqNumber[10], + new->PcieRpClkReqNumber[10]); + soc_display_upd_value("PcieRpClkReqNumber[11]", 1, + old->PcieRpClkReqNumber[11], + new->PcieRpClkReqNumber[11]); + soc_display_upd_value("PcieRpClkReqNumber[12]", 1, + old->PcieRpClkReqNumber[12], + new->PcieRpClkReqNumber[12]); + soc_display_upd_value("PcieRpClkReqNumber[13]", 1, + old->PcieRpClkReqNumber[13], + new->PcieRpClkReqNumber[13]); + soc_display_upd_value("PcieRpClkReqNumber[14]", 1, + old->PcieRpClkReqNumber[14], + new->PcieRpClkReqNumber[14]); + soc_display_upd_value("PcieRpClkReqNumber[15]", 1, + old->PcieRpClkReqNumber[15], + new->PcieRpClkReqNumber[15]); + soc_display_upd_value("PcieRpClkReqNumber[16]", 1, + old->PcieRpClkReqNumber[16], + new->PcieRpClkReqNumber[16]); + soc_display_upd_value("PcieRpClkReqNumber[17]", 1, + old->PcieRpClkReqNumber[17], + new->PcieRpClkReqNumber[17]); + soc_display_upd_value("PcieRpClkReqNumber[18]", 1, + old->PcieRpClkReqNumber[18], + new->PcieRpClkReqNumber[18]); + soc_display_upd_value("PcieRpClkReqNumber[19]", 1, + old->PcieRpClkReqNumber[19], + new->PcieRpClkReqNumber[19]); + soc_display_upd_value("PortUsb20Enable[0]", 1, old->PortUsb20Enable[0], + new->PortUsb20Enable[0]); + soc_display_upd_value("PortUsb20Enable[1]", 1, old->PortUsb20Enable[1], + new->PortUsb20Enable[1]); + soc_display_upd_value("PortUsb20Enable[2]", 1, old->PortUsb20Enable[2], + new->PortUsb20Enable[2]); + soc_display_upd_value("PortUsb20Enable[3]", 1, old->PortUsb20Enable[3], + new->PortUsb20Enable[3]); + soc_display_upd_value("PortUsb20Enable[4]", 1, old->PortUsb20Enable[4], + new->PortUsb20Enable[4]); + soc_display_upd_value("PortUsb20Enable[5]", 1, old->PortUsb20Enable[5], + new->PortUsb20Enable[5]); + soc_display_upd_value("PortUsb20Enable[6]", 1, old->PortUsb20Enable[6], + new->PortUsb20Enable[6]); + soc_display_upd_value("PortUsb20Enable[7]", 1, old->PortUsb20Enable[7], + new->PortUsb20Enable[7]); + soc_display_upd_value("PortUsb20Enable[8]", 1, old->PortUsb20Enable[8], + new->PortUsb20Enable[8]); + soc_display_upd_value("PortUsb20Enable[9]", 1, old->PortUsb20Enable[9], + new->PortUsb20Enable[9]); + soc_display_upd_value("PortUsb20Enable[10]", 1, + old->PortUsb20Enable[10], + new->PortUsb20Enable[10]); + soc_display_upd_value("PortUsb20Enable[11]", 1, + old->PortUsb20Enable[11], + new->PortUsb20Enable[11]); + soc_display_upd_value("PortUsb20Enable[12]", 1, + old->PortUsb20Enable[12], + new->PortUsb20Enable[12]); + soc_display_upd_value("PortUsb20Enable[13]", 1, + old->PortUsb20Enable[13], + new->PortUsb20Enable[13]); + soc_display_upd_value("PortUsb20Enable[14]", 1, + old->PortUsb20Enable[14], + new->PortUsb20Enable[14]); + soc_display_upd_value("PortUsb20Enable[15]", 1, + old->PortUsb20Enable[15], + new->PortUsb20Enable[15]); + soc_display_upd_value("PortUsb30Enable[0]", 1, old->PortUsb30Enable[0], + new->PortUsb30Enable[0]); + soc_display_upd_value("PortUsb30Enable[1]", 1, old->PortUsb30Enable[1], + new->PortUsb30Enable[1]); + soc_display_upd_value("PortUsb30Enable[2]", 1, old->PortUsb30Enable[2], + new->PortUsb30Enable[2]); + soc_display_upd_value("PortUsb30Enable[3]", 1, old->PortUsb30Enable[3], + new->PortUsb30Enable[3]); + soc_display_upd_value("PortUsb30Enable[4]", 1, old->PortUsb30Enable[4], + new->PortUsb30Enable[4]); + soc_display_upd_value("PortUsb30Enable[5]", 1, old->PortUsb30Enable[5], + new->PortUsb30Enable[5]); + soc_display_upd_value("PortUsb30Enable[6]", 1, old->PortUsb30Enable[6], + new->PortUsb30Enable[6]); + soc_display_upd_value("PortUsb30Enable[7]", 1, old->PortUsb30Enable[7], + new->PortUsb30Enable[7]); + soc_display_upd_value("PortUsb30Enable[8]", 1, old->PortUsb30Enable[8], + new->PortUsb30Enable[8]); + soc_display_upd_value("PortUsb30Enable[9]", 1, old->PortUsb30Enable[9], + new->PortUsb30Enable[9]); + soc_display_upd_value("XdciEnable", 1, old->XdciEnable, + new->XdciEnable); + soc_display_upd_value("SsicPortEnable", 1, old->SsicPortEnable, + new->SsicPortEnable); + soc_display_upd_value("SmbusEnable", 1, old->SmbusEnable, + new->SmbusEnable); + soc_display_upd_value("SerialIoDevMode[0]", 1, old->SerialIoDevMode[0], + new->SerialIoDevMode[0]); + soc_display_upd_value("SerialIoDevMode[1]", 1, old->SerialIoDevMode[1], + new->SerialIoDevMode[1]); + soc_display_upd_value("SerialIoDevMode[2]", 1, old->SerialIoDevMode[2], + new->SerialIoDevMode[2]); + soc_display_upd_value("SerialIoDevMode[3]", 1, old->SerialIoDevMode[3], + new->SerialIoDevMode[3]); + soc_display_upd_value("SerialIoDevMode[4]", 1, old->SerialIoDevMode[4], + new->SerialIoDevMode[4]); + soc_display_upd_value("SerialIoDevMode[5]", 1, old->SerialIoDevMode[5], + new->SerialIoDevMode[5]); + soc_display_upd_value("SerialIoDevMode[6]", 1, old->SerialIoDevMode[6], + new->SerialIoDevMode[6]); + soc_display_upd_value("SerialIoDevMode[7]", 1, old->SerialIoDevMode[7], + new->SerialIoDevMode[7]); + soc_display_upd_value("SerialIoDevMode[8]", 1, old->SerialIoDevMode[8], + new->SerialIoDevMode[8]); + soc_display_upd_value("SerialIoDevMode[9]", 1, old->SerialIoDevMode[9], + new->SerialIoDevMode[9]); + soc_display_upd_value("SerialIoDevMode[10]", 1, + old->SerialIoDevMode[10], + new->SerialIoDevMode[10]); + soc_display_upd_value("Cio2Enable", 1, old->Cio2Enable, + new->Cio2Enable); + soc_display_upd_value("ScsEmmcEnabled", 1, old->ScsEmmcEnabled, + new->ScsEmmcEnabled); + soc_display_upd_value("ScsEmmcHs400Enabled", 1, + old->ScsEmmcHs400Enabled, + new->ScsEmmcHs400Enabled); + soc_display_upd_value("ScsSdCardEnabled", 1, old->ScsSdCardEnabled, + new->ScsSdCardEnabled); + soc_display_upd_value("IshEnable", 1, old->IshEnable, new->IshEnable); + soc_display_upd_value("ShowSpiController", 1, old->ShowSpiController, + new->ShowSpiController); + soc_display_upd_value("PttSwitch", 1, old->PttSwitch, new->PttSwitch); + soc_display_upd_value("HeciTimeouts", 1, old->HeciTimeouts, + new->HeciTimeouts); + soc_display_upd_value("HsioMessaging", 1, old->HsioMessaging, + new->HsioMessaging); + soc_display_upd_value("Heci3Enabled", 1, old->Heci3Enabled, + new->Heci3Enabled); + soc_display_upd_value("IgdDvmt50PreAlloc", 1, old->IgdDvmt50PreAlloc, + new->IgdDvmt50PreAlloc); + soc_display_upd_value("PrimaryDisplay", 1, old->PrimaryDisplay, + new->PrimaryDisplay); + soc_display_upd_value("InternalGfx", 1, old->InternalGfx, + new->InternalGfx); + soc_display_upd_value("ApertureSize", 1, old->ApertureSize, + new->ApertureSize); + soc_display_upd_value("SkipExtGfxScan", 1, old->SkipExtGfxScan, + new->SkipExtGfxScan); + soc_display_upd_value("ScanExtGfxForLegacyOpRom", 1, + old->ScanExtGfxForLegacyOpRom, + new->ScanExtGfxForLegacyOpRom); } - -#endif -void __attribute__((weak)) mainboard_pre_console_init(void) {} diff --git a/src/soc/intel/skylake/romstage/smbus.c b/src/soc/intel/skylake/romstage/smbus.c index f09459bedd..b72255f7f6 100644 --- a/src/soc/intel/skylake/romstage/smbus.c +++ b/src/soc/intel/skylake/romstage/smbus.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> diff --git a/src/soc/intel/skylake/romstage/spi.c b/src/soc/intel/skylake/romstage/spi.c index a2c5d33a75..206350bffd 100644 --- a/src/soc/intel/skylake/romstage/spi.c +++ b/src/soc/intel/skylake/romstage/spi.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,16 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> #include <console/console.h> -#include <device/pci_ids.h> -#include <device/pci_def.h> #include <delay.h> #include <soc/spi.h> -#include <soc/rcba.h> #include <soc/romstage.h> #define SPI_DELAY 10 /* 10us */ @@ -31,43 +29,47 @@ static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) { - u32 *ptr32 = (u32*)buffer; + u32 *ptr32 = (u32 *)buffer; u32 i; + u16 hsfs, hsfc; + void *spibar = get_spi_bar(); /* Clear status bits */ - SPIBAR16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR | - SPIBAR_HSFS_FDONE; + hsfs = read16(spibar + SPIBAR_HSFS); + write16(spibar + SPIBAR_HSFS, hsfs | SPIBAR_HSFS_AEL | + SPIBAR_HSFS_FCERR | SPIBAR_HSFS_FDONE); - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { + if (read16(spibar + SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { printk(BIOS_ERR, "SPI ERROR: transaction in progress\n"); return -1; } /* Set flash address */ - SPIBAR32(SPIBAR_FADDR) = offset; + write32(spibar + SPIBAR_FADDR, offset); /* Setup read transaction */ - SPIBAR16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) | - SPIBAR_HSFC_CYCLE_READ; + write16(spibar + SPIBAR_HSFC, SPIBAR_HSFC_BYTE_COUNT(size) | + SPIBAR_HSFC_CYCLE_READ); - /* Start transaction */ - SPIBAR16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO; + /* Start transactinon */ + hsfc = read16(spibar + SPIBAR_HSFC); + write16(spibar + SPIBAR_HSFC, hsfc | SPIBAR_HSFC_GO); /* Wait for completion */ for (i = 0; i < SPI_RETRY; i++) { - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { + if (read16(spibar + SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { /* Cycle in progress, wait 1ms */ udelay(SPI_DELAY); continue; } - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { + if (read16(spibar + SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { printk(BIOS_ERR, "SPI ERROR: Access Error\n"); return -1; } - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { + if (read16(spibar + SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n"); return -1; } @@ -80,14 +82,18 @@ static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) } /* Read the data */ - for (i = 0; i < size; i+=sizeof(u32)) { + for (i = 0; i < size; i += sizeof(u32)) { if (size-i >= 4) { /* reading >= dword */ - *ptr32++ = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32))); + *ptr32++ = read32(spibar + + SPIBAR_FDATA(i/sizeof(u32))); } else { /* reading < dword */ - u8 j, *ptr8 = (u8*)ptr32; - u32 temp = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32))); + u8 j, *ptr8 = (u8 *)ptr32; + u32 temp; + + temp = read32(spibar + + SPIBAR_FDATA(i/sizeof(u32))); for (j = 0; j < (size-i); j++) { *ptr8++ = temp & 0xff; temp >>= 8; @@ -122,18 +128,19 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer) int early_spi_read_wpsr(u8 *sr) { int retry; + void *spibar = get_spi_bar(); /* No address associated with rdsr */ - SPIBAR8(SPIBAR_OPTYPE) = 0x0; + write8(spibar + SPIBAR_OPTYPE, 0x0); /* Setup opcode[0] = read wpsr */ - SPIBAR8(SPIBAR_OPMENU_LOWER) = 0x5; + write8(spibar + SPIBAR_OPMENU_LOWER, 0x5); /* Start transaction */ - SPIBAR16(SPIBAR_SSFC) = SPIBAR_SSFC_DATA | SPIBAR_SSFC_GO; + write16(spibar + SPIBAR_SSFC, SPIBAR_SSFC_DATA | SPIBAR_SSFC_GO); /* Wait for error / complete status */ for (retry = SPI_RETRY; retry; retry--) { - u16 status = SPIBAR16(SPIBAR_SSFS); + u16 status = read16(spibar + SPIBAR_SSFS); if (status & SPIBAR_SSFS_ERROR) { printk(BIOS_ERR, "SPI rdsr failed\n"); return -1; @@ -143,7 +150,9 @@ int early_spi_read_wpsr(u8 *sr) udelay(SPI_DELAY); } - - *sr = SPIBAR32(SPIBAR_FDATA(0)) & 0xff; + /* Flash protected range 0 register bit 31 indicates WP + * Bit 31[WPE] 1= WP Enable 0= WP Disable + */ + *sr = (read32(spibar + SPIBAR_FPR(0)) & SPIBAR_FPR_WPE) >> 24; return 0; } diff --git a/src/soc/intel/skylake/romstage/stack.c b/src/soc/intel/skylake/romstage/stack.c deleted file mode 100644 index a81eb07639..0000000000 --- a/src/soc/intel/skylake/romstage/stack.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stddef.h> -#include <stdint.h> -#include <arch/cpu.h> -#include <arch/early_variables.h> -#include <console/console.h> -#include <cbmem.h> -#include <cpu/x86/mtrr.h> -#include <soc/romstage.h> - -static inline uint32_t *stack_push(u32 *stack, u32 value) -{ - stack = &stack[-1]; - *stack = value; - return stack; -} - -/* Romstage needs quite a bit of stack for decompressing images since the lzma - * lib keeps its state on the stack during romstage. */ -static unsigned long choose_top_of_stack(void) -{ - unsigned long stack_top; - const unsigned long romstage_ram_stack_size = 0x5000; - - /* cbmem_add() does a find() before add(). */ - stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, - romstage_ram_stack_size); - stack_top += romstage_ram_stack_size; - return stack_top; -} - -/* setup_stack_and_mttrs() determines the stack to use after - * cache-as-ram is torn down as well as the MTRR settings to use. */ -void *setup_stack_and_mttrs(void) -{ - unsigned long top_of_stack; - int num_mtrrs; - uint32_t *slot; - uint32_t mtrr_mask_upper; - uint32_t top_of_ram; - - /* Top of stack needs to be aligned to a 4-byte boundary. */ - top_of_stack = choose_top_of_stack() & ~3; - slot = (void *)top_of_stack; - num_mtrrs = 0; - - /* The upper bits of the MTRR mask need to set according to the number - * of physical address bits. */ - mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1; - - /* The order for each MTTR is value then base with upper 32-bits of - * each value coming before the lower 32-bits. The reasoning for - * this ordering is to create a stack layout like the following: - * +0: Number of MTRRs - * +4: MTTR base 0 31:0 - * +8: MTTR base 0 63:32 - * +12: MTTR mask 0 31:0 - * +16: MTTR mask 0 63:32 - * +20: MTTR base 1 31:0 - * +24: MTTR base 1 63:32 - * +28: MTTR mask 1 31:0 - * +32: MTTR mask 1 63:32 - */ - - /* Cache the ROM as WP just below 4GiB. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT); - num_mtrrs++; - - /* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK); - num_mtrrs++; - - top_of_ram = (uint32_t)cbmem_top(); - /* Cache 8MiB below the top of ram. The top of ram under 4GiB is the - * start of the TSEG region. It is required to be 8MiB aligned. Set - * this area as cacheable so it can be used later for ramstage before - * setting up the entire RAM as cacheable. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK); - num_mtrrs++; - - /* Cache 8MiB at the top of ram. Top of ram is where the TSEG - * region resides. However, it is not restricted to SMM mode until - * SMM has been relocated. By setting the region to cacheable it - * provides faster access when relocating the SMM handler as well - * as using the TSEG region for other purposes. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK); - num_mtrrs++; - - /* Save the number of MTTRs to setup. Return the stack location - * pointing to the number of MTRRs. */ - slot = stack_push(slot, num_mtrrs); - - return slot; -} diff --git a/src/soc/intel/skylake/romstage/systemagent.c b/src/soc/intel/skylake/romstage/systemagent.c index 7a43917601..36f68712c4 100644 --- a/src/soc/intel/skylake/romstage/systemagent.c +++ b/src/soc/intel/skylake/romstage/systemagent.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2010 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <stdlib.h> diff --git a/src/soc/intel/skylake/romstage/uart.c b/src/soc/intel/skylake/romstage/uart.c index 96c96343f1..8ddcbadda8 100644 --- a/src/soc/intel/skylake/romstage/uart.c +++ b/src/soc/intel/skylake/romstage/uart.c @@ -1,7 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Google Inc. + * Copyright (C) 2015 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,72 +15,61 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ -#include <arch/early_variables.h> #include <arch/io.h> -#include <delay.h> #include <device/pci_def.h> -#include <reg_script.h> #include <stdint.h> -#include <uart8250.h> -#include <soc/iobp.h> +#include <soc/pci_devs.h> +#include <soc/pcr.h> +#include <soc/romstage.h> #include <soc/serialio.h> -const struct reg_script uart_init[] = { - /* Set MMIO BAR */ - REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, CONFIG_TTYS0_BASE), - /* Enable Memory access and Bus Master */ - REG_PCI_OR32(PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER), - /* Initialize LTR */ - REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_GEN, - ~SIO_REG_PPR_GEN_LTR_MODE_MASK, 0), - REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST, - ~(SIO_REG_PPR_RST_ASSERT), 0), - /* Take UART out of reset */ - REG_MMIO_OR32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST, - SIO_REG_PPR_RST_ASSERT), - /* Set M and N divisor inputs and enable clock */ - REG_MMIO_WRITE32(CONFIG_TTYS0_BASE + SIO_REG_PPR_CLOCK, - SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE | - (SIO_REG_PPR_CLOCK_N_DIV << 16) | - (SIO_REG_PPR_CLOCK_M_DIV << 1)), - REG_SCRIPT_END -}; - void pch_uart_init(void) { - /* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b */ - u32 gpiodf = 0x131f; device_t dev; + u32 tmp, legacy; + u8 *base = (u8 *)CONFIG_TTYS0_BASE; - /* Put UART in byte access mode for 16550 compatibility */ switch (CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER) { case 0: dev = PCH_DEV_UART0; - gpiodf |= SIO_IOBP_GPIODF_UART0_BYTE_ACCESS; + legacy = SIO_PCH_LEGACY_UART0; break; case 1: dev = PCH_DEV_UART1; - gpiodf |= SIO_IOBP_GPIODF_UART1_BYTE_ACCESS; + legacy = SIO_PCH_LEGACY_UART1; + break; + case 2: + dev = PCH_DEV_UART2; + legacy = SIO_PCH_LEGACY_UART2; break; default: return; } - /* Program IOBP GPIODF */ - pch_iobp_update(SIO_IOBP_GPIODF, ~gpiodf, gpiodf); + /* Set configured UART base address */ + pci_write_config32(dev, PCI_BASE_ADDRESS_0, (u32)base); - /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */ - pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f); + /* Enable memory access and bus master */ + tmp = pci_read_config32(dev, PCI_COMMAND); + tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config32(dev, PCI_COMMAND, tmp); - /* Initialize chipset uart interface */ - reg_script_run_on_dev(dev, uart_init); + /* Take UART out of reset */ + tmp = read32(base + SIO_REG_PPR_RESETS); + tmp |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB | + SIO_REG_PPR_RESETS_IDMA; + write32(base + SIO_REG_PPR_RESETS, tmp); + + /* Set M and N divisor inputs and enable clock */ + tmp = read32(base + SIO_REG_PPR_CLOCK); + tmp |= SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE | + (SIO_REG_PPR_CLOCK_N_DIV << 16) | + (SIO_REG_PPR_CLOCK_M_DIV << 1); + write32(base + SIO_REG_PPR_CLOCK, tmp); - /* - * Perform standard UART initialization - * Divisor 1 is 115200 BAUD - */ - uart8250_mem_init(CONFIG_TTYS0_BASE, 1); + /* Put UART in byte access mode for 16550 compatibility */ + pcr_andthenor32(PID_SERIALIO, R_PCH_PCR_SERIAL_IO_GPPRVRW7, 0, legacy); } diff --git a/src/soc/intel/skylake/sata.c b/src/soc/intel/skylake/sata.c deleted file mode 100644 index d3cf52527d..0000000000 --- a/src/soc/intel/skylake/sata.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/io.h> -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ids.h> -#include <delay.h> -#include <soc/iobp.h> -#include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/sata.h> -#include <soc/intel/broadwell/chip.h> - -static inline u32 sir_read(struct device *dev, int idx) -{ - pci_write_config32(dev, SATA_SIRI, idx); - return pci_read_config32(dev, SATA_SIRD); -} - -static inline void sir_write(struct device *dev, int idx, u32 value) -{ - pci_write_config32(dev, SATA_SIRI, idx); - pci_write_config32(dev, SATA_SIRD, value); -} - -static void sata_init(struct device *dev) -{ - config_t *config = dev->chip_info; - u32 reg32; - u8 *abar; - u16 reg16; - int port; - - printk(BIOS_DEBUG, "SATA: Initializing controller in AHCI mode.\n"); - - /* Enable BARs */ - pci_write_config16(dev, PCI_COMMAND, 0x0007); - - /* Set Interrupt Line */ - /* Interrupt Pin is set by D31IP.PIP */ - pci_write_config8(dev, PCI_INTERRUPT_LINE, 0x0a); - - /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE); - - /* for AHCI, Port Enable is managed in memory mapped space */ - reg16 = pci_read_config16(dev, 0x92); - reg16 &= ~0xf; - reg16 |= 0x8000 | config->sata_port_map; - pci_write_config16(dev, 0x92, reg16); - udelay(2); - - /* Setup register 98h */ - reg32 = pci_read_config32(dev, 0x98); - reg32 &= ~((1 << 31) | (1 << 30)); - reg32 |= 1 << 23; - reg32 |= 1 << 24; /* Enable MPHY Dynamic Power Gating */ - pci_write_config32(dev, 0x98, reg32); - - /* Setup register 9Ch */ - reg16 = 0; /* Disable alternate ID */ - reg16 = 1 << 5; /* BWG step 12 */ - pci_write_config16(dev, 0x9c, reg16); - - /* SATA Initialization register */ - reg32 = 0x183; - reg32 |= (config->sata_port_map ^ 0xf) << 24; - reg32 |= (config->sata_devslp_mux & 1) << 15; - pci_write_config32(dev, 0x94, reg32); - - /* Initialize AHCI memory-mapped space */ - abar = (u8 *)(pci_read_config32(dev, PCI_BASE_ADDRESS_5)); - printk(BIOS_DEBUG, "ABAR: %p\n", abar); - - /* CAP (HBA Capabilities) : enable power management */ - reg32 = read32(abar + 0x00); - reg32 |= 0x0c006000; /* set PSC+SSC+SALP+SSS */ - reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */ - reg32 |= (1 << 18); /* SAM: SATA AHCI MODE ONLY */ - write32(abar + 0x00, reg32); - - /* PI (Ports implemented) */ - write32(abar + 0x0c, config->sata_port_map); - (void) read32(abar + 0x0c); /* Read back 1 */ - (void) read32(abar + 0x0c); /* Read back 2 */ - - /* CAP2 (HBA Capabilities Extended)*/ - if (config->sata_devslp_disable) { - reg32 = read32(abar + 0x24); - reg32 &= ~(1 << 3); - write32(abar + 0x24, reg32); - } else { - /* Enable DEVSLP */ - reg32 = read32(abar + 0x24); - reg32 |= (1 << 5)|(1 << 4)|(1 << 3)|(1 << 2); - write32(abar + 0x24, reg32); - - for (port = 0; port < 4; port++) { - if (!(config->sata_port_map & (1 << port))) - continue; - reg32 = read32(abar + 0x144 + (0x80 * port)); - reg32 |= (1 << 1); /* DEVSLP DSP */ - write32(abar + 0x144 + (0x80 * port), reg32); - } - } - - /* - * Static Power Gating for unused ports - */ - reg32 = RCBA32(0x3a84); - /* Port 3 and 2 disabled */ - if ((config->sata_port_map & ((1 << 3)|(1 << 2))) == 0) - reg32 |= (1 << 24) | (1 << 26); - /* Port 1 and 0 disabled */ - if ((config->sata_port_map & ((1 << 1)|(1 << 0))) == 0) - reg32 |= (1 << 20) | (1 << 18); - RCBA32(0x3a84) = reg32; - - /* Set Gen3 Transmitter settings if needed */ - if (config->sata_port0_gen3_tx) - pch_iobp_update(SATA_IOBP_SP0_SECRT88, - ~(SATA_SECRT88_VADJ_MASK << - SATA_SECRT88_VADJ_SHIFT), - (config->sata_port0_gen3_tx & - SATA_SECRT88_VADJ_MASK) - << SATA_SECRT88_VADJ_SHIFT); - - if (config->sata_port1_gen3_tx) - pch_iobp_update(SATA_IOBP_SP1_SECRT88, - ~(SATA_SECRT88_VADJ_MASK << - SATA_SECRT88_VADJ_SHIFT), - (config->sata_port1_gen3_tx & - SATA_SECRT88_VADJ_MASK) - << SATA_SECRT88_VADJ_SHIFT); - - /* Set Gen3 DTLE DATA / EDGE registers if needed */ - if (config->sata_port0_gen3_dtle) { - pch_iobp_update(SATA_IOBP_SP0DTLE_DATA, - ~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT), - (config->sata_port0_gen3_dtle & SATA_DTLE_MASK) - << SATA_DTLE_DATA_SHIFT); - - pch_iobp_update(SATA_IOBP_SP0DTLE_EDGE, - ~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT), - (config->sata_port0_gen3_dtle & SATA_DTLE_MASK) - << SATA_DTLE_EDGE_SHIFT); - } - - if (config->sata_port1_gen3_dtle) { - pch_iobp_update(SATA_IOBP_SP1DTLE_DATA, - ~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT), - (config->sata_port1_gen3_dtle & SATA_DTLE_MASK) - << SATA_DTLE_DATA_SHIFT); - - pch_iobp_update(SATA_IOBP_SP1DTLE_EDGE, - ~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT), - (config->sata_port1_gen3_dtle & SATA_DTLE_MASK) - << SATA_DTLE_EDGE_SHIFT); - } - - /* - * Additional Programming Requirements for Power Optimizer - */ - - /* Step 1 */ - sir_write(dev, 0x64, 0x883c9003); - - /* Step 2: SIR 68h[15:0] = 880Ah */ - reg32 = sir_read(dev, 0x68); - reg32 &= 0xffff0000; - reg32 |= 0x880a; - sir_write(dev, 0x68, reg32); - - /* Step 3: SIR 60h[3] = 1 */ - reg32 = sir_read(dev, 0x60); - reg32 |= (1 << 3); - sir_write(dev, 0x60, reg32); - - /* Step 4: SIR 60h[0] = 1 */ - reg32 = sir_read(dev, 0x60); - reg32 |= (1 << 0); - sir_write(dev, 0x60, reg32); - - /* Step 5: SIR 60h[1] = 1 */ - reg32 = sir_read(dev, 0x60); - reg32 |= (1 << 1); - sir_write(dev, 0x60, reg32); - - /* Clock Gating */ - sir_write(dev, 0x70, 0x3f00bf1f); - sir_write(dev, 0x54, 0xcf000f0f); - sir_write(dev, 0x58, 0x00190000); - RCBA32_AND_OR(0x333c, 0xffcfffff, 0x00c00000); - - reg32 = pci_read_config32(dev, 0x300); - reg32 |= (1 << 17) | (1 << 16) | (1 << 19); - reg32 |= (1 << 31) | (1 << 30) | (1 << 29); - pci_write_config32(dev, 0x300, reg32); - - reg32 = pci_read_config32(dev, 0x98); - reg32 |= 1 << 29; - pci_write_config32(dev, 0x98, reg32); - - /* Register Lock */ - reg32 = pci_read_config32(dev, 0x9c); - reg32 |= (1 << 31); - pci_write_config32(dev, 0x9c, reg32); -} - -/* - * Set SATA controller mode early so the resource allocator can - * properly assign IO/Memory resources for the controller. - */ -static void sata_enable(device_t dev) -{ - /* Get the chip configuration */ - config_t *config = dev->chip_info; - u16 map = 0x0060; - - map |= (config->sata_port_map ^ 0xf) << 8; - - pci_write_config16(dev, 0x90, map); -} - -static struct device_operations sata_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &pci_dev_set_resources, - .enable_resources = &pci_dev_enable_resources, - .init = &sata_init, - .enable = &sata_enable, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c03, 0x9c05, 0x9c07, 0x9c0f, /* LynxPoint-LP */ - 0x9c83, 0x9c85, 0x282a, 0x9c87, 0x282a, 0x9c8f, /* WildcatPoint */ - 0 -}; - -static const struct pci_driver pch_sata __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/serialio.c b/src/soc/intel/skylake/serialio.c deleted file mode 100644 index 6eba7ac020..0000000000 --- a/src/soc/intel/skylake/serialio.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <arch/io.h> -#include <cbmem.h> -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pciexp.h> -#include <device/pci_ids.h> -#include <stdlib.h> -#include <soc/iobp.h> -#include <soc/nvs.h> -#include <soc/pci_devs.h> -#include <soc/pch.h> -#include <soc/ramstage.h> -#include <soc/rcba.h> -#include <soc/serialio.h> -#include <soc/intel/broadwell/chip.h> - -/* Set D3Hot Power State in ACPI mode */ -static void serialio_enable_d3hot(struct resource *res) -{ - u32 reg32 = read32(res2mmio(res, PCH_PCS, 0)); - reg32 |= PCH_PCS_PS_D3HOT; - write32(res2mmio(res, PCH_PCS, 0), reg32); -} - -static int serialio_uart_is_debug(struct device *dev) -{ -#if CONFIG_INTEL_PCH_UART_CONSOLE - switch (dev->path.pci.devfn) { - case PCH_DEVFN_UART0: /* UART0 */ - return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 0); - case PCH_DEVFN_UART1: /* UART1 */ - return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1); - } -#endif - return 0; -} - -/* Enable clock in PCI mode */ -static void serialio_enable_clock(struct resource *bar0) -{ - u32 reg32 = read32(res2mmio(bar0, SIO_REG_PPR_CLOCK, 0)); - reg32 |= SIO_REG_PPR_CLOCK_EN; - write32(res2mmio(bar0, SIO_REG_PPR_CLOCK, 0), reg32); -} - -/* Put Serial IO D21:F0-F6 device into desired mode. */ -static void serialio_d21_mode(int sio_index, int int_pin, int acpi_mode) -{ - u32 portctrl = SIO_IOBP_PORTCTRL_PM_CAP_PRSNT; - - /* Snoop select 1. */ - portctrl |= SIO_IOBP_PORTCTRL_SNOOP_SELECT(1); - - /* Set interrupt pin. */ - portctrl |= SIO_IOBP_PORTCTRL_INT_PIN(int_pin); - - if (acpi_mode) { - /* Enable ACPI interrupt mode. */ - portctrl |= SIO_IOBP_PORTCTRL_ACPI_IRQ_EN; - - /* Disable PCI config space. */ - portctrl |= SIO_IOBP_PORTCTRL_PCI_CONF_DIS; - } - - pch_iobp_update(SIO_IOBP_PORTCTRLX(sio_index), 0, portctrl); -} - -/* Put Serial IO D23:F0 device into desired mode. */ -static void serialio_d23_mode(int acpi_mode) -{ - u32 portctrl = 0; - - /* Snoop select 1. */ - pch_iobp_update(SIO_IOBP_PORTCTRL1, 0, - SIO_IOBP_PORTCTRL1_SNOOP_SELECT(1)); - - if (acpi_mode) { - /* Enable ACPI interrupt mode. */ - portctrl |= SIO_IOBP_PORTCTRL0_ACPI_IRQ_EN; - - /* Disable PCI config space. */ - portctrl |= SIO_IOBP_PORTCTRL0_PCI_CONF_DIS; - } - - pch_iobp_update(SIO_IOBP_PORTCTRL0, 0, portctrl); -} - -/* Enable LTR Auto Mode for D21:F1-F6. */ -static void serialio_d21_ltr(struct resource *bar0) -{ - u32 reg; - - /* 1. Program BAR0 + 808h[2] = 0b */ - reg = read32(res2mmio(bar0, SIO_REG_PPR_GEN, 0)); - reg &= ~SIO_REG_PPR_GEN_LTR_MODE_MASK; - write32(res2mmio(bar0, SIO_REG_PPR_GEN, 0), reg); - - /* 2. Program BAR0 + 804h[1:0] = 00b */ - reg = read32(res2mmio(bar0, SIO_REG_PPR_RST, 0)); - reg &= ~SIO_REG_PPR_RST_ASSERT; - write32(res2mmio(bar0, SIO_REG_PPR_RST, 0), reg); - - /* 3. Program BAR0 + 804h[1:0] = 11b */ - reg = read32(res2mmio(bar0, SIO_REG_PPR_RST, 0)); - reg |= SIO_REG_PPR_RST_ASSERT; - write32(res2mmio(bar0, SIO_REG_PPR_RST, 0), reg); - - /* 4. Program BAR0 + 814h[31:0] = 00000000h */ - write32(res2mmio(bar0, SIO_REG_AUTO_LTR, 0), 0); -} - -/* Enable LTR Auto Mode for D23:F0. */ -static void serialio_d23_ltr(struct resource *bar0) -{ - u32 reg; - - /* Program BAR0 + 1008h[2] = 1b */ - reg = read32(res2mmio(bar0, SIO_REG_SDIO_PPR_GEN, 0)); - reg |= SIO_REG_PPR_GEN_LTR_MODE_MASK; - write32(res2mmio(bar0, SIO_REG_SDIO_PPR_GEN, 0), reg); - - /* Program BAR0 + 1010h = 0x00000000 */ - write32(res2mmio(bar0, SIO_REG_SDIO_PPR_SW_LTR, 0), 0); - - /* Program BAR0 + 3Ch[30] = 1b */ - reg = read32(res2mmio(bar0, SIO_REG_SDIO_PPR_CMD12, 0)); - reg |= SIO_REG_SDIO_PPR_CMD12_B30; - write32(res2mmio(bar0, SIO_REG_SDIO_PPR_CMD12, 0), reg); -} - -/* Select I2C voltage of 1.8V or 3.3V. */ -static void serialio_i2c_voltage_sel(struct resource *bar0, u8 voltage) -{ - u32 reg32 = read32(res2mmio(bar0, SIO_REG_PPR_GEN, 0)); - reg32 &= ~SIO_REG_PPR_GEN_VOLTAGE_MASK; - reg32 |= SIO_REG_PPR_GEN_VOLTAGE(voltage); - write32(res2mmio(bar0, SIO_REG_PPR_GEN, 0), reg32); -} - -/* Init sequence to be run once, done as part of D21:F0 (SDMA) init. */ -static void serialio_init_once(int acpi_mode) -{ - if (acpi_mode) { - /* Enable ACPI IRQ for IRQ13, IRQ7, IRQ6, IRQ5 in RCBA. */ - RCBA32_OR(ACPIIRQEN, (1 << 13)|(1 << 7)|(1 << 6)|(1 << 5)); - } - - /* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b. */ - pch_iobp_update(SIO_IOBP_GPIODF, ~0x0000131f, 0x0000131f); - - /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */ - pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f); -} - -static void serialio_init(struct device *dev) -{ - config_t *config = dev->chip_info; - struct resource *bar0, *bar1; - int sio_index = -1; - u32 reg32; - - printk(BIOS_DEBUG, "Initializing Serial IO device\n"); - - /* Ensure memory and bus master are enabled */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Find BAR0 and BAR1 */ - bar0 = find_resource(dev, PCI_BASE_ADDRESS_0); - if (!bar0) - return; - bar1 = find_resource(dev, PCI_BASE_ADDRESS_1); - if (!bar1) - return; - - if (!config->sio_acpi_mode) - serialio_enable_clock(bar0); - - switch (dev->path.pci.devfn) { - case PCH_DEVFN_SDMA: /* SDMA */ - sio_index = SIO_ID_SDMA; - serialio_init_once(config->sio_acpi_mode); - serialio_d21_mode(sio_index, SIO_PIN_INTB, - config->sio_acpi_mode); - break; - case PCH_DEVFN_I2C0: /* I2C0 */ - sio_index = SIO_ID_I2C0; - serialio_d21_ltr(bar0); - serialio_i2c_voltage_sel(bar0, config->sio_i2c0_voltage); - serialio_d21_mode(sio_index, SIO_PIN_INTC, - config->sio_acpi_mode); - break; - case PCH_DEVFN_I2C1: /* I2C1 */ - sio_index = SIO_ID_I2C1; - serialio_d21_ltr(bar0); - serialio_i2c_voltage_sel(bar0, config->sio_i2c1_voltage); - serialio_d21_mode(sio_index, SIO_PIN_INTC, - config->sio_acpi_mode); - break; - case PCH_DEVFN_SPI0: /* SPI0 */ - sio_index = SIO_ID_SPI0; - serialio_d21_ltr(bar0); - serialio_d21_mode(sio_index, SIO_PIN_INTC, - config->sio_acpi_mode); - break; - case PCH_DEVFN_SPI1: /* SPI1 */ - sio_index = SIO_ID_SPI1; - serialio_d21_ltr(bar0); - serialio_d21_mode(sio_index, SIO_PIN_INTC, - config->sio_acpi_mode); - break; - case PCH_DEVFN_UART0: /* UART0 */ - sio_index = SIO_ID_UART0; - if (!serialio_uart_is_debug(dev)) - serialio_d21_ltr(bar0); - serialio_d21_mode(sio_index, SIO_PIN_INTD, - config->sio_acpi_mode); - break; - case PCH_DEVFN_UART1: /* UART1 */ - sio_index = SIO_ID_UART1; - if (!serialio_uart_is_debug(dev)) - serialio_d21_ltr(bar0); - serialio_d21_mode(sio_index, SIO_PIN_INTD, - config->sio_acpi_mode); - break; - case PCH_DEVFN_SDIO: /* SDIO */ - sio_index = SIO_ID_SDIO; - serialio_d23_ltr(bar0); - serialio_d23_mode(config->sio_acpi_mode); - break; - default: - return; - } - - if (config->sio_acpi_mode) { - global_nvs_t *gnvs; - - /* Find ACPI NVS to update BARs */ - gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS); - if (!gnvs) { - printk(BIOS_ERR, "Unable to locate Global NVS\n"); - return; - } - - /* Save BAR0 and BAR1 to ACPI NVS */ - gnvs->dev.bar0[sio_index] = (u32)bar0->base; - gnvs->dev.bar1[sio_index] = (u32)bar1->base; - - /* Do not enable UART if it is used as debug port */ - if (!serialio_uart_is_debug(dev)) - gnvs->dev.enable[sio_index] = 1; - - /* Put device in D3hot state via BAR1 */ - if (dev->path.pci.devfn != PCH_DEVFN_SDMA) - serialio_enable_d3hot(bar1); /* all but SDMA */ - } -} - -static void serialio_set_resources(struct device *dev) -{ - pci_dev_set_resources(dev); - -#if CONFIG_INTEL_PCH_UART_CONSOLE - /* Update UART base address if used for debug */ - if (serialio_uart_is_debug(dev)) { - struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); - if (res) - uartmem_setbaseaddr(res->base); - } -#endif -} - -static struct device_operations device_ops = { - .read_resources = &pci_dev_read_resources, - .set_resources = &serialio_set_resources, - .enable_resources = &pci_dev_enable_resources, - .init = &serialio_init, - .ops_pci = &broadwell_pci_ops, -}; - -static const unsigned short pci_device_ids[] = { - 0x9c60, 0x9ce0, /* 0:15.0 - SDMA */ - 0x9c61, 0x9ce1, /* 0:15.1 - I2C0 */ - 0x9c62, 0x9ce2, /* 0:15.2 - I2C1 */ - 0x9c65, 0x9ce5, /* 0:15.3 - SPI0 */ - 0x9c66, 0x9ce6, /* 0:15.4 - SPI1 */ - 0x9c63, 0x9ce3, /* 0:15.5 - UART0 */ - 0x9c64, 0x9ce4, /* 0:15.6 - UART1 */ - 0x9c35, 0x9cb5, /* 0:17.0 - SDIO */ - 0 -}; - -static const struct pci_driver pch_pcie __pci_driver = { - .ops = &device_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/skylake/smbus.c b/src/soc/intel/skylake/smbus.c index 0ec84b27db..872b16ba2c 100644 --- a/src/soc/intel/skylake/smbus.c +++ b/src/soc/intel/skylake/smbus.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> @@ -94,15 +95,14 @@ static struct device_operations smbus_ops = { .read_resources = &smbus_read_resources, .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, - .scan_bus = &scan_static_bus, + .scan_bus = &scan_smbus, .init = &pch_smbus_init, .ops_smbus_bus = &lops_smbus_bus, - .ops_pci = &broadwell_pci_ops, + .ops_pci = &soc_pci_ops, }; static const unsigned short pci_device_ids[] = { - 0x9c22, /* LynxPoint */ - 0x9ca2, /* WildcatPoint */ + 0x9d23, /* SunRisePoint LP */ 0 }; diff --git a/src/soc/intel/skylake/smbus_common.c b/src/soc/intel/skylake/smbus_common.c index 41416c712c..fea9d805ee 100644 --- a/src/soc/intel/skylake/smbus_common.c +++ b/src/soc/intel/skylake/smbus_common.c @@ -4,6 +4,7 @@ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com> * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/io.h> @@ -65,9 +66,9 @@ int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address) unsigned char global_status_register; unsigned char byte; - if (smbus_wait_until_ready(smbus_base) < 0) { + if (smbus_wait_until_ready(smbus_base) < 0) return SMBUS_WAIT_UNTIL_READY_TIMEOUT; - } + /* Setup transaction */ /* Disable interrupts */ outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL); @@ -89,9 +90,8 @@ int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address) smbus_base + SMBHSTCTL); /* Poll for transaction completion */ - if (smbus_wait_until_done(smbus_base) < 0) { + if (smbus_wait_until_done(smbus_base) < 0) return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; - } global_status_register = inb(smbus_base + SMBHSTSTAT); @@ -100,9 +100,8 @@ int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address) /* Read results of transaction */ byte = inb(smbus_base + SMBHSTDAT0); - if (global_status_register != (1 << 1)) { + if (global_status_register != (1 << 1)) return SMBUS_ERROR; - } return byte; } diff --git a/src/soc/intel/skylake/smi.c b/src/soc/intel/skylake/smi.c index 85a508b629..c474e023a6 100644 --- a/src/soc/intel/skylake/smi.c +++ b/src/soc/intel/skylake/smi.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <device/device.h> @@ -60,7 +61,8 @@ void southbridge_smm_enable_smi(void) enable_pm1(PWRBTN_EN | GBL_EN); disable_gpe(PME_B0_EN); - /* Enable SMI generation: + /* + * Enable SMI generation: * - on APMC writes (io 0xb2) * - on writes to SLP_EN (sleep states) * - on writes to GBL_RLS (bios commands) @@ -73,7 +75,7 @@ void southbridge_smm_enable_smi(void) void southbridge_trigger_smi(void) { - /** + /* * There are several methods of raising a controlled SMI# via * software, among them: * - Writes to io 0xb2 (APMC) diff --git a/src/soc/intel/skylake/smihandler.c b/src/soc/intel/skylake/smihandler.c index 63c93739e7..dddba56ee8 100644 --- a/src/soc/intel/skylake/smihandler.c +++ b/src/soc/intel/skylake/smihandler.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,11 +16,12 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <delay.h> #include <types.h> +#include <arch/hlt.h> #include <arch/io.h> #include <console/console.h> #include <cpu/x86/cache.h> @@ -27,16 +29,16 @@ #include <cpu/x86/smm.h> #include <spi-generic.h> #include <elog.h> -#include <halt.h> #include <pc80/mc146818rtc.h> +#include <soc/iomap.h> #include <soc/lpc.h> #include <soc/nvs.h> #include <soc/pci_devs.h> +#include <soc/pch.h> +#include <soc/pcr.h> #include <soc/pm.h> -#include <soc/rcba.h> +#include <soc/pmc.h> #include <soc/smm.h> -#include <soc/xhci.h> -#include <drivers/intel/gma/i915_reg.h> static u8 smm_initialized = 0; @@ -55,9 +57,10 @@ int southbridge_io_trap_handler(int smif) switch (smif) { case 0x32: printk(BIOS_DEBUG, "OS Init\n"); - /* gnvs->smif: - * On success, the IO Trap Handler returns 0 - * On failure, the IO Trap Handler returns a value != 0 + /* + * gnvs->smif: + * - On success, the IO Trap Handler returns 0 + * - On failure, the IO Trap Handler returns a value != 0 */ gnvs->smif = 0; return 1; /* IO trap handled */ @@ -67,9 +70,7 @@ int southbridge_io_trap_handler(int smif) return 0; } -/** - * @brief Set the EOS bit - */ +/* Set the EOS bit */ void southbridge_smi_set_eos(void) { enable_smi(EOS); @@ -77,78 +78,39 @@ void southbridge_smi_set_eos(void) static void busmaster_disable_on_bus(int bus) { - int slot, func; - unsigned int val; - unsigned char hdr; - - for (slot = 0; slot < 0x20; slot++) { - for (func = 0; func < 8; func++) { - u32 reg32; - device_t dev = PCI_DEV(bus, slot, func); - - val = pci_read_config32(dev, PCI_VENDOR_ID); - - if (val == 0xffffffff || val == 0x00000000 || - val == 0x0000ffff || val == 0xffff0000) - continue; - - /* Disable Bus Mastering for this one device */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~PCI_COMMAND_MASTER; - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* If this is a bridge, then follow it. */ - hdr = pci_read_config8(dev, PCI_HEADER_TYPE); - hdr &= 0x7f; - if (hdr == PCI_HEADER_TYPE_BRIDGE || - hdr == PCI_HEADER_TYPE_CARDBUS) { - unsigned int buses; - buses = pci_read_config32(dev, PCI_PRIMARY_BUS); - busmaster_disable_on_bus((buses >> 8) & 0xff); - } - } - } + int slot, func; + unsigned int val; + unsigned char hdr; + + for (slot = 0; slot < 0x20; slot++) { + for (func = 0; func < 8; func++) { + u32 reg32; + device_t dev = PCI_DEV(bus, slot, func); + + val = pci_read_config32(dev, PCI_VENDOR_ID); + + if (val == 0xffffffff || val == 0x00000000 || + val == 0x0000ffff || val == 0xffff0000) + continue; + + /* Disable Bus Mastering for this one device */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 &= ~PCI_COMMAND_MASTER; + pci_write_config32(dev, PCI_COMMAND, reg32); + + /* If this is a bridge, then follow it. */ + hdr = pci_read_config8(dev, PCI_HEADER_TYPE); + hdr &= 0x7f; + if (hdr == PCI_HEADER_TYPE_BRIDGE || + hdr == PCI_HEADER_TYPE_CARDBUS) { + unsigned int buses; + buses = pci_read_config32(dev, PCI_PRIMARY_BUS); + busmaster_disable_on_bus((buses >> 8) & 0xff); + } + } + } } -/* - * Turn off the backlight if it is on, and wait for the specified - * backlight off delay. This will allow panel power timings to meet - * spec and prevent brief garbage on the screen when turned off - * during firmware with power button triggered SMI. - */ -static void backlight_off(void) -{ - void *reg_base; - uint32_t pp_ctrl; - uint32_t bl_off_delay; - - reg_base = (void *)((uintptr_t)pci_read_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_0) & ~0xf); - - /* Check if backlight is enabled */ - pp_ctrl = read32(reg_base + PCH_PP_CONTROL); - if (!(pp_ctrl & EDP_BLC_ENABLE)) - return; - - /* Enable writes to this register */ - pp_ctrl &= ~PANEL_UNLOCK_MASK; - pp_ctrl |= PANEL_UNLOCK_REGS; - - /* Turn off backlight */ - pp_ctrl &= ~EDP_BLC_ENABLE; - - write32(reg_base + PCH_PP_CONTROL, pp_ctrl); - read32(reg_base + PCH_PP_CONTROL); - - /* Read backlight off delay in 100us units */ - bl_off_delay = read32(reg_base + PCH_PP_OFF_DELAYS); - bl_off_delay &= PANEL_LIGHT_OFF_DELAY_MASK; - bl_off_delay *= 100; - - /* Wait for backlight to turn off */ - udelay(bl_off_delay); - - printk(BIOS_INFO, "Backlight turned off\n"); -} static void southbridge_smi_sleep(void) { @@ -176,21 +138,15 @@ static void southbridge_smi_sleep(void) /* Do any mainboard sleep handling */ mainboard_smi_sleep(slp_typ-2); - /* USB sleep preparations */ - usb_xhci_sleep_prepare(PCH_DEV_XHCI, slp_typ); - -#if CONFIG_ELOG_GSMI - /* Log S3, S4, and S5 entry */ - if (slp_typ >= 5) - elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ-2); -#endif + if (IS_ENABLED(CONFIG_ELOG_GSMI)) + /* Log S3, S4, and S5 entry */ + if (slp_typ >= 5) + elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ-2); /* Clear pending GPE events */ clear_gpe_status(); - /* Next, do the deed. - */ - + /* Next, do the deed. */ switch (slp_typ) { case SLP_TYP_S0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); @@ -204,27 +160,23 @@ static void southbridge_smi_sleep(void) /* Invalidate the cache before going to S3 */ wbinvd(); break; - case SLP_TYP_S4: - printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); - break; case SLP_TYP_S5: printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); - - /* Turn off backlight if needed */ - backlight_off(); - + /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/ + s5pwr = MAINBOARD_POWER_ON; /* Disable all GPE */ disable_all_gpe(); - /* Always set the flag in case CMOS was changed on runtime. For + /* + * Always set the flag in case CMOS was changed on runtime. For * "KEEP", switch to "OFF" - KEEP is software emulated */ - reg8 = pci_read_config8(PCH_DEV_LPC, GEN_PMCON_3); + reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B); if (s5pwr == MAINBOARD_POWER_ON) reg8 &= ~1; else reg8 |= 1; - pci_write_config8(PCH_DEV_LPC, GEN_PMCON_3, reg8); + pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8); /* also iterates over all bridges on bus 0 */ busmaster_disable_on_bus(0); @@ -243,7 +195,7 @@ static void southbridge_smi_sleep(void) /* Make sure to stop executing code here for S3/S4/S5 */ if (slp_typ > 1) - halt(); + hlt(); /* * In most sleep states, the code flow of this function ends at @@ -293,9 +245,9 @@ static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd) return NULL; } -#if CONFIG_ELOG_GSMI static void southbridge_smi_gsmi(void) { +#if IS_ENABLED(CONFIG_ELOG_GSMI) u32 *ret, *param; u8 sub_command; em64t101_smm_state_save_area_t *io_smi = @@ -305,16 +257,16 @@ static void southbridge_smi_gsmi(void) return; /* Command and return value in EAX */ - ret = (u32*)&io_smi->rax; + ret = (u32 *)&io_smi->rax; sub_command = (u8)(*ret >> 8); /* Parameter buffer in EBX */ - param = (u32*)&io_smi->rbx; + param = (u32 *)&io_smi->rbx; /* drivers/elog/gsmi.c */ *ret = gsmi_exec(sub_command, param); -} #endif +} static void finalize(void) { @@ -326,10 +278,9 @@ static void finalize(void) } finalize_done = 1; -#if CONFIG_SPI_FLASH_SMM - /* Re-init SPI driver to handle locked BAR */ - spi_init(); -#endif + if (IS_ENABLED(CONFIG_SPI_FLASH_SMM)) + /* Re-init SPI driver to handle locked BAR */ + spi_init(); } static void southbridge_smi_apmc(void) @@ -341,9 +292,6 @@ static void southbridge_smi_apmc(void) reg8 = inb(APM_CNT); switch (reg8) { - case APM_CNT_CST_CONTROL: - printk(BIOS_DEBUG, "C-state control\n"); - break; case APM_CNT_PST_CONTROL: printk(BIOS_DEBUG, "P-state control\n"); break; @@ -372,11 +320,10 @@ static void southbridge_smi_apmc(void) printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); } break; -#if CONFIG_ELOG_GSMI case ELOG_GSMI_APM_CNT: - southbridge_smi_gsmi(); + if (IS_ENABLED(CONFIG_ELOG_GSMI)) + southbridge_smi_gsmi(); break; -#endif } mainboard_smi_apmc(reg8); @@ -386,14 +333,14 @@ static void southbridge_smi_pm1(void) { u16 pm1_sts = clear_pm1_status(); - /* While OSPM is not active, poweroff immediately - * on a power button event. + /* + * While OSPM is not active, poweroff immediately on a power button + * event. */ if (pm1_sts & PWRBTN_STS) { /* power button pressed */ -#if CONFIG_ELOG_GSMI - elog_add_event(ELOG_TYPE_POWER_BUTTON); -#endif + if (IS_ENABLED(CONFIG_ELOG_GSMI)) + elog_add_event(ELOG_TYPE_POWER_BUTTON); disable_pm1_control(-1UL); enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10)); } @@ -431,8 +378,8 @@ static void southbridge_smi_tco(void) if (!tco_sts) return; - if (tco_sts & (1 << 8)) { // BIOSWR - u8 bios_cntl = pci_read_config16(PCH_DEV_LPC, BIOS_CNTL); + if (tco_sts & (1 << 8)) { /* BIOSWR */ + u8 bios_cntl = pci_read_config16(PCH_DEV_SPI, BIOS_CNTL); if (bios_cntl & 1) { /* @@ -446,7 +393,7 @@ static void southbridge_smi_tco(void) * box. */ printk(BIOS_DEBUG, "Switching back to RO\n"); - pci_write_config32(PCH_DEV_LPC, BIOS_CNTL, + pci_write_config32(PCH_DEV_SPI, BIOS_CNTL, (bios_cntl & ~1)); } /* No else for now? */ } else if (tco_sts & (1 << 3)) { /* TIMEOUT */ @@ -472,12 +419,14 @@ static void southbridge_smi_monitor(void) u32 trap_sts, trap_cycle; u32 data, mask = 0; int i; - - trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register - RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR - - trap_cycle = RCBA32(0x1e10); - for (i=16; i<20; i++) { + /* TRSR - Trap Status Register */ + pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPST, &trap_sts); + /* Clear trap(s) in TRSR */ + pcr_write8(PID_PSTH, R_PCH_PCR_PSTH_TRPST, trap_sts); + + /* TRPC - Trapped cycle */ + pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPC, &trap_cycle); + for (i = 16; i < 20; i++) { if (trap_cycle & (1 << i)) mask |= (0xff << ((i - 16) << 2)); } @@ -486,30 +435,30 @@ static void southbridge_smi_monitor(void) /* IOTRAP(3) SMI function call */ if (IOTRAP(3)) { if (gnvs && gnvs->smif) - io_trap_handler(gnvs->smif); // call function smif + io_trap_handler(gnvs->smif); /* call function smif */ return; } - /* IOTRAP(2) currently unused - * IOTRAP(1) currently unused */ + /* + * IOTRAP(2) currently unused + * IOTRAP(1) currently unused + */ /* IOTRAP(0) SMIC */ if (IOTRAP(0)) { - if (!(trap_cycle & (1 << 24))) { // It's a write + if (!(trap_cycle & (1 << 24))) { /* It's a write */ printk(BIOS_DEBUG, "SMI1 command\n"); - data = RCBA32(0x1e18); + /* Trapped write data */ + pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data); data &= mask; - // if (smi1) - // southbridge_smi_command(data); - // return; } - // Fall through to debug } printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc); - for (i=0; i < 4; i++) - if(IOTRAP(i)) printk(BIOS_DEBUG, " TRAP = %d\n", i); + for (i = 0; i < 4; i++) + if (IOTRAP(i)) + printk(BIOS_DEBUG, " TRAP = %d\n", i); printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf); printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask); printk(BIOS_DEBUG, " read/write: %s\n", @@ -517,7 +466,7 @@ static void southbridge_smi_monitor(void) if (!(trap_cycle & (1 << 24))) { /* Write Cycle */ - data = RCBA32(0x1e18); + pcr_read32(PID_PSTH, R_PCH_PCR_PSTH_TRPD, &data); printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data); } #undef IOTRAP @@ -526,52 +475,50 @@ static void southbridge_smi_monitor(void) typedef void (*smi_handler_t)(void); static smi_handler_t southbridge_smi[32] = { - NULL, // [0] reserved - NULL, // [1] reserved - NULL, // [2] BIOS_STS - NULL, // [3] LEGACY_USB_STS - southbridge_smi_sleep, // [4] SLP_SMI_STS - southbridge_smi_apmc, // [5] APM_STS - NULL, // [6] SWSMI_TMR_STS - NULL, // [7] reserved - southbridge_smi_pm1, // [8] PM1_STS - southbridge_smi_gpe0, // [9] GPE0_STS - southbridge_smi_gpi, // [10] GPI_STS - southbridge_smi_mc, // [11] MCSMI_STS - NULL, // [12] DEVMON_STS - southbridge_smi_tco, // [13] TCO_STS - southbridge_smi_periodic, // [14] PERIODIC_STS - NULL, // [15] SERIRQ_SMI_STS - NULL, // [16] SMBUS_SMI_STS - NULL, // [17] LEGACY_USB2_STS - NULL, // [18] INTEL_USB2_STS - NULL, // [19] reserved - NULL, // [20] PCI_EXP_SMI_STS - southbridge_smi_monitor, // [21] MONITOR_STS - NULL, // [22] reserved - NULL, // [23] reserved - NULL, // [24] reserved - NULL, // [25] EL_SMI_STS - NULL, // [26] SPI_STS - NULL, // [27] reserved - NULL, // [28] reserved - NULL, // [29] reserved - NULL, // [30] reserved - NULL // [31] reserved + NULL, /* [0] reserved */ + NULL, /* [1] reserved */ + NULL, /* [2] BIOS_STS */ + NULL, /* [3] LEGACY_USB_STS */ + southbridge_smi_sleep, /* [4] SLP_SMI_STS */ + southbridge_smi_apmc, /* [5] APM_STS */ + NULL, /* [6] SWSMI_TMR_STS */ + NULL, /* [7] reserved */ + southbridge_smi_pm1, /* [8] PM1_STS */ + southbridge_smi_gpe0, /* [9] GPE0_STS */ + southbridge_smi_gpi, /* [10] GPI_STS */ + southbridge_smi_mc, /* [11] MCSMI_STS */ + NULL, /* [12] DEVMON_STS */ + southbridge_smi_tco, /* [13] TCO_STS */ + southbridge_smi_periodic, /* [14] PERIODIC_STS */ + NULL, /* [15] SERIRQ_SMI_STS */ + NULL, /* [16] SMBUS_SMI_STS */ + NULL, /* [17] LEGACY_USB2_STS */ + NULL, /* [18] INTEL_USB2_STS */ + NULL, /* [19] reserved */ + NULL, /* [20] PCI_EXP_SMI_STS */ + southbridge_smi_monitor, /* [21] MONITOR_STS */ + NULL, /* [22] reserved */ + NULL, /* [23] reserved */ + NULL, /* [24] reserved */ + NULL, /* [25] EL_SMI_STS */ + NULL, /* [26] SPI_STS */ + NULL, /* [27] reserved */ + NULL, /* [28] reserved */ + NULL, /* [29] reserved */ + NULL, /* [30] reserved */ + NULL /* [31] reserved */ }; -/** - * @brief Interrupt handler for SMI# - * - * @param smm_revision revision of the smm state save map +/* + * Interrupt handler for SMI# */ - void southbridge_smi_handler(void) { int i; u32 smi_sts; - /* We need to clear the SMI status registers, or we won't see what's + /* + * We need to clear the SMI status registers, or we won't see what's * happening in the following calls. */ smi_sts = clear_smi_status(); @@ -583,8 +530,8 @@ void southbridge_smi_handler(void) southbridge_smi[i](); } else { printk(BIOS_DEBUG, - "SMI_STS[%d] occurred, but no " - "handler available.\n", i); + "SMI_STS[%d] occured, but no handler available.\n", + i); } } } diff --git a/src/soc/intel/skylake/smmrelocate.c b/src/soc/intel/skylake/smmrelocate.c index 47d6385a63..874d95f10a 100644 --- a/src/soc/intel/skylake/smmrelocate.c +++ b/src/soc/intel/skylake/smmrelocate.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <types.h> @@ -34,6 +35,7 @@ #include <soc/pci_devs.h> #include <soc/smm.h> #include <soc/systemagent.h> +#include "chip.h" /* This gets filled in and used during relocation. */ static struct smm_relocation_params smm_reloc_params; @@ -46,48 +48,44 @@ static inline void write_smrr(struct smm_relocation_params *relo_params) wrmsr(SMRRphysMask_MSR, relo_params->smrr_mask); } -static inline void write_emrr(struct smm_relocation_params *relo_params) -{ - printk(BIOS_DEBUG, "Writing EMRR. base = 0x%08x, mask=0x%08x\n", - relo_params->emrr_base.lo, relo_params->emrr_mask.lo); - wrmsr(EMRRphysBase_MSR, relo_params->emrr_base); - wrmsr(EMRRphysMask_MSR, relo_params->emrr_mask); -} - static inline void write_uncore_emrr(struct smm_relocation_params *relo_params) { printk(BIOS_DEBUG, "Writing UNCORE_EMRR. base = 0x%08x, mask=0x%08x\n", relo_params->uncore_emrr_base.lo, relo_params->uncore_emrr_mask.lo); - wrmsr(UNCORE_EMRRphysBase_MSR, relo_params->uncore_emrr_base); - wrmsr(UNCORE_EMRRphysMask_MSR, relo_params->uncore_emrr_mask); + wrmsr(UNCORE_EMRR_PHYS_BASE_MSR, relo_params->uncore_emrr_base); + wrmsr(UNCORE_EMRR_PHYS_MASK_MSR, relo_params->uncore_emrr_mask); } static void update_save_state(int cpu, - struct smm_relocation_params *relo_params, - const struct smm_runtime *runtime) + struct smm_relocation_params *relo_params, + const struct smm_runtime *runtime) { u32 smbase; u32 iedbase; - /* The relocated handler runs with all CPUs concurrently. Therefore + /* + * The relocated handler runs with all CPUs concurrently. Therefore * stagger the entry points adjusting SMBASE downwards by save state - * size * CPU num. */ + * size * CPU num. + */ smbase = relo_params->smram_base - cpu * runtime->save_state_size; iedbase = relo_params->ied_base; printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n", smbase, iedbase); - /* All threads need to set IEDBASE and SMBASE to the relocated + /* + * All threads need to set IEDBASE and SMBASE to the relocated * handler region. However, the save state location depends on the * smm_save_state_in_msrs field in the relocation parameters. If * smm_save_state_in_msrs is non-zero then the CPUs are relocating * the SMM handler in parallel, and each CPUs save state area is * located in their respective MSR space. If smm_save_state_in_msrs * is zero then the SMM relocation is happening serially so the - * save state is at the same default location for all CPUs. */ + * save state is at the same default location for all CPUs. + */ if (relo_params->smm_save_state_in_msrs) { msr_t smbase_msr; msr_t iedbase_msr; @@ -95,8 +93,10 @@ static void update_save_state(int cpu, smbase_msr.lo = smbase; smbase_msr.hi = 0; - /* According the BWG the IEDBASE MSR is in bits 63:32. It's - * not clear why it differs from the SMBASE MSR. */ + /* + * According the BWG the IEDBASE MSR is in bits 63:32. It's + * not clear why it differs from the SMBASE MSR. + */ iedbase_msr.lo = 0; iedbase_msr.hi = iedbase; @@ -131,9 +131,11 @@ static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) return relo_params->smm_save_state_in_msrs; } -/* The relocation work is actually performed in SMM context, but the code +/* + * The relocation work is actually performed in SMM context, but the code * resides in the ramstage module. This occurs by trampolining from the default - * SMRAM entry point to here. */ + * SMRAM entry point to here. + */ static void asmlinkage cpu_smm_do_relocation(void *arg) { msr_t mtrr_cap; @@ -155,16 +157,20 @@ static void asmlinkage cpu_smm_do_relocation(void *arg) printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu); - /* Determine if the processor supports saving state in MSRs. If so, + /* + * Determine if the processor supports saving state in MSRs. If so, * enable it before the non-BSPs run so that SMM relocation can occur - * in parallel in the non-BSP CPUs. */ + * in parallel in the non-BSP CPUs. + */ if (cpu == 0) { - /* If smm_save_state_in_msrs is 1 then that means this is the + /* + * If smm_save_state_in_msrs is 1 then that means this is the * 2nd time through the relocation handler for the BSP. * Parallel SMM handler relocation is taking place. However, * it is desired to access other CPUs save state in the real * SMM handler. Therefore, disable the SMM save state in MSRs - * feature. */ + * feature. + */ if (relo_params->smm_save_state_in_msrs) { msr_t smm_feature_control; @@ -172,10 +178,12 @@ static void asmlinkage cpu_smm_do_relocation(void *arg) smm_feature_control.lo &= ~SMM_CPU_SAVE_EN; wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control); } else if (bsp_setup_msr_save_state(relo_params)) - /* Just return from relocation handler if MSR save + /* + * Just return from relocation handler if MSR save * state is enabled. In that case the BSP will come * back into the relocation handler to setup the new - * SMBASE as well disabling SMM save state in MSRs. */ + * SMBASE as well disabling SMM save state in MSRs. + */ return; } @@ -186,14 +194,6 @@ static void asmlinkage cpu_smm_do_relocation(void *arg) mtrr_cap = rdmsr(MTRRcap_MSR); if (mtrr_cap.lo & SMRR_SUPPORTED) write_smrr(relo_params); - - if (mtrr_cap.lo & EMRR_SUPPORTED) { - write_emrr(relo_params); - /* UNCORE_EMRR msrs are package level. Therefore, only - * configure these MSRs on the BSP. */ - if (cpu == 0) - write_uncore_emrr(relo_params); - } } static u32 northbridge_get_base_reg(device_t dev, int reg) @@ -207,7 +207,7 @@ static u32 northbridge_get_base_reg(device_t dev, int reg) } static void fill_in_relocation_params(device_t dev, - struct smm_relocation_params *params) + struct smm_relocation_params *params) { u32 tseg_size; u32 tsegmb; @@ -217,23 +217,26 @@ static void fill_in_relocation_params(device_t dev, int phys_bits; /* All range registers are aligned to 4KiB */ const u32 rmask = ~((1 << 12) - 1); + config_t *conf = dev->chip_info; - /* Some of the range registers are dependent on the number of physical - * address bits supported. */ + /* + * Some of the range registers are dependent on the number of physical + * address bits supported. + */ phys_bits = cpuid_eax(0x80000008) & 0xff; - /* The range bounded by the TSEGMB and BGSM registers encompasses the - * SMRAM range as well as the IED range. However, the SMRAM available - * to the handler is 4MiB since the IEDRAM lives TSEGMB + 4MiB. + /* + * The range bounded by the TSEGMB and BGSM registers encompasses the + * SMRAM range as well as the IED range. */ tsegmb = northbridge_get_base_reg(dev, TSEG); bgsm = northbridge_get_base_reg(dev, BGSM); tseg_size = bgsm - tsegmb; + params->ied_size = conf->IedSize; + params->smram_size = tseg_size - params->ied_size; params->smram_base = tsegmb; - params->smram_size = 4 << 20; params->ied_base = tsegmb + params->smram_size; - params->ied_size = tseg_size - params->smram_size; /* Adjust available SMM handler memory size. */ params->smram_size -= CONFIG_SMM_RESERVED_SIZE; @@ -248,8 +251,10 @@ static void fill_in_relocation_params(device_t dev, emrr_base = (params->ied_base + (2 << 20)) & rmask; emrr_size = params->ied_size - (2 << 20); - /* EMRR has 46 bits of valid address aligned to 4KiB. It's dependent - * on the number of physical address bits supported. */ + /* + * EMRR has 46 bits of valid address aligned to 4KiB. It's dependent + * on the number of physical address bits supported. + */ params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK; params->emrr_base.hi = 0; params->emrr_mask.lo = (~(emrr_size - 1) & rmask) | MTRRphysMaskValid; @@ -259,7 +264,7 @@ static void fill_in_relocation_params(device_t dev, params->uncore_emrr_base.lo = emrr_base; params->uncore_emrr_base.hi = 0; params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) | - MTRRphysMaskValid; + MTRRphysMaskValid; params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1; } @@ -280,14 +285,16 @@ static void adjust_apic_id_map(struct smm_loader_params *smm_params) } static int install_relocation_handler(int num_cpus, - struct smm_relocation_params *relo_params) + struct smm_relocation_params *relo_params) { - /* The default SMM entry can happen in parallel or serially. If the + /* + * The default SMM entry can happen in parallel or serially. If the * default SMM entry is done in parallel the BSP has already setup * the saving state to each CPU's MSRs. At least one save state size * is required for the initial SMM entry for the BSP to determine if * parallel SMM relocation is even feasible. Set the stack size to - * the save state size, and call into the do_relocation handler. */ + * the save state size, and call into the do_relocation handler. + */ int save_state_size = sizeof(em64t101_smm_state_save_area_t); struct smm_loader_params smm_params = { .per_cpu_stack_size = save_state_size, @@ -318,6 +325,9 @@ static void setup_ied_area(struct smm_relocation_params *params) ied_base = (void *)params->ied_base; + printk(BIOS_DEBUG, "IED base = 0x%08x\n", params->ied_base); + printk(BIOS_DEBUG, "IED size = 0x%08x\n", params->ied_size); + /* Place IED header at IEDBASE. */ memcpy(ied_base, &ied, sizeof(ied)); @@ -326,10 +336,12 @@ static void setup_ied_area(struct smm_relocation_params *params) } static int install_permanent_handler(int num_cpus, - struct smm_relocation_params *relo_params) + struct smm_relocation_params *relo_params) { - /* There are num_cpus concurrent stacks and num_cpus concurrent save - * state areas. Lastly, set the stack size to the save state size. */ + /* + * There are num_cpus concurrent stacks and num_cpus concurrent save + * state areas. Lastly, set the stack size to the save state size. + */ int save_state_size = sizeof(em64t101_smm_state_save_area_t); struct smm_loader_params smm_params = { .per_cpu_stack_size = save_state_size, @@ -341,7 +353,7 @@ static int install_permanent_handler(int num_cpus, printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n", relo_params->smram_base); if (smm_load_module((void *)relo_params->smram_base, - relo_params->smram_size, &smm_params)) + relo_params->smram_size, &smm_params)) return -1; adjust_apic_id_map(&smm_params); @@ -359,14 +371,15 @@ static int cpu_smm_setup(void) fill_in_relocation_params(dev, &smm_reloc_params); - setup_ied_area(&smm_reloc_params); + if (smm_reloc_params.ied_size) + setup_ied_area(&smm_reloc_params); msr = rdmsr(CORE_THREAD_COUNT_MSR); num_cpus = msr.lo & 0xffff; if (num_cpus > CONFIG_MAX_CPUS) { printk(BIOS_CRIT, - "Error: Hardware CPUs (%d) > MAX_CPUS (%d)\n", - num_cpus, CONFIG_MAX_CPUS); + "Error: Hardware CPUs (%d) > MAX_CPUS (%d)\n", + num_cpus, CONFIG_MAX_CPUS); } if (install_relocation_handler(num_cpus, &smm_reloc_params)) { @@ -380,7 +393,6 @@ static int cpu_smm_setup(void) } /* Ensure the SMM handlers hit DRAM before performing first SMI. */ - /* TODO(adurbin): Is this really needed? */ wbinvd(); return 0; @@ -398,9 +410,8 @@ int smm_initialize(void) /* Run the relocation handler. */ smm_initiate_relocation(); - if (smm_reloc_params.smm_save_state_in_msrs) { + if (smm_reloc_params.smm_save_state_in_msrs) printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n"); - } return 0; } @@ -421,16 +432,19 @@ void smm_relocate(void) void smm_init(void) { - /* smm_init() is normally called from initialize_cpus() in + /* + * smm_init() is normally called from initialize_cpus() in * lapic_cpu_init.c. However, that path is no longer used. Don't reuse * the function name because that would cause confusion. * The smm_initialize() function above is used to setup SMM at the - * appropriate time. */ + * appropriate time. + */ } void smm_lock(void) { - /* LOCK the SMM memory window and enable normal SMM. + /* + * LOCK the SMM memory window and enable normal SMM. * After running this function, only a full reset can * make the SMM registers writable again. */ diff --git a/src/soc/intel/skylake/spi.c b/src/soc/intel/skylake/spi.c deleted file mode 100644 index 36558a1db9..0000000000 --- a/src/soc/intel/skylake/spi.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Copyright (C) 2014 Google Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <bootstate.h> -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/pci_ids.h> -#include <spi-generic.h> -#include <soc/pci_devs.h> -#include <soc/rcba.h> -#include <soc/spi.h> - -#ifdef __SMM__ -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ -#include <device/device.h> -#include <device/pci.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ - -typedef struct spi_slave ich_spi_slave; - -static int ichspi_lock = 0; - -typedef struct ich9_spi_regs { - uint32_t bfpr; - uint16_t hsfs; - uint16_t hsfc; - uint32_t faddr; - uint32_t _reserved0; - uint32_t fdata[16]; - uint32_t frap; - uint32_t freg[5]; - uint32_t _reserved1[3]; - uint32_t pr[5]; - uint32_t _reserved2[2]; - uint8_t ssfs; - uint8_t ssfc[3]; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; - uint32_t bbar; - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; -} __attribute__((packed)) ich9_spi_regs; - -typedef struct ich_spi_controller { - int locked; - - uint8_t *opmenu; - int menubytes; - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; - unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; -} ich_spi_controller; - -static ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -}; - -#if CONFIG_DEBUG_SPI_FLASH - -static u8 readb_(const void *addr) -{ - u8 v = read8(addr); - printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u16 readw_(const void *addr) -{ - u16 v = read16(addr); - printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u32 readl_(const void *addr) -{ - u32 v = read32(addr); - printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static void writeb_(u8 b, const void *addr) -{ - write8(addr, b); - printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writew_(u16 b, const void *addr) -{ - write16(addr, b); - printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writel_(u32 b, const void *addr) -{ - write32(addr, b); - printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8(a) -#define readw_(a) read16(a) -#define readl_(a) read32(a) -#define writeb_(val, addr) write8(addr, val) -#define writew_(val, addr) write16(addr, val) -#define writel_(val, addr) write32(addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static void write_reg(const void *value, void *dest, uint32_t size) -{ - const uint8_t *bvalue = value; - uint8_t *bdest = dest; - - while (size >= 4) { - writel_(*(const uint32_t *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static void read_reg(const void *src, void *value, uint32_t size) -{ - const uint8_t *bsrc = src; - uint8_t *bvalue = value; - - while (size >= 4) { - *(uint32_t *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) -{ - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - slave->bus = bus; - slave->cs = cs; - return slave; -} - -void spi_init(void) -{ - uint8_t *rcrb; /* Root Complex Register Block */ - uint32_t rcba; /* Root Complex Base Address */ - uint8_t bios_cntl; - device_t dev = PCH_DEV_LPC; - ich9_spi_regs *ich9_spi; - - pci_read_config_dword(dev, 0xf0, &rcba); - /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ - rcrb = (uint8_t *)(rcba & 0xffffc000); - ich9_spi = (ich9_spi_regs *)(rcrb + 0x3800); - ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - ich_set_bbar(0); - - /* Disable the BIOS write protect so write commands are allowed. */ - pci_read_config_byte(dev, 0xdc, &bios_cntl); - bios_cntl &= ~(1 << 5); - pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -} - -#if ENV_RAMSTAGE -static void spi_init_cb(void *unused) -{ - spi_init(); -} - -BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -#endif - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -typedef struct spi_transaction { - const uint8_t *out; - uint32_t bytesout; - uint8_t *in; - uint32_t bytesin; - uint8_t type; - uint8_t opcode; - uint32_t offset; -} spi_transaction; - -static inline void spi_use_out(spi_transaction *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(spi_transaction *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static void spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static int spi_setup_opcode(spi_transaction *trans) -{ - uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; - - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); - if (!ichspi_lock) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } else { - /* The lock is on. See if what we need is on the menu. */ - uint8_t optype; - uint16_t opcode_index; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == cntlr.menubytes) { - printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", - trans->opcode); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", - optype); - return -1; - } - return opcode_index; - } -} - -static int spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); - return -1; - } -} - -/* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static int ich_status_poll(u16 bitmask, int wait_til_set) -{ - int timeout = 6000; /* This will result in 60 ms */ - u16 status = 0; - - while (timeout--) { - status = readw_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writew_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); - return -1; -} - -unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) -{ - return min(cntlr.databytes, buf_len); -} - -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) -{ - uint16_t control; - int16_t opcode_index; - int with_address; - int status; - - spi_transaction trans = { - dout, bytesout, - din, bytesin, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bytesout || !dout) { - printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bytesin != 0 && !din) { - printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!ichspi_lock) - writew_(trans.opcode, cntlr.preop); - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bytesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); - return -1; - } - - return 0; - } - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " CONTROLLER_PAGE_LIMIT?\n"); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - uint32_t data_length; - - /* SPI addresses are 24 bit only */ - /* http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/pentium-n3520-j2850-celeron-n2920-n2820-n2815-n2806-j1850-j1750-datasheet.pdf */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); - else - data_length = min(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -} - -/* Use first empty Protected Range Register to cover region of flash */ -int spi_flash_protect(u32 start, u32 size) -{ - u32 end = start + size - 1; - u32 reg; - int prr; - - /* Find first empty PRR */ - for (prr = 0; prr < SPI_PRR_MAX; prr++) { - reg = SPIBAR32(SPI_PRR(prr)); - if (reg == 0) - break; - } - if (prr >= SPI_PRR_MAX) { - printk(BIOS_ERR, "ERROR: No SPI PRR free!\n"); - return -1; - } - - /* Set protected range base and limit */ - reg = ((end >> SPI_PRR_SHIFT) & SPI_PRR_MASK); - reg <<= SPI_PRR_LIMIT_SHIFT; - reg |= ((start >> SPI_PRR_SHIFT) & SPI_PRR_MASK); - reg |= SPI_PRR_WPE; - - /* Set the PRR register and verify it is protected */ - SPIBAR32(SPI_PRR(prr)) = reg; - reg = SPIBAR32(SPI_PRR(prr)); - if (!(reg & SPI_PRR_WPE)) { - printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr); - return -1; - } - - printk(BIOS_INFO, "%s: PRR %d is enabled for range 0x%08x-0x%08x\n", - __func__, prr, start, end); - return 0; -} diff --git a/src/soc/intel/skylake/stage_cache.c b/src/soc/intel/skylake/stage_cache.c deleted file mode 100644 index 346e673cf5..0000000000 --- a/src/soc/intel/skylake/stage_cache.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <cbmem.h> -#include <soc/smm.h> -#include <stage_cache.h> -#include <stdint.h> - -void stage_cache_external_region(void **base, size_t *size) -{ - /* The ramstage cache lives in the TSEG region. - * The top of ram is defined to be the TSEG base address. */ - u32 offset = smm_region_size(); - offset -= CONFIG_IED_REGION_SIZE; - offset -= CONFIG_SMM_RESERVED_SIZE; - - *base = (void *)(cbmem_top() + offset); - *size = CONFIG_SMM_RESERVED_SIZE; -} diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c index d58cf219b7..2034e8e1f1 100644 --- a/src/soc/intel/skylake/systemagent.c +++ b/src/soc/intel/skylake/systemagent.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <console/console.h> @@ -29,6 +30,7 @@ #include <stdlib.h> #include <string.h> #include <cbmem.h> +#include <romstage_handoff.h> #include <vendorcode/google/chromeos/chromeos.h> #include <soc/cpu.h> #include <soc/iomap.h> @@ -54,17 +56,17 @@ static int get_pcie_bar(device_t dev, unsigned int index, u32 *base, u32 *len) return 0; switch ((pciexbar_reg >> 1) & 3) { - case 0: // 256MB + case 0: /* 256MB */ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)| (1 << 28)); *len = 256 * 1024 * 1024; return 1; - case 1: // 128M + case 1: /* 128M */ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)| (1 << 28)|(1 << 27)); *len = 128 * 1024 * 1024; return 1; - case 2: // 64M + case 2: /* 64M */ *base = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)| (1 << 28)|(1 << 27)|(1 << 26)); *len = 64 * 1024 * 1024; @@ -90,11 +92,13 @@ static int get_bar(device_t dev, unsigned int index, u32 *base, u32 *len) return 1; } -/* There are special BARs that actually are programmed in the MCHBAR. These +/* + * There are special BARs that actually are programmed in the MCHBAR. These * Intel special features, but they do consume resources that need to be - * accounted for. */ + * accounted for. + */ static int get_bar_in_mchbar(device_t dev, unsigned int index, u32 *base, - u32 *len) + u32 *len) { u32 bar; @@ -114,7 +118,7 @@ struct fixed_mmio_descriptor { unsigned int index; u32 size; int (*get_resource)(device_t dev, unsigned int index, - u32 *base, u32 *size); + u32 *base, u32 *size); const char *description; }; @@ -144,13 +148,13 @@ static void mc_add_fixed_mmio_resources(device_t dev) size = mc_fixed_resources[i].size; index = mc_fixed_resources[i].index; if (!mc_fixed_resources[i].get_resource(dev, index, - &base, &size)) + &base, &size)) continue; resource = new_resource(dev, mc_fixed_resources[i].index); resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | - IORESOURCE_STORED | IORESOURCE_RESERVE | - IORESOURCE_ASSIGNED; + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED; resource->base = base; resource->size = size; printk(BIOS_DEBUG, "%s: Adding %s @ %x 0x%08lx-0x%08lx.\n", @@ -159,7 +163,8 @@ static void mc_add_fixed_mmio_resources(device_t dev) } } -/* Host Memory Map: +/* + * Host Memory Map: * * +--------------------------+ TOUUD * | | @@ -172,6 +177,10 @@ static void mc_add_fixed_mmio_resources(device_t dev) * +--------------------------+ BGSM * | TSEG | * +--------------------------+ TSEGMB + * | DMA Protected Region | + * +--------------------------+ DPR + * | Reserved - FSP | + * +--------------------------+ RSVFSP * | Usage DRAM | * +--------------------------+ 0 * @@ -189,7 +198,7 @@ struct map_entry { }; static void read_map_entry(device_t dev, struct map_entry *entry, - uint64_t *result) + uint64_t *result) { uint64_t value; uint64_t mask; @@ -240,7 +249,7 @@ enum { BGSM_REG, BDSM_REG, TSEG_REG, - // Must be last. + /* Must be last. */ NUM_MAP_ENTRIES }; @@ -260,9 +269,8 @@ static struct map_entry memory_map[NUM_MAP_ENTRIES] = { static void mc_read_map_entries(device_t dev, uint64_t *values) { int i; - for (i = 0; i < NUM_MAP_ENTRIES; i++) { + for (i = 0; i < NUM_MAP_ENTRIES; i++) read_map_entry(dev, &memory_map[i], &values[i]); - } } static void mc_report_map_entries(device_t dev, uint64_t *values) @@ -343,23 +351,26 @@ static void mc_add_dram_resources(device_t dev) base_k = 0xc0000 >> 10; size_k = (unsigned long)(mc_values[TSEG_REG] >> 10) - base_k; size_k -= dpr_size >> 10; + size_k -= CONFIG_CHIPSET_RESERVED_MEM_BYTES >> 10; ram_resource(dev, index++, base_k, size_k); /* TSEG - DPR -> BGSM */ resource = new_resource(dev, index++); resource->base = mc_values[TSEG_REG] - dpr_size; resource->size = mc_values[BGSM_REG] - resource->base; + resource->base -= CONFIG_CHIPSET_RESERVED_MEM_BYTES; + resource->size += CONFIG_CHIPSET_RESERVED_MEM_BYTES; resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | - IORESOURCE_STORED | IORESOURCE_RESERVE | - IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE; + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED | IORESOURCE_CACHEABLE; /* BGSM -> TOLUD */ resource = new_resource(dev, index++); resource->base = mc_values[BGSM_REG]; resource->size = mc_values[TOLUD_REG] - resource->base; resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | - IORESOURCE_STORED | IORESOURCE_RESERVE | - IORESOURCE_ASSIGNED; + IORESOURCE_STORED | IORESOURCE_RESERVE | + IORESOURCE_ASSIGNED; /* 4GiB -> TOUUD */ base_k = 4096 * 1024; /* 4GiB */ @@ -368,14 +379,15 @@ static void mc_add_dram_resources(device_t dev) if (touud_k > base_k) ram_resource(dev, index++, base_k, size_k); - /* Reserve everything between A segment and 1MB: + /* + * Reserve everything between A segment and 1MB: * * 0xa0000 - 0xbffff: legacy VGA * 0xc0000 - 0xfffff: RAM */ mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10); reserved_ram_resource(dev, index++, (0xc0000 >> 10), - (0x100000 - 0xc0000) >> 10); + (0x100000 - 0xc0000) >> 10); chromeos_reserve_ram_oops(dev, index++); } @@ -416,32 +428,39 @@ static void systemagent_init(struct device *dev) set_power_limits(28); } -unsigned long acpi_fill_slit(unsigned long current) +static void systemagent_enable(device_t dev) { - // Not implemented - return current; -} - -unsigned long acpi_fill_srat(unsigned long current) -{ - /* No NUMA, no SRAT */ - return current; +#if CONFIG_HAVE_ACPI_RESUME + struct romstage_handoff *handoff; + + handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO); + + if (handoff == NULL) { + printk(BIOS_DEBUG, "Unknown boot method, assuming normal.\n"); + acpi_slp_type = 0; + } else if (handoff->s3_resume) { + printk(BIOS_DEBUG, "S3 Resume.\n"); + acpi_slp_type = 3; + } else { + printk(BIOS_DEBUG, "Normal boot.\n"); + acpi_slp_type = 0; + } +#endif } static struct device_operations systemagent_ops = { .read_resources = &systemagent_read_resources, - .acpi_fill_ssdt_generator = &generate_cpu_entries, .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, .init = &systemagent_init, - .ops_pci = &broadwell_pci_ops, + .enable = &systemagent_enable, + .ops_pci = &soc_pci_ops, }; static const unsigned short systemagent_ids[] = { - 0x0a04, /* Haswell ULT */ - 0x1604, /* Broadwell-U/Y */ - 0x1610, /* Broadwell-H Desktop */ - 0x1614, /* Broadwell-H Mobile */ + MCH_SKYLAKE_ID_U, + MCH_SKYLAKE_ID_Y, + MCH_SKYLAKE_ID_ULX, 0 }; diff --git a/src/soc/intel/skylake/tsc_freq.c b/src/soc/intel/skylake/tsc_freq.c index 5487b16b8c..5990d27e13 100644 --- a/src/soc/intel/skylake/tsc_freq.c +++ b/src/soc/intel/skylake/tsc_freq.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <stdint.h> diff --git a/src/soc/intel/skylake/uart.c b/src/soc/intel/skylake/uart.c new file mode 100644 index 0000000000..36b1b5a71b --- /dev/null +++ b/src/soc/intel/skylake/uart.c @@ -0,0 +1,76 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Google Inc. + * Copyright (C) 2015 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include <console/uart.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <stdlib.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> + +static int pch_uart_is_debug(struct device *dev) +{ + if (!IS_ENABLED(CONFIG_INTEL_PCH_UART_CONSOLE)) + return 0; + + switch (dev->path.pci.devfn) { + case PCH_DEVFN_UART0: + return CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 0; + case PCH_DEVFN_UART1: + return CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1; + case PCH_DEVFN_UART2: + return CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 2; + } + return 0; +} + +static void pch_uart_read_resources(struct device *dev) +{ + pci_dev_read_resources(dev); + + /* Set the configured UART base address for the debug port */ + if (pch_uart_is_debug(dev)) { + struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); + res->size = 0x1000; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED; + } +} + +static struct device_operations device_ops = { + .read_resources = &pch_uart_read_resources, + .set_resources = &pci_dev_set_resources, + .enable_resources = &pci_dev_enable_resources, + .ops_pci = &soc_pci_ops, +}; + +static const unsigned short pci_device_ids[] = { + 0x9d27, /* UART0 */ + 0x9d28, /* UART1 */ + 0x9d66, /* UART2 */ + 0 +}; + +static const struct pci_driver pch_uart __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; diff --git a/src/soc/intel/skylake/usbdebug.c b/src/soc/intel/skylake/usbdebug.c deleted file mode 100644 index 736a1a3c44..0000000000 --- a/src/soc/intel/skylake/usbdebug.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdint.h> -#include <arch/io.h> -#include <console/console.h> -#include <usbdebug.h> -#include <device/pci.h> -#include <device/pci_def.h> -#include <soc/pci_devs.h> - -void set_debug_port(unsigned int port) -{ - /* Hardcoded to physical port 1 */ -} - -void enable_usbdebug(unsigned int port) -{ - u32 tmp32; - - tmp32 = pci_read_config32(PCH_DEV_EHCI, PCI_VENDOR_ID); - if (tmp32 == 0xffffffff || tmp32 == 0) - return; - - /* Set the EHCI BAR address. */ - pci_write_config32(PCH_DEV_EHCI, EHCI_BAR_INDEX, CONFIG_EHCI_BAR); - - /* Enable access to the EHCI memory space registers. */ - pci_write_config8(PCH_DEV_EHCI, PCI_COMMAND, PCI_COMMAND_MEMORY); - - /* Force ownership of the Debug Port to the EHCI controller. */ - tmp32 = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET); - tmp32 |= (1 << 30); - write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, tmp32); -} diff --git a/src/soc/intel/skylake/xhci.c b/src/soc/intel/skylake/xhci.c index 9d0390e1a2..275739730a 100644 --- a/src/soc/intel/skylake/xhci.c +++ b/src/soc/intel/skylake/xhci.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <console/console.h> @@ -27,209 +28,15 @@ #include <soc/xhci.h> #include <soc/cpu.h> -#ifdef __SMM__ -static u8 *usb_xhci_mem_base(device_t dev) -{ - u32 mem_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); - - /* Check if the controller is disabled or not present */ - if (mem_base == 0 || mem_base == 0xffffffff) - return 0; - - return (u8 *)(mem_base & ~0xf); -} - -static int usb_xhci_port_count_usb3(device_t dev) -{ - /* PCH-LP has 4 SS ports */ - return 4; -} - -static void usb_xhci_reset_status_usb3(u8 *mem_base, int port) -{ - u8 *portsc = mem_base + XHCI_USB3_PORTSC(port); - u32 status = read32(portsc); - /* Do not set Port Enabled/Disabled field */ - status &= ~XHCI_USB3_PORTSC_PED; - /* Clear all change status bits */ - status |= XHCI_USB3_PORTSC_CHST; - write32(portsc, status); -} - -static void usb_xhci_reset_port_usb3(u8 *mem_base, int port) -{ - u8 *portsc = mem_base + XHCI_USB3_PORTSC(port); - write32(portsc, read32(portsc) | XHCI_USB3_PORTSC_WPR); -} - -#define XHCI_RESET_DELAY_US 1000 /* 1ms */ -#define XHCI_RESET_TIMEOUT 100 /* 100ms */ - -/* - * 1) Wait until port is done polling - * 2) If port is disconnected - * a) Issue warm port reset - * b) Poll for warm reset complete - * c) Write 1 to port change status bits - */ -static void usb_xhci_reset_usb3(device_t dev, int all) -{ - u32 status, port_disabled; - int timeout, port; - int port_count = usb_xhci_port_count_usb3(dev); - u8 *mem_base = usb_xhci_mem_base(dev); - - if (!mem_base || !port_count) - return; - - /* Get mask of disabled ports */ - port_disabled = pci_read_config32(dev, XHCI_USB3PDO); - - /* Wait until all enabled ports are done polling */ - for (timeout = XHCI_RESET_TIMEOUT; timeout; timeout--) { - int complete = 1; - for (port = 0; port < port_count; port++) { - /* Skip disabled ports */ - if (port_disabled & (1 << port)) - continue; - /* Read port link status field */ - status = read32(mem_base + XHCI_USB3_PORTSC(port)); - status &= XHCI_USB3_PORTSC_PLS; - if (status == XHCI_PLSR_POLLING) - complete = 0; - } - /* Exit if all ports not polling */ - if (complete) - break; - udelay(XHCI_RESET_DELAY_US); - } - - /* Reset all requested ports */ - for (port = 0; port < port_count; port++) { - u8 *portsc = mem_base + XHCI_USB3_PORTSC(port); - /* Skip disabled ports */ - if (port_disabled & (1 << port)) - continue; - status = read32(portsc) & XHCI_USB3_PORTSC_PLS; - /* Reset all or only disconnected ports */ - if (all || (status == XHCI_PLSR_RXDETECT || - status == XHCI_PLSR_POLLING)) - usb_xhci_reset_port_usb3(mem_base, port); - else - port_disabled |= 1 << port; - } - - /* Wait for warm reset complete on all reset ports */ - for (timeout = XHCI_RESET_TIMEOUT; timeout; timeout--) { - int complete = 1; - for (port = 0; port < port_count; port++) { - /* Only check ports that were reset */ - if (port_disabled & (1 << port)) - continue; - /* Check if warm reset is complete */ - status = read32(mem_base + XHCI_USB3_PORTSC(port)); - if (!(status & XHCI_USB3_PORTSC_WRC)) - complete = 0; - } - /* Check for warm reset complete in any port */ - if (complete) - break; - udelay(XHCI_RESET_DELAY_US); - } - - /* Clear port change status bits */ - for (port = 0; port < port_count; port++) - usb_xhci_reset_status_usb3(mem_base, port); -} - -/* Handler for XHCI controller on entry to S3/S4/S5 */ -void usb_xhci_sleep_prepare(device_t dev, u8 slp_typ) -{ - u16 reg16; - u32 reg32; - u8 *mem_base = usb_xhci_mem_base(dev); - u8 is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT); - - if (!mem_base || slp_typ < 3) - return; - - /* Set D0 state */ - reg16 = pci_read_config16(dev, XHCI_PWR_CTL_STS); - reg16 &= ~XHCI_PWR_CTL_SET_MASK; - reg16 |= XHCI_PWR_CTL_SET_D0; - pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16); - - if (!is_broadwell) { - /* This WA is only for lpt */ - - /* Clear PCI 0xB0[14:13] */ - reg32 = pci_read_config32(dev, 0xb0); - reg32 &= ~((1 << 14) | (1 << 13)); - pci_write_config32(dev, 0xb0, reg32); - - /* Clear MMIO 0x816c[14,2] */ - reg32 = read32(mem_base + 0x816c); - reg32 &= ~((1 << 14) | (1 << 2)); - write32(mem_base + 0x816c, reg32); - - /* Reset disconnected USB3 ports */ - usb_xhci_reset_usb3(dev, 0); - - /* Set MMIO 0x80e0[15] */ - reg32 = read32(mem_base + 0x80e0); - reg32 |= (1 << 15); - write32(mem_base + 0x80e0, reg32); - } else { - /* - * Clear port change status bits. Clearing CSC alone seemed to - * fix wakeup from S3 if entering USB compliance state even if - * bit wasn't set on the port. - */ - int port; - for (port = 0; port < usb_xhci_port_count_usb3(dev); port++) - usb_xhci_reset_status_usb3(mem_base, port); - } - - reg32 = read32(mem_base + 0x8154); - reg32 &= ~(1 << 31); - write32(mem_base + 0x8154, reg32); - - /* Set D3Hot state and enable PME */ - pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_SET_D3); - pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_STATUS_PME); - pci_or_config16(dev, XHCI_PWR_CTL_STS, XHCI_PWR_CTL_ENABLE_PME); -} -#else /* !__SMM__ */ - -static void xhci_init(struct device *dev) -{ - struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); - u16 reg16; - u32 reg32; - - /* Ensure controller is in D0 state */ - reg16 = pci_read_config16(dev, XHCI_PWR_CTL_STS); - reg16 &= ~XHCI_PWR_CTL_SET_MASK; - reg16 |= XHCI_PWR_CTL_SET_D0; - pci_write_config16(dev, XHCI_PWR_CTL_STS, reg16); - - /* Disable Compliance Mode Entry */ - reg32 = read32(res2mmio(res, 0x80ec, 0)); - reg32 |= (1 << 0); - write32(res2mmio(res, 0x80ec, 0), reg32); -} - static struct device_operations usb_xhci_ops = { .read_resources = &pci_dev_read_resources, .set_resources = &pci_dev_set_resources, .enable_resources = &pci_dev_enable_resources, - .ops_pci = &broadwell_pci_ops, - .init = &xhci_init, + .ops_pci = &soc_pci_ops, }; static const unsigned short pci_device_ids[] = { - 0x9c31, /* LynxPoint-LP */ - 0x9cb1, /* WildcatPoint */ + 0x9d2f, /* SunRisePoint LP */ 0 }; @@ -238,4 +45,3 @@ static const struct pci_driver pch_usb_xhci __pci_driver = { .vendor = PCI_VENDOR_ID_INTEL, .devices = pci_device_ids, }; -#endif /* !__SMM__ */ |