baytrail: add initial support
The initial Bay Trail code is intended to support the mobile and desktop version of Bay Trail. This support can train memory and execute through ramstage. However, the resource allocation is not curently handled correctly. The MRC cache parameters are successfully saved and reused after the initial cold boot. BUG=chrome-os-partner:22292 BRANCH=None TEST=Built and booted on a reference board through ramstage. Change-Id: I238ede326802aad272c6cca39d7ad4f161d813f5 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/168387 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/4847 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
parent
ba6b07e888
commit
9a7d7bcea5
|
@ -50,7 +50,7 @@ PHONY+= clean-abuild coreboot lint lint-stable build-dirs
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# root source directories of coreboot
|
# root source directories of coreboot
|
||||||
subdirs-y := src/lib src/console src/device src/ec src/southbridge
|
subdirs-y := src/lib src/console src/device src/ec src/southbridge src/soc
|
||||||
subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode
|
subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode
|
||||||
subdirs-y += util/cbfstool util/sconfig util/nvramtool
|
subdirs-y += util/cbfstool util/sconfig util/nvramtool
|
||||||
subdirs-y += src/arch/$(ARCHDIR-y)
|
subdirs-y += src/arch/$(ARCHDIR-y)
|
||||||
|
|
|
@ -261,6 +261,8 @@ comment "Super I/O"
|
||||||
source src/superio/Kconfig
|
source src/superio/Kconfig
|
||||||
comment "Embedded Controllers"
|
comment "Embedded Controllers"
|
||||||
source src/ec/Kconfig
|
source src/ec/Kconfig
|
||||||
|
comment "SoC"
|
||||||
|
source src/soc/Kconfig
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
if ARCH_X86
|
||||||
|
source src/soc/intel/Kconfig
|
||||||
|
endif
|
|
@ -0,0 +1,4 @@
|
||||||
|
################################################################################
|
||||||
|
## Subdirectories
|
||||||
|
################################################################################
|
||||||
|
subdirs-y += intel
|
|
@ -0,0 +1 @@
|
||||||
|
source src/soc/intel/baytrail/Kconfig
|
|
@ -0,0 +1 @@
|
||||||
|
subdirs-$(CONFIG_SOC_INTEL_BAYTRAIL) += baytrail
|
|
@ -0,0 +1,236 @@
|
||||||
|
|
||||||
|
config SOC_INTEL_BAYTRAIL
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Bay Trail M/D part support.
|
||||||
|
|
||||||
|
if SOC_INTEL_BAYTRAIL
|
||||||
|
|
||||||
|
config CPU_SPECIFIC_OPTIONS
|
||||||
|
def_bool y
|
||||||
|
select SMP
|
||||||
|
select SSE2
|
||||||
|
select UDELAY_TSC
|
||||||
|
select TSC_CONSTANT_RATE
|
||||||
|
select SMM_TSEG
|
||||||
|
select SMM_MODULES
|
||||||
|
select RELOCATABLE_MODULES
|
||||||
|
select DYNAMIC_CBMEM
|
||||||
|
select SUPPORT_CPU_UCODE_IN_CBFS
|
||||||
|
select TSC_SYNC_MFENCE
|
||||||
|
select CAR_MIGRATION
|
||||||
|
select MMCONF_SUPPORT
|
||||||
|
select MMCONF_SUPPORT_DEFAULT
|
||||||
|
select HAVE_SMI_HANDLER
|
||||||
|
select CACHE_MRC_SETTINGS
|
||||||
|
select CACHE_ROM
|
||||||
|
select SPI_FLASH
|
||||||
|
|
||||||
|
config BOOTBLOCK_CPU_INIT
|
||||||
|
string
|
||||||
|
default "soc/intel/baytrail/bootblock/bootblock.c"
|
||||||
|
|
||||||
|
config MMCONF_BASE_ADDRESS
|
||||||
|
hex
|
||||||
|
default 0xe0000000
|
||||||
|
|
||||||
|
config MAX_CPUS
|
||||||
|
int
|
||||||
|
default 4
|
||||||
|
|
||||||
|
config CPU_ADDR_BITS
|
||||||
|
int
|
||||||
|
default 36
|
||||||
|
|
||||||
|
config SMM_TSEG_SIZE
|
||||||
|
hex
|
||||||
|
default 0x800000
|
||||||
|
|
||||||
|
config SMM_RESERVED_SIZE
|
||||||
|
hex
|
||||||
|
default 0x100000
|
||||||
|
|
||||||
|
config HAVE_MRC
|
||||||
|
bool "Add a Memory Reference Code binary"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Select this option to add a blob containing
|
||||||
|
memory reference code.
|
||||||
|
Note: Without this binary coreboot will not work
|
||||||
|
|
||||||
|
if HAVE_MRC
|
||||||
|
|
||||||
|
config MRC_FILE
|
||||||
|
string "Intel memory refeference code path and filename"
|
||||||
|
default "3rdparty/northbridge/intel/sandybridge/systemagent-r6.bin"
|
||||||
|
help
|
||||||
|
The path and filename of the file to use as System Agent
|
||||||
|
binary. Note that this points to the sandybridge binary file
|
||||||
|
which is will not work, but it serves its purpose to do builds.
|
||||||
|
|
||||||
|
config MRC_BIN_ADDRESS
|
||||||
|
hex
|
||||||
|
default 0xfffa0000
|
||||||
|
|
||||||
|
config CACHE_MRC_SETTINGS
|
||||||
|
bool "Save cached MRC settings"
|
||||||
|
default n
|
||||||
|
|
||||||
|
if CACHE_MRC_SETTINGS
|
||||||
|
|
||||||
|
config MRC_SETTINGS_CACHE_BASE
|
||||||
|
hex
|
||||||
|
default 0xffb00000
|
||||||
|
|
||||||
|
config MRC_SETTINGS_CACHE_SIZE
|
||||||
|
hex
|
||||||
|
default 0x10000
|
||||||
|
|
||||||
|
endif # CACHE_MRC_SETTINGS
|
||||||
|
|
||||||
|
endif # HAVE_MRC
|
||||||
|
|
||||||
|
config CAR_TILE_SIZE
|
||||||
|
hex
|
||||||
|
default 0x8000
|
||||||
|
help
|
||||||
|
The tile size is the limit that can be assigned to cache-as-ram
|
||||||
|
region as well as the amount of code cache used during cache-as-ram.
|
||||||
|
Also note that (DCACHE_RAM_BASE ^ MRC_BIN_ADDRESS) & CAR_TILE_SIZE ==
|
||||||
|
CAR_TILE_SIZE.
|
||||||
|
|
||||||
|
# Cache As RAM region layout:
|
||||||
|
#
|
||||||
|
# +-------------+ DCACHE_RAM_BASE + DCACHE_RAM_SIZE + DCACHE_RAM_MRC_VAR_SIZE
|
||||||
|
# | MRC usage |
|
||||||
|
# | |
|
||||||
|
# +-------------+ DCACHE_RAM_BASE + DCACHE_RAM_SIZE
|
||||||
|
# | Stack |\
|
||||||
|
# | | | * DCACHE_RAM_ROMSTAGE_STACK_SIZE
|
||||||
|
# | v |/
|
||||||
|
# +-------------+
|
||||||
|
# | ^ |
|
||||||
|
# | | |
|
||||||
|
# | CAR Globals |
|
||||||
|
# +-------------+ DCACHE_RAM_BASE
|
||||||
|
#
|
||||||
|
# Note that the MRC binary is linked to assume the region marked as "MRC usage"
|
||||||
|
# starts at DCACHE_RAM_BASE + DCACHE_RAM_SIZE. If those values change then
|
||||||
|
# a new MRC binary needs to be produced with the updated start and size
|
||||||
|
# information.
|
||||||
|
|
||||||
|
config DCACHE_RAM_BASE
|
||||||
|
hex
|
||||||
|
default 0xff7f8000
|
||||||
|
|
||||||
|
config DCACHE_RAM_SIZE
|
||||||
|
hex
|
||||||
|
default 0x1000
|
||||||
|
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 0x7000
|
||||||
|
help
|
||||||
|
The amount of cache-as-ram region required by the reference code.
|
||||||
|
|
||||||
|
config DCACHE_RAM_ROMSTAGE_STACK_SIZE
|
||||||
|
hex
|
||||||
|
default 0x800
|
||||||
|
help
|
||||||
|
The amount of anticipated stack usage from the data cache
|
||||||
|
during pre-ram rom stage execution.
|
||||||
|
|
||||||
|
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 baytrail 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 CBFS_SIZE
|
||||||
|
hex "Size of CBFS filesystem in ROM"
|
||||||
|
default 0x100000
|
||||||
|
help
|
||||||
|
On Bay Trail systems the firmware image has to store a lot more
|
||||||
|
than just coreboot, including:
|
||||||
|
- a firmware descriptor
|
||||||
|
- Intel Management Engine firmware
|
||||||
|
- MRC cache information
|
||||||
|
This option allows to limit the size of the CBFS portion in the
|
||||||
|
firmware image.
|
||||||
|
|
||||||
|
config ENABLE_BUILTIN_COM1
|
||||||
|
bool "Enable builtin COM1 Serial Port"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
The PMC has a legacy COM1 serial port. Choose this option to
|
||||||
|
configure the pads and enable it. This serial port can be used for
|
||||||
|
the debug console.
|
||||||
|
|
||||||
|
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 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 ME_BIN_PATH
|
||||||
|
string "Path to management engine firmware"
|
||||||
|
depends on HAVE_ME_BIN
|
||||||
|
default "3rdparty/mainboard/$(MAINBOARDDIR)/me.bin"
|
||||||
|
|
||||||
|
config HAVE_IFD_BIN
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config BUILD_WITH_FAKE_IFD
|
||||||
|
bool "Build with a fake IFD"
|
||||||
|
default y if !HAVE_IFD_BIN
|
||||||
|
help
|
||||||
|
If you don't have an Intel Firmware Descriptor (ifd.bin) for your
|
||||||
|
board, you can select this option and coreboot will build without it.
|
||||||
|
Though, the resulting coreboot.rom will not contain all parts required
|
||||||
|
to get coreboot running on your board. You can however write only the
|
||||||
|
BIOS section to your board's flash ROM and keep the other sections
|
||||||
|
untouched. Unfortunately the current version of flashrom doesn't
|
||||||
|
support this yet. But there is a patch pending [1].
|
||||||
|
|
||||||
|
WARNING: Never write a complete coreboot.rom to your flash ROM if it
|
||||||
|
was built with a fake IFD. It just won't work.
|
||||||
|
|
||||||
|
[1] http://www.flashrom.org/pipermail/flashrom/2013-June/011083.html
|
||||||
|
|
||||||
|
config IFD_BIOS_SECTION
|
||||||
|
depends on BUILD_WITH_FAKE_IFD
|
||||||
|
string
|
||||||
|
default ""
|
||||||
|
|
||||||
|
config IFD_ME_SECTION
|
||||||
|
depends on BUILD_WITH_FAKE_IFD
|
||||||
|
string
|
||||||
|
default ""
|
||||||
|
|
||||||
|
config IFD_PLATFORM_SECTION
|
||||||
|
depends on BUILD_WITH_FAKE_IFD
|
||||||
|
string
|
||||||
|
default ""
|
||||||
|
|
||||||
|
config IFD_BIN_PATH
|
||||||
|
string "Path to intel firmware descriptor"
|
||||||
|
depends on !BUILD_WITH_FAKE_IFD
|
||||||
|
default "3rdparty/mainboard/$(MAINBOARDDIR)/descriptor.bin"
|
||||||
|
|
||||||
|
endif
|
|
@ -0,0 +1,65 @@
|
||||||
|
subdirs-y += microcode
|
||||||
|
subdirs-y += romstage
|
||||||
|
subdirs-y += ../../../cpu/x86/lapic
|
||||||
|
subdirs-y += ../../../cpu/x86/mtrr
|
||||||
|
subdirs-y += ../../../cpu/x86/tsc
|
||||||
|
|
||||||
|
ramstage-y += memmap.c
|
||||||
|
romstage-y += memmap.c
|
||||||
|
ramstage-y += tsc_freq.c
|
||||||
|
romstage-y += tsc_freq.c
|
||||||
|
ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += nvm.c
|
||||||
|
ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
|
||||||
|
romstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
|
||||||
|
ramstage-y += spi.c
|
||||||
|
ramstage-y += chip.c
|
||||||
|
ramstage-y += iosf.c
|
||||||
|
romstage-y += iosf.c
|
||||||
|
|
||||||
|
|
||||||
|
# Remove as ramstage gets fleshed out
|
||||||
|
ramstage-y += placeholders.c
|
||||||
|
|
||||||
|
INCLUDES += -Isrc/soc/intel/baytrail/
|
||||||
|
|
||||||
|
# Run an intermediate step when producing coreboot.rom
|
||||||
|
# that adds additional components to the final firmware
|
||||||
|
# image outside of CBFS
|
||||||
|
INTERMEDIATE:=baytrail_add_me
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BUILD_WITH_FAKE_IFD),y)
|
||||||
|
IFD_BIN_PATH := $(objgenerated)/ifdfake.bin
|
||||||
|
IFD_SECTIONS := $(addprefix -b ,$(CONFIG_IFD_BIOS_SECTION:"%"=%)) \
|
||||||
|
$(addprefix -m ,$(CONFIG_IFD_ME_SECTION:"%"=%)) \
|
||||||
|
$(addprefix -p ,$(CONFIG_IFD_PLATFORM_SECTION:"%"=%))
|
||||||
|
else
|
||||||
|
IFD_BIN_PATH := $(CONFIG_IFD_BIN_PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
baytrail_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"
|
||||||
|
printf "Never write a complete coreboot.rom with a fake IFD to your board's\n"
|
||||||
|
printf "flash ROM! Make sure that you only write valid flash regions.\n\n"
|
||||||
|
printf " IFDFAKE Building a fake Intel Firmware Descriptor\n"
|
||||||
|
$(IFDFAKE) $(IFD_SECTIONS) $(IFD_BIN_PATH)
|
||||||
|
endif
|
||||||
|
printf " DD Adding Intel Firmware Descriptor\n"
|
||||||
|
dd if=$(IFD_BIN_PATH) \
|
||||||
|
of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1
|
||||||
|
ifeq ($(CONFIG_HAVE_ME_BIN),y)
|
||||||
|
printf " IFDTOOL me.bin -> coreboot.pre\n"
|
||||||
|
$(objutil)/ifdtool/ifdtool \
|
||||||
|
-i ME:$(CONFIG_ME_BIN_PATH) \
|
||||||
|
$(obj)/coreboot.pre
|
||||||
|
mv $(obj)/coreboot.pre.new $(obj)/coreboot.pre
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Add memory reference code blob.
|
||||||
|
cbfs-files-$(CONFIG_HAVE_MRC) += mrc.bin
|
||||||
|
mrc.bin-file := $(call strip_quotes,$(CONFIG_MRC_FILE))
|
||||||
|
mrc.bin-position := $(CONFIG_MRC_BIN_ADDRESS)
|
||||||
|
mrc.bin-type := 0xab
|
||||||
|
|
||||||
|
PHONY += baytrail_add_me
|
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Global Variables */
|
||||||
|
|
||||||
|
Name(\PICM, 0) // IOAPIC/8259
|
||||||
|
Name(\DSEN, 1) // Display Output Switching Enable
|
||||||
|
|
||||||
|
/* Global ACPI memory region. This region is used for passing information
|
||||||
|
* between coreboot (aka "the system bios"), ACPI, and the SMI handler.
|
||||||
|
* Since we don't know where this will end up in memory at ACPI compile time,
|
||||||
|
* we have to fix it up in coreboot's ACPI creation phase.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
OperationRegion (GNVS, SystemMemory, 0xC0DEBABE, 0xf00)
|
||||||
|
Field (GNVS, ByteAcc, NoLock, Preserve)
|
||||||
|
{
|
||||||
|
/* Miscellaneous */
|
||||||
|
Offset (0x00),
|
||||||
|
OSYS, 16, // 0x00 - Operating System
|
||||||
|
SMIF, 8, // 0x02 - SMI function
|
||||||
|
PRM0, 8, // 0x03 - SMI function parameter
|
||||||
|
PRM1, 8, // 0x04 - SMI function parameter
|
||||||
|
SCIF, 8, // 0x05 - SCI function
|
||||||
|
PRM2, 8, // 0x06 - SCI function parameter
|
||||||
|
PRM3, 8, // 0x07 - SCI function parameter
|
||||||
|
LCKF, 8, // 0x08 - Global Lock function for EC
|
||||||
|
PRM4, 8, // 0x09 - Lock function parameter
|
||||||
|
PRM5, 8, // 0x0a - Lock function parameter
|
||||||
|
P80D, 32, // 0x0b - Debug port (IO 0x80) value
|
||||||
|
LIDS, 8, // 0x0f - LID state (open = 1)
|
||||||
|
PWRS, 8, // 0x10 - Power State (AC = 1)
|
||||||
|
/* Thermal policy */
|
||||||
|
Offset (0x11),
|
||||||
|
TLVL, 8, // 0x11 - Throttle Level Limit
|
||||||
|
FLVL, 8, // 0x12 - Current FAN Level
|
||||||
|
TCRT, 8, // 0x13 - Critical Threshold
|
||||||
|
TPSV, 8, // 0x14 - Passive Threshold
|
||||||
|
TMAX, 8, // 0x15 - CPU Tj_max
|
||||||
|
F0OF, 8, // 0x16 - FAN 0 OFF Threshold
|
||||||
|
F0ON, 8, // 0x17 - FAN 0 ON Threshold
|
||||||
|
F0PW, 8, // 0x18 - FAN 0 PWM value
|
||||||
|
F1OF, 8, // 0x19 - FAN 1 OFF Threshold
|
||||||
|
F1ON, 8, // 0x1a - FAN 1 ON Threshold
|
||||||
|
F1PW, 8, // 0x1b - FAN 1 PWM value
|
||||||
|
F2OF, 8, // 0x1c - FAN 2 OFF Threshold
|
||||||
|
F2ON, 8, // 0x1d - FAN 2 ON Threshold
|
||||||
|
F2PW, 8, // 0x1e - FAN 2 PWM value
|
||||||
|
F3OF, 8, // 0x1f - FAN 3 OFF Threshold
|
||||||
|
F3ON, 8, // 0x20 - FAN 3 ON Threshold
|
||||||
|
F3PW, 8, // 0x21 - FAN 3 PWM value
|
||||||
|
F4OF, 8, // 0x22 - FAN 4 OFF Threshold
|
||||||
|
F4ON, 8, // 0x23 - FAN 4 ON Threshold
|
||||||
|
F4PW, 8, // 0x24 - FAN 4 PWM value
|
||||||
|
TMPS, 8, // 0x25 - Temperature Sensor ID
|
||||||
|
/* Processor Identification */
|
||||||
|
Offset (0x28),
|
||||||
|
APIC, 8, // 0x28 - APIC Enabled by coreboot
|
||||||
|
MPEN, 8, // 0x29 - Multi Processor Enable
|
||||||
|
PCP0, 8, // 0x2a - PDC CPU/CORE 0
|
||||||
|
PCP1, 8, // 0x2b - PDC CPU/CORE 1
|
||||||
|
PPCM, 8, // 0x2c - Max. PPC state
|
||||||
|
PCNT, 8, // 0x2d - Processor count
|
||||||
|
/* Super I/O & CMOS config */
|
||||||
|
Offset (0x32),
|
||||||
|
NATP, 8, // 0x32 -
|
||||||
|
S5U0, 8, // 0x33 - Enable USB0 in S5
|
||||||
|
S5U1, 8, // 0x34 - Enable USB1 in S5
|
||||||
|
S3U0, 8, // 0x35 - Enable USB0 in S3
|
||||||
|
S3U1, 8, // 0x36 - Enable USB1 in S3
|
||||||
|
S33G, 8, // 0x37 - Enable 3G in S3
|
||||||
|
CMEM, 32, // 0x38 - CBMEM TOC
|
||||||
|
/* Integrated Graphics Device */
|
||||||
|
Offset (0x3c),
|
||||||
|
IGDS, 8, // 0x3c - IGD state (primary = 1)
|
||||||
|
TLST, 8, // 0x3d - Display Toggle List pointer
|
||||||
|
CADL, 8, // 0x3e - Currently Attached Devices List
|
||||||
|
PADL, 8, // 0x3f - Previously Attached Devices List
|
||||||
|
CSTE, 16, // 0x40 - Current display state
|
||||||
|
NSTE, 16, // 0x42 - Next display state
|
||||||
|
SSTE, 16, // 0x44 - Set display state
|
||||||
|
Offset (0x46),
|
||||||
|
NDID, 8, // 0x46 - Number of Device IDs
|
||||||
|
DID1, 32, // 0x47 - Device ID 1
|
||||||
|
DID2, 32, // 0x4b - Device ID 2
|
||||||
|
DID3, 32, // 0x4f - Device ID 3
|
||||||
|
DID4, 32, // 0x53 - Device ID 4
|
||||||
|
DID5, 32, // 0x57 - Device ID 5
|
||||||
|
|
||||||
|
/* TPM support */
|
||||||
|
Offset (0x5b),
|
||||||
|
TPMP, 8, // 0x5b - TPM Present
|
||||||
|
TPME, 8, // 0x5c - TPM Enable
|
||||||
|
|
||||||
|
/* LynxPoint Serial IO device BARs */
|
||||||
|
Offset (0x60),
|
||||||
|
S0B0, 32, // 0x60 - D21:F0 Serial IO SDMA BAR0
|
||||||
|
S1B0, 32, // 0x64 - D21:F1 Serial IO I2C0 BAR0
|
||||||
|
S2B0, 32, // 0x68 - D21:F2 Serial IO I2C1 BAR0
|
||||||
|
S3B0, 32, // 0x6c - D21:F3 Serial IO SPI0 BAR0
|
||||||
|
S4B0, 32, // 0x70 - D21:F4 Serial IO SPI1 BAR0
|
||||||
|
S5B0, 32, // 0x74 - D21:F5 Serial IO UAR0 BAR0
|
||||||
|
S6B0, 32, // 0x78 - D21:F6 Serial IO UAR1 BAR0
|
||||||
|
S7B0, 32, // 0x7c - D23:F0 Serial IO SDIO BAR0
|
||||||
|
S0B1, 32, // 0x80 - D21:F0 Serial IO SDMA BAR1
|
||||||
|
S1B1, 32, // 0x84 - D21:F1 Serial IO I2C0 BAR1
|
||||||
|
S2B1, 32, // 0x88 - D21:F2 Serial IO I2C1 BAR1
|
||||||
|
S3B1, 32, // 0x8c - D21:F3 Serial IO SPI0 BAR1
|
||||||
|
S4B1, 32, // 0x90 - D21:F4 Serial IO SPI1 BAR1
|
||||||
|
S5B1, 32, // 0x94 - D21:F5 Serial IO UAR0 BAR1
|
||||||
|
S6B1, 32, // 0x98 - D21:F6 Serial IO UAR1 BAR1
|
||||||
|
S7B1, 32, // 0x9c - D23:F0 Serial IO SDIO BAR1
|
||||||
|
|
||||||
|
Offset (0xa0),
|
||||||
|
CBMC, 32, // 0xa0 - coreboot mem console pointer
|
||||||
|
|
||||||
|
/* IGD OpRegion */
|
||||||
|
Offset (0xb4),
|
||||||
|
ASLB, 32, // 0xb4 - IGD OpRegion Base Address
|
||||||
|
IBTT, 8, // 0xb8 - IGD boot panel device
|
||||||
|
IPAT, 8, // 0xb9 - IGD panel type cmos option
|
||||||
|
ITVF, 8, // 0xba - IGD TV format cmos option
|
||||||
|
ITVM, 8, // 0xbb - IGD TV minor format option
|
||||||
|
IPSC, 8, // 0xbc - IGD panel scaling
|
||||||
|
IBLC, 8, // 0xbd - IGD BLC config
|
||||||
|
IBIA, 8, // 0xbe - IGD BIA config
|
||||||
|
ISSC, 8, // 0xbf - IGD SSC config
|
||||||
|
I409, 8, // 0xc0 - IGD 0409 modified settings
|
||||||
|
I509, 8, // 0xc1 - IGD 0509 modified settings
|
||||||
|
I609, 8, // 0xc2 - IGD 0609 modified settings
|
||||||
|
I709, 8, // 0xc3 - IGD 0709 modified settings
|
||||||
|
IDMM, 8, // 0xc4 - IGD Power conservation feature
|
||||||
|
IDMS, 8, // 0xc5 - IGD DVMT memory size
|
||||||
|
IF1E, 8, // 0xc6 - IGD function 1 enable
|
||||||
|
HVCO, 8, // 0xc7 - IGD HPLL VCO
|
||||||
|
NXD1, 32, // 0xc8 - IGD _DGS next DID1
|
||||||
|
NXD2, 32, // 0xcc - IGD _DGS next DID2
|
||||||
|
NXD3, 32, // 0xd0 - IGD _DGS next DID3
|
||||||
|
NXD4, 32, // 0xd4 - IGD _DGS next DID4
|
||||||
|
NXD5, 32, // 0xd8 - IGD _DGS next DID5
|
||||||
|
NXD6, 32, // 0xdc - IGD _DGS next DID6
|
||||||
|
NXD7, 32, // 0xe0 - IGD _DGS next DID7
|
||||||
|
NXD8, 32, // 0xe4 - IGD _DGS next DID8
|
||||||
|
|
||||||
|
ISCI, 8, // 0xe8 - IGD SMI/SCI mode (0: SCI)
|
||||||
|
PAVP, 8, // 0xe9 - IGD PAVP data
|
||||||
|
Offset (0xeb),
|
||||||
|
OSCC, 8, // 0xeb - PCIe OSC control
|
||||||
|
NPCE, 8, // 0xec - native pcie support
|
||||||
|
PLFL, 8, // 0xed - platform flavor
|
||||||
|
BREV, 8, // 0xee - board revision
|
||||||
|
DPBM, 8, // 0xef - digital port b mode
|
||||||
|
DPCM, 8, // 0xf0 - digital port c mode
|
||||||
|
DPDM, 8, // 0xf1 - digital port d mode
|
||||||
|
ALFP, 8, // 0xf2 - active lfp
|
||||||
|
IMON, 8, // 0xf3 - current graphics turbo imon value
|
||||||
|
MMIO, 8, // 0xf4 - 64bit mmio support
|
||||||
|
|
||||||
|
/* ChromeOS specific */
|
||||||
|
Offset (0x100),
|
||||||
|
#include <vendorcode/google/chromeos/acpi/gnvs.asl>
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set flag to enable USB charging in S3 */
|
||||||
|
Method (S3UE)
|
||||||
|
{
|
||||||
|
Store (One, \S3U0)
|
||||||
|
Store (One, \S3U1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set flag to disable USB charging in S3 */
|
||||||
|
Method (S3UD)
|
||||||
|
{
|
||||||
|
Store (Zero, \S3U0)
|
||||||
|
Store (Zero, \S3U1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set flag to enable USB charging in S5 */
|
||||||
|
Method (S5UE)
|
||||||
|
{
|
||||||
|
Store (One, \S5U0)
|
||||||
|
Store (One, \S5U1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set flag to disable USB charging in S5 */
|
||||||
|
Method (S5UD)
|
||||||
|
{
|
||||||
|
Store (Zero, \S5U0)
|
||||||
|
Store (Zero, \S5U1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
External (\_TZ.THRM)
|
||||||
|
External (\_TZ.SKIN)
|
||||||
|
|
||||||
|
Method (TZUP)
|
||||||
|
{
|
||||||
|
/* Update Primary Thermal Zone */
|
||||||
|
If (CondRefOf (\_TZ.THRM, Local0)) {
|
||||||
|
Notify (\_TZ.THRM, 0x81)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Secondary Thermal Zone */
|
||||||
|
If (CondRefOf (\_TZ.SKIN, Local0)) {
|
||||||
|
Notify (\_TZ.SKIN, 0x81)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Fan 0 thresholds */
|
||||||
|
Method (F0UT, 2)
|
||||||
|
{
|
||||||
|
Store (Arg0, \F0OF)
|
||||||
|
Store (Arg1, \F0ON)
|
||||||
|
TZUP ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Fan 1 thresholds */
|
||||||
|
Method (F1UT, 2)
|
||||||
|
{
|
||||||
|
Store (Arg0, \F1OF)
|
||||||
|
Store (Arg1, \F1ON)
|
||||||
|
TZUP ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Fan 2 thresholds */
|
||||||
|
Method (F2UT, 2)
|
||||||
|
{
|
||||||
|
Store (Arg0, \F2OF)
|
||||||
|
Store (Arg1, \F2ON)
|
||||||
|
TZUP ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Fan 3 thresholds */
|
||||||
|
Method (F3UT, 2)
|
||||||
|
{
|
||||||
|
Store (Arg0, \F3OF)
|
||||||
|
Store (Arg1, \F3ON)
|
||||||
|
TZUP ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Fan 4 thresholds */
|
||||||
|
Method (F4UT, 2)
|
||||||
|
{
|
||||||
|
Store (Arg0, \F4OF)
|
||||||
|
Store (Arg1, \F4ON)
|
||||||
|
TZUP ()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update Temperature Sensor ID */
|
||||||
|
Method (TMPU, 1)
|
||||||
|
{
|
||||||
|
Store (Arg0, \TMPS)
|
||||||
|
TZUP ()
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2009 coresystems GmbH
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
Name(\_S0, Package(){0x0,0x0,0x0,0x0})
|
||||||
|
// Name(\_S1, Package(){0x1,0x1,0x0,0x0})
|
||||||
|
Name(\_S3, Package(){0x5,0x5,0x0,0x0})
|
||||||
|
Name(\_S4, Package(){0x6,0x6,0x0,0x0})
|
||||||
|
Name(\_S5, Package(){0x7,0x7,0x0,0x0})
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
Scope(\)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 _BAYTRAIL_ACPI_H_
|
||||||
|
#define _BAYTRAIL_ACPI_H_
|
||||||
|
|
||||||
|
#include <arch/acpi.h>
|
||||||
|
|
||||||
|
void acpi_create_intel_hpet(acpi_hpet_t * hpet);
|
||||||
|
void acpi_create_serialio_ssdt(acpi_header_t *ssdt);
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_ACPI_H_ */
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_GPIO_H_
|
||||||
|
#define _BAYTRAIL_GPIO_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <arch/io.h>
|
||||||
|
#include <baytrail/iomap.h>
|
||||||
|
|
||||||
|
/* Registers sitting behind the IO_BASE_ADDRESS */
|
||||||
|
|
||||||
|
#define SCORE_PCONF_OFFSET 0x0000
|
||||||
|
#define SSUS_PCONF_OFFSET 0x2000
|
||||||
|
|
||||||
|
static inline unsigned int score_pconf0(int pad_num)
|
||||||
|
{
|
||||||
|
return IO_BASE_ADDRESS + SCORE_PCONF_OFFSET + pad_num * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline unsigned int ssus_pconf0(int pad_num)
|
||||||
|
{
|
||||||
|
return IO_BASE_ADDRESS + SSUS_PCONF_OFFSET + pad_num * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void score_select_func(int pad, int func)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
uint32_t pconf0_addr = score_pconf0(pad);
|
||||||
|
|
||||||
|
reg = read32(pconf0_addr);
|
||||||
|
reg &= ~0x7;
|
||||||
|
reg |= func & 0x7;
|
||||||
|
write32(pconf0_addr, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ssus_select_func(int pad, int func)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
uint32_t pconf0_addr = ssus_pconf0(pad);
|
||||||
|
|
||||||
|
reg = read32(pconf0_addr);
|
||||||
|
reg &= ~0x7;
|
||||||
|
reg |= func & 0x7;
|
||||||
|
write32(pconf0_addr, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SCORE Pad definitions. */
|
||||||
|
#define PCU_SMB_CLK_PAD 88
|
||||||
|
#define PCU_SMB_DATA_PAD 90
|
||||||
|
#define PCU_SMB_ALERT_PAD 92
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_GPIO_H_ */
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_IOMAP_H_
|
||||||
|
#define _BAYTRAIL_IOMAP_H_
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory Mapped IO bases. */
|
||||||
|
|
||||||
|
#define PMC_BASE_ADDRESS 0xfed03000
|
||||||
|
#define IO_BASE_ADDRESS 0xfed0c000
|
||||||
|
#define ILB_BASE_ADDRESS 0xfed08000
|
||||||
|
#define SPI_BASE_ADDRESS 0xfed01000
|
||||||
|
#define MPHY_BASE_ADDRESS 0xfef00000
|
||||||
|
#define RCBA_BASE_ADDRESS 0xfed1c000
|
||||||
|
|
||||||
|
/* IO Port base */
|
||||||
|
#define ACPI_BASE_ADDRESS 0x0400
|
||||||
|
#define GPIO_BASE_ADDRESS 0x0500
|
||||||
|
#define SMBUS_BASE_ADDRESS 0xefa0
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_IOMAP_H_ */
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 _BAYTRAIL_IOSF_H_
|
||||||
|
#define _BAYTRAIL_IOSF_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <baytrail/pci_devs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Bay Trail SoC has a message network called IOSF Sideband. The access
|
||||||
|
* routines are through 3 registers in PCI config space of 00:00.0:
|
||||||
|
* MCR - control register
|
||||||
|
* MDR - data register
|
||||||
|
* MCRX - control register extension
|
||||||
|
* The extension regist is only used for addresses that don't fit into the
|
||||||
|
* 8 bit register address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PCI_DEV
|
||||||
|
#define PCI_DEV(SEGBUS, DEV, FN) ( \
|
||||||
|
(((SEGBUS) & 0xFFF) << 20) | \
|
||||||
|
(((DEV) & 0x1F) << 15) | \
|
||||||
|
(((FN) & 0x07) << 12))
|
||||||
|
#endif
|
||||||
|
#define IOSF_PCI_DEV PCI_DEV(0,SOC_DEV,SOC_FUNC)
|
||||||
|
|
||||||
|
#define MCR_REG 0xd0
|
||||||
|
#define IOSF_OPCODE(x) ((x) << 24)
|
||||||
|
#define IOSF_PORT(x) ((0xff & (x)) << 16)
|
||||||
|
#define IOSF_REG(x) ((0xff & (x)) << 8)
|
||||||
|
#define IOSF_BYTE_EN 0xf0
|
||||||
|
#define MDR_REG 0xd4
|
||||||
|
#define MCRX_REG 0xd8
|
||||||
|
|
||||||
|
uint32_t iosf_bunit_read(int reg);
|
||||||
|
void iosf_bunit_write(int reg, uint32_t val);
|
||||||
|
|
||||||
|
/* IOSF ports. */
|
||||||
|
#define IOSF_PORT_AUNIT 0x00 /* IO Arbiter unit */
|
||||||
|
#define IOSF_PORT_SYSMEMC 0x01 /* System Memory Controller */
|
||||||
|
#define IOSF_PORT_CPU_BUS 0x02 /* CPU Bus Interface Controller */
|
||||||
|
#define IOSF_PORT_BUNIT 0x03 /* System Memroy Arbiter/Bunit */
|
||||||
|
#define IOSF_PORT_PMC 0x04 /* Power Management Controller */
|
||||||
|
#define IOSF_PORT_GFX 0x06 /* Graphics Adapter */
|
||||||
|
#define IOSF_PORT_SYSMEMIO 0x0c /* System Memory IO */
|
||||||
|
#define IOSF_PORT_USBPHY 0x43 /* USB PHY */
|
||||||
|
#define IOSF_PORT_SATAPHY 0xa3 /* SATA PHY */
|
||||||
|
#define IOSF_PORT_PCIEPHY 0xa3 /* PCIE PHY */
|
||||||
|
|
||||||
|
/* Read and write opcodes differ per port. */
|
||||||
|
#define IOSF_OP_READ_AUNIT 0x10
|
||||||
|
#define IOSF_OP_WRITE_AUNIT (IOSF_OP_READ_AUNIT | 1)
|
||||||
|
#define IOSF_OP_READ_SYSMEMC 0x10
|
||||||
|
#define IOSF_OP_WRITE_SYSMEMC (IOSF_OP_READ_SYSMEMC | 1)
|
||||||
|
#define IOSF_OP_READ_CPU_BUS 0x10
|
||||||
|
#define IOSF_OP_WRITE_CPU_BUS (IOSF_OP_READ_CPU_BUS | 1)
|
||||||
|
#define IOSF_OP_READ_BUNIT 0x10
|
||||||
|
#define IOSF_OP_WRITE_BUNIT (IOSF_OP_READ_BUNIT | 1)
|
||||||
|
#define IOSF_OP_READ_PMC 0x06
|
||||||
|
#define IOSF_OP_WRITE_PMC (IOSF_OP_READ_PMC | 1)
|
||||||
|
#define IOSF_OP_READ_GFX 0x00
|
||||||
|
#define IOSF_OP_WRITE_GFX (IOSF_OP_READ_GFX | 1)
|
||||||
|
#define IOSF_OP_READ_SYSMEMIO 0x06
|
||||||
|
#define IOSF_OP_WRITE_SYSMEMIO (IOSF_OP_READ_SYSMEMIO | 1)
|
||||||
|
#define IOSF_OP_READ_USBPHY 0x06
|
||||||
|
#define IOSF_OP_WRITE_USBPHY (IOSF_OP_READ_USBPHY | 1)
|
||||||
|
#define IOSF_OP_READ_SATAPHY 0x00
|
||||||
|
#define IOSF_OP_WRITE_SATAPHY (IOSF_OP_READ_SATAPHY | 1)
|
||||||
|
#define IOSF_OP_READ_PCIEPHY 0x00
|
||||||
|
#define IOSF_OP_WRITE_PCIEPHY (IOSF_OP_READ_PCIEPHY | 1)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BUNIT Registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BNOCACHE 0x23
|
||||||
|
/* BMBOUND has a 128MiB granularity. Highest address is 0xf8000000. */
|
||||||
|
#define BUNIT_BMBOUND 0x25
|
||||||
|
/* BMBOUND_HI describes the available ram above 4GiB. It has a
|
||||||
|
* 256MiB granularity. Physical address bits 35:28 are compared with 31:24
|
||||||
|
* bits in the BMBOUND_HI register. Also note that since BMBOUND has 128MiB
|
||||||
|
* granularity care needs to be taken with the e820 map to account for a hole
|
||||||
|
* in the ram. */
|
||||||
|
#define BUNIT_BMBOUND_HI 0x26
|
||||||
|
#define BUNIT_MMCONF_REG 0x27
|
||||||
|
/* The SMMRR registers define the SMM region in MiB granularity. */
|
||||||
|
#define BUNIT_SMRRL 0x2e
|
||||||
|
#define BUNIT_SMRRH 0x2f
|
||||||
|
# define BUNIT_SMRR_ENABLE (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_IOSF_H_ */
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_LPC_H_
|
||||||
|
#define _BAYTRAIL_LPC_H_
|
||||||
|
|
||||||
|
/* PCI config registers in LPC bridge. */
|
||||||
|
#define ABASE 0x40
|
||||||
|
#define PBASE 0x44
|
||||||
|
#define GBASE 0x48
|
||||||
|
#define IOBASE 0x4c
|
||||||
|
#define IBASE 0x50
|
||||||
|
#define SBASE 0x54
|
||||||
|
#define MPBASE 0x58
|
||||||
|
#define UART_CONT 0x80
|
||||||
|
#define RCBA 0xf0
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_LPC_H_ */
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _MRC_CACHE_H_
|
||||||
|
#define _MRC_CACHE_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Wrapper object to save MRC information. */
|
||||||
|
struct mrc_saved_data {
|
||||||
|
uint32_t signature;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t checksum;
|
||||||
|
uint32_t reserved;
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/* Locate the most recently saved MRC data. */
|
||||||
|
int mrc_cache_get_current(const struct mrc_saved_data **cache);
|
||||||
|
|
||||||
|
/* Stash the resulting MRC data to be saved in non-volatile storage later. */
|
||||||
|
int mrc_cache_stash_data(void *data, size_t size);
|
||||||
|
#endif /* _MRC_CACHE_H_ */
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* MRC wrapper definitions
|
||||||
|
*
|
||||||
|
* Copyright 2013 Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _MRC_WRAPPER_H_
|
||||||
|
#define _MRC_WRAPPER_H_
|
||||||
|
|
||||||
|
#define MRC_PARAMS_VER 1
|
||||||
|
|
||||||
|
#define NUM_CHANNELS 2
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DRAM_INFO_SPD_SMBUS, /* Use the typical SPD smbus access. */
|
||||||
|
DRAM_INFO_SPD_MEM, /* SPD info in memory. */
|
||||||
|
DRAM_INFO_DETAILED, /* Timing info not in SPD format. */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum dram_type {
|
||||||
|
DRAM_DDR3,
|
||||||
|
DRAM_DDR3L,
|
||||||
|
DRAM_LPDDR3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Errors returned by the MRC wrapper. */
|
||||||
|
enum mrc_wrapper_error {
|
||||||
|
INVALID_VER = -1,
|
||||||
|
INVALID_DRAM_TYPE = -2,
|
||||||
|
INVALID_SLEEP_MODE = -3,
|
||||||
|
PLATFORM_SETTINGS_FAIL = -4,
|
||||||
|
DIMM_DETECTION_FAILURE = -5,
|
||||||
|
MEMORY_CONFIG_FAILURE = -6,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mrc_mainboard_params {
|
||||||
|
int dram_type;
|
||||||
|
int dram_info_location; /* DRAM_INFO_* */
|
||||||
|
int spd_addrs[NUM_CHANNELS];
|
||||||
|
void *dram_data[NUM_CHANNELS]; /* SPD or Timing specific data. */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct mrc_params {
|
||||||
|
/* Mainboard Inputs */
|
||||||
|
int version;
|
||||||
|
|
||||||
|
struct mrc_mainboard_params mainboard;
|
||||||
|
|
||||||
|
void (*console_out)(unsigned char byte);
|
||||||
|
|
||||||
|
int prev_sleep_state;
|
||||||
|
|
||||||
|
int saved_data_size;
|
||||||
|
const void *saved_data;
|
||||||
|
|
||||||
|
int txe_size_mb; /* TXE memory size in megabytes. */
|
||||||
|
|
||||||
|
/* Outputs */
|
||||||
|
void *txe_base_address;
|
||||||
|
int data_to_save_size;
|
||||||
|
void *data_to_save;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/* Call into wrapper. */
|
||||||
|
typedef int (*mrc_wrapper_entry_t)(struct mrc_params *);
|
||||||
|
|
||||||
|
#endif /* _MRC_WRAPPER_H_ */
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 _BAYTRAIL_MSR_H_
|
||||||
|
#define _BAYTRAIL_MSR_H_
|
||||||
|
|
||||||
|
#define MSR_PLATFORM_INFO 0xce
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_IOSF_H_ */
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _NVM_H_
|
||||||
|
#define _NVM_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Determine if area is erased. returns 1 if erased. 0 otherwise. */
|
||||||
|
int nvm_is_erased(const void *start, size_t size);
|
||||||
|
|
||||||
|
/* Erase region according to start and size. Returns < 0 on error else 0. */
|
||||||
|
int nvm_erase(void *start, size_t size);
|
||||||
|
|
||||||
|
/* Write data to NVM. Returns 0 on success < 0 on error. */
|
||||||
|
int nvm_write(void *start, const void *data, size_t size);
|
||||||
|
|
||||||
|
#endif /* _NVM_H_ */
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2009 coresystems GmbH
|
||||||
|
* Copyright (C) 2011 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 "vendorcode/google/chromeos/gnvs.h"
|
||||||
|
typedef struct {
|
||||||
|
/* Miscellaneous */
|
||||||
|
u16 osys; /* 0x00 - Operating System */
|
||||||
|
u8 smif; /* 0x02 - SMI function call ("TRAP") */
|
||||||
|
u8 prm0; /* 0x03 - SMI function call parameter */
|
||||||
|
u8 prm1; /* 0x04 - SMI function call parameter */
|
||||||
|
u8 scif; /* 0x05 - SCI function call (via _L00) */
|
||||||
|
u8 prm2; /* 0x06 - SCI function call parameter */
|
||||||
|
u8 prm3; /* 0x07 - SCI function call parameter */
|
||||||
|
u8 lckf; /* 0x08 - Global Lock function for EC */
|
||||||
|
u8 prm4; /* 0x09 - Lock function parameter */
|
||||||
|
u8 prm5; /* 0x0a - Lock function parameter */
|
||||||
|
u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
|
||||||
|
u8 lids; /* 0x0f - LID state (open = 1) */
|
||||||
|
u8 pwrs; /* 0x10 - Power state (AC = 1) */
|
||||||
|
/* Thermal policy */
|
||||||
|
u8 tlvl; /* 0x11 - Throttle Level Limit */
|
||||||
|
u8 flvl; /* 0x12 - Current FAN Level */
|
||||||
|
u8 tcrt; /* 0x13 - Critical Threshold */
|
||||||
|
u8 tpsv; /* 0x14 - Passive Threshold */
|
||||||
|
u8 tmax; /* 0x15 - CPU Tj_max */
|
||||||
|
u8 f0of; /* 0x16 - FAN 0 OFF Threshold */
|
||||||
|
u8 f0on; /* 0x17 - FAN 0 ON Threshold */
|
||||||
|
u8 f0pw; /* 0x18 - FAN 0 PWM value */
|
||||||
|
u8 f1of; /* 0x19 - FAN 1 OFF Threshold */
|
||||||
|
u8 f1on; /* 0x1a - FAN 1 ON Threshold */
|
||||||
|
u8 f1pw; /* 0x1b - FAN 1 PWM value */
|
||||||
|
u8 f2of; /* 0x1c - FAN 2 OFF Threshold */
|
||||||
|
u8 f2on; /* 0x1d - FAN 2 ON Threshold */
|
||||||
|
u8 f2pw; /* 0x1e - FAN 2 PWM value */
|
||||||
|
u8 f3of; /* 0x1f - FAN 3 OFF Threshold */
|
||||||
|
u8 f3on; /* 0x20 - FAN 3 ON Threshold */
|
||||||
|
u8 f3pw; /* 0x21 - FAN 3 PWM value */
|
||||||
|
u8 f4of; /* 0x22 - FAN 4 OFF Threshold */
|
||||||
|
u8 f4on; /* 0x23 - FAN 4 ON Threshold */
|
||||||
|
u8 f4pw; /* 0x24 - FAN 4 PWM value */
|
||||||
|
u8 tmps; /* 0x25 - Temperature Sensor ID */
|
||||||
|
u8 rsvd3[2];
|
||||||
|
/* Processor Identification */
|
||||||
|
u8 apic; /* 0x28 - APIC enabled */
|
||||||
|
u8 mpen; /* 0x29 - MP capable/enabled */
|
||||||
|
u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
|
||||||
|
u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
|
||||||
|
u8 ppcm; /* 0x2c - Max. PPC state */
|
||||||
|
u8 pcnt; /* 0x2d - Processor Count */
|
||||||
|
u8 rsvd4[4];
|
||||||
|
/* Super I/O & CMOS config */
|
||||||
|
u8 natp; /* 0x32 - SIO type */
|
||||||
|
u8 s5u0; /* 0x33 - Enable USB0 in S5 */
|
||||||
|
u8 s5u1; /* 0x34 - Enable USB1 in S5 */
|
||||||
|
u8 s3u0; /* 0x35 - Enable USB0 in S3 */
|
||||||
|
u8 s3u1; /* 0x36 - Enable USB1 in S3 */
|
||||||
|
u8 s33g; /* 0x37 - Enable S3 in 3G */
|
||||||
|
u32 cmem; /* 0x38 - CBMEM TOC */
|
||||||
|
/* Integrated Graphics Device */
|
||||||
|
u8 igds; /* 0x3c - IGD state */
|
||||||
|
u8 tlst; /* 0x3d - Display Toggle List Pointer */
|
||||||
|
u8 cadl; /* 0x3e - currently attached devices */
|
||||||
|
u8 padl; /* 0x3f - previously attached devices */
|
||||||
|
u16 cste; /* 0x40 - current display state */
|
||||||
|
u16 nste; /* 0x42 - next display state */
|
||||||
|
u16 sste; /* 0x44 - set display state */
|
||||||
|
u8 ndid; /* 0x46 - number of device ids */
|
||||||
|
u32 did[5]; /* 0x47 - 5b device id 1..5 */
|
||||||
|
/* TPM support */
|
||||||
|
u8 tpmp; /* 0x5b - TPM Present */
|
||||||
|
u8 tpme; /* 0x5c - TPM Enable */
|
||||||
|
u8 rsvd5[3];
|
||||||
|
/* LynxPoint Serial IO device BARs */
|
||||||
|
u32 s0b[8]; /* 0x60 - 0x7f - BAR0 */
|
||||||
|
u32 s1b[8]; /* 0x80 - 0x9f - BAR1 */
|
||||||
|
u32 cbmc; /* 0xa0 - 0xa3 - coreboot memconsole */
|
||||||
|
u8 rsvd6[16];
|
||||||
|
/* IGD OpRegion (not implemented yet) */
|
||||||
|
u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
|
||||||
|
u8 ibtt; /* 0xb8 - IGD boot type */
|
||||||
|
u8 ipat; /* 0xb9 - IGD panel type */
|
||||||
|
u8 itvf; /* 0xba - IGD TV format */
|
||||||
|
u8 itvm; /* 0xbb - IGD TV minor format */
|
||||||
|
u8 ipsc; /* 0xbc - IGD Panel Scaling */
|
||||||
|
u8 iblc; /* 0xbd - IGD BLC configuration */
|
||||||
|
u8 ibia; /* 0xbe - IGD BIA configuration */
|
||||||
|
u8 issc; /* 0xbf - IGD SSC configuration */
|
||||||
|
u8 i409; /* 0xc0 - IGD 0409 modified settings */
|
||||||
|
u8 i509; /* 0xc1 - IGD 0509 modified settings */
|
||||||
|
u8 i609; /* 0xc2 - IGD 0609 modified settings */
|
||||||
|
u8 i709; /* 0xc3 - IGD 0709 modified settings */
|
||||||
|
u8 idmm; /* 0xc4 - IGD Power Conservation */
|
||||||
|
u8 idms; /* 0xc5 - IGD DVMT memory size */
|
||||||
|
u8 if1e; /* 0xc6 - IGD Function 1 Enable */
|
||||||
|
u8 hvco; /* 0xc7 - IGD HPLL VCO */
|
||||||
|
u32 nxd[8]; /* 0xc8 - IGD next state DIDx for _DGS */
|
||||||
|
u8 isci; /* 0xe8 - IGD SMI/SCI mode (0: SCI) */
|
||||||
|
u8 pavp; /* 0xe9 - IGD PAVP data */
|
||||||
|
u8 rsvd12; /* 0xea - rsvd */
|
||||||
|
u8 oscc; /* 0xeb - PCIe OSC control */
|
||||||
|
u8 npce; /* 0xec - native pcie support */
|
||||||
|
u8 plfl; /* 0xed - platform flavor */
|
||||||
|
u8 brev; /* 0xee - board revision */
|
||||||
|
u8 dpbm; /* 0xef - digital port b mode */
|
||||||
|
u8 dpcm; /* 0xf0 - digital port c mode */
|
||||||
|
u8 dpdm; /* 0xf1 - digital port c mode */
|
||||||
|
u8 alfp; /* 0xf2 - active lfp */
|
||||||
|
u8 imon; /* 0xf3 - current graphics turbo imon value */
|
||||||
|
u8 mmio; /* 0xf4 - 64bit mmio support */
|
||||||
|
u8 rsvd13[11]; /* 0xf5 - rsvd */
|
||||||
|
|
||||||
|
/* ChromeOS specific (starts at 0x100)*/
|
||||||
|
chromeos_acpi_t chromeos;
|
||||||
|
} __attribute__((packed)) global_nvs_t;
|
||||||
|
|
||||||
|
#ifdef __SMM__
|
||||||
|
/* Used in SMM to find the ACPI GNVS address */
|
||||||
|
global_nvs_t *smm_get_gnvs(void);
|
||||||
|
#endif
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_PCI_DEVS_H_
|
||||||
|
#define _BAYTRAIL_PCI_DEVS_H_
|
||||||
|
|
||||||
|
/* All these devices live on bus 0 with the associated device and function */
|
||||||
|
|
||||||
|
/* SoC transaction router */
|
||||||
|
#define SOC_DEV 0
|
||||||
|
#define SOC_FUNC 0
|
||||||
|
# define SOC_DEVID 0x0f00
|
||||||
|
|
||||||
|
/* Graphics and Display */
|
||||||
|
#define GFX_DEV 2
|
||||||
|
#define GFX_FUNC 0
|
||||||
|
# define GFX_DEVID 0x0f31
|
||||||
|
|
||||||
|
/* MMC Port */
|
||||||
|
#define MMC_DEV 16
|
||||||
|
#define MMC_FUNC 0
|
||||||
|
# define MMC_DEVID 0x0f14
|
||||||
|
|
||||||
|
/* SDIO Port */
|
||||||
|
#define SDIO_DEV 17
|
||||||
|
#define SDIO_FUNC 0
|
||||||
|
# define SDIO_DEVID 0x0f15
|
||||||
|
|
||||||
|
/* SD Port */
|
||||||
|
#define SD_DEV 18
|
||||||
|
#define SD_FUNC 0
|
||||||
|
# define SD_DEVID 0x0f16
|
||||||
|
|
||||||
|
/* SATA */
|
||||||
|
#define SATA_DEV 19
|
||||||
|
#define SATA_FUNC 0
|
||||||
|
# define ACHI1_DEVID 0x0f22
|
||||||
|
# define ACHI2_DEVID 0x0f23
|
||||||
|
|
||||||
|
/* xHCI */
|
||||||
|
#define XHCI_DEV 20
|
||||||
|
#define XHCI_FUNC 0
|
||||||
|
# define XCHI_DEVID 0x0f35
|
||||||
|
|
||||||
|
/* LPE Audio */
|
||||||
|
#define LPE_DEV 21
|
||||||
|
#define LPE_FUNC 0
|
||||||
|
# define LPE_DEVID 0x0f28
|
||||||
|
|
||||||
|
/* Serial IO 1 */
|
||||||
|
#define SIO1_DEV 24
|
||||||
|
# define SIO_DMA1_DEV SIO1_DEV
|
||||||
|
# define SIO_DMA1_FUNC 0
|
||||||
|
# define SIO_DMA1_DEVID 0x0f40
|
||||||
|
# define I2C1_DEV SIO1_DEV
|
||||||
|
# define I2C1_FUNC 1
|
||||||
|
# define I2C1_DEVID 0x0f41
|
||||||
|
# define I2C2_DEV SIO1_DEV
|
||||||
|
# define I2C2_FUNC 2
|
||||||
|
# define I2C2_DEVID 0x0f42
|
||||||
|
# define I2C3_DEV SIO1_DEV
|
||||||
|
# define I2C3_FUNC 3
|
||||||
|
# define I2C3_DEVID 0x0f43
|
||||||
|
# define I2C4_DEV SIO1_DEV
|
||||||
|
# define I2C4_FUNC 4
|
||||||
|
# define I2C4_DEVID 0x0f44
|
||||||
|
# define I2C5_DEV SIO1_DEV
|
||||||
|
# define I2C5_FUNC 5
|
||||||
|
# define I2C5_DEVID 0x0f45
|
||||||
|
# define I2C6_DEV SIO1_DEV
|
||||||
|
# define I2C6_FUNC 6
|
||||||
|
# define I2C6_DEVID 0x0f46
|
||||||
|
# define I2C7_DEV SIO1_DEV
|
||||||
|
# define I2C7_FUNC 7
|
||||||
|
# define I2C7_DEVID 0x0f47
|
||||||
|
|
||||||
|
/* Trusted Execution Engine */
|
||||||
|
#define TXE_DEV 26
|
||||||
|
#define TXE_FUNC 0
|
||||||
|
# define TXE_DEVID 0x0f18
|
||||||
|
|
||||||
|
/* HD Audio */
|
||||||
|
#define HDA_DEV 27
|
||||||
|
#define HDA_FUNC 0
|
||||||
|
# define HDA_DEVID 0x0f04
|
||||||
|
|
||||||
|
/* PCIe Ports */
|
||||||
|
#define PCIE_DEV 28
|
||||||
|
# define PCIE_PORT1_FUNC 0
|
||||||
|
# define PCIE_PORT1_DEVID 0x0f48
|
||||||
|
# define PCIE_PORT2_FUNC 1
|
||||||
|
# define PCIE_PORT2_DEVID 0x0f4a
|
||||||
|
# define PCIE_PORT3_FUNC 2
|
||||||
|
# define PCIE_PORT3_DEVID 0x0f4c
|
||||||
|
# define PCIE_PORT4_FUNC 3
|
||||||
|
# define PCIE_PORT4_DEVID 0x0f4e
|
||||||
|
|
||||||
|
/* EHCI */
|
||||||
|
#define EHCI_DEV 29
|
||||||
|
#define EHCI_FUNC 29
|
||||||
|
# define EHCI_DEVID 0x0f34
|
||||||
|
|
||||||
|
/* Serial IO 2 */
|
||||||
|
#define SIO2_DEV 30
|
||||||
|
# define SIO_DMA2_DEV SIO2_DEV
|
||||||
|
# define SIO_DMA2_FUNC 0
|
||||||
|
# define SIO_DMA2_DEVID 0x0f06
|
||||||
|
# define PWM1_DEV SIO2_DEV
|
||||||
|
# define PWM1_FUNC 1
|
||||||
|
# define PWM1_DEVID 0x0f08
|
||||||
|
# define PWM2_DEV SIO2_DEV
|
||||||
|
# define PWM2_FUNC 2
|
||||||
|
# define PWM2_DEVID 0x0f09
|
||||||
|
# define HSUART1_DEV SIO2_DEV
|
||||||
|
# define HSUART1_FUNC 3
|
||||||
|
# define HSUART1_DEVID 0x0f0a
|
||||||
|
# define HSUART2_DEV SIO2_DEV
|
||||||
|
# define HSUART2_FUNC 4
|
||||||
|
# define HSUART2_DEVID 0x0f0c
|
||||||
|
# define SPI_DEV SIO2_DEV
|
||||||
|
# define SPI_FUNC 5
|
||||||
|
# define SPI_DEVID 0xf0e
|
||||||
|
|
||||||
|
/* Platform Controller Unit */
|
||||||
|
#define PCU_DEV 31
|
||||||
|
# define LPC_DEV PCU_DEV
|
||||||
|
# define LPC_FUNC 0
|
||||||
|
# define LPC_DEVID 0x0f1c
|
||||||
|
# define SMBUS_DEV PCU_DEV
|
||||||
|
# define SMBUS_FUNC 3
|
||||||
|
# define SMBUS_DEVID 0x0f12
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_PCI_DEVS_H_ */
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_PMC_H_
|
||||||
|
#define _BAYTRAIL_PMC_H_
|
||||||
|
|
||||||
|
|
||||||
|
#define IOCOM1 0x3f8
|
||||||
|
|
||||||
|
/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
|
||||||
|
#define GEN_PMCONF1 0x20
|
||||||
|
# define UART_EN (1 << 24)
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_PMC_H_ */
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_ROMSTAGE_H_
|
||||||
|
#define _BAYTRAIL_ROMSTAGE_H_
|
||||||
|
|
||||||
|
#if !defined(__PRE_RAM__)
|
||||||
|
#error "Don't include romstage.h from a ramstage compilation unit!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <arch/cpu.h>
|
||||||
|
#include <baytrail/mrc_wrapper.h>
|
||||||
|
|
||||||
|
struct romstage_params {
|
||||||
|
struct mrc_params *mrc_params;
|
||||||
|
};
|
||||||
|
|
||||||
|
void mainboard_romstage_entry(unsigned long bist);
|
||||||
|
void romstage_common(const struct romstage_params *params);
|
||||||
|
void * asmlinkage romstage_main(unsigned long bist);
|
||||||
|
void asmlinkage romstage_after_car(void);
|
||||||
|
void raminit(struct mrc_params *mp, int prev_sleep_state);
|
||||||
|
|
||||||
|
#if CONFIG_ENABLE_BUILTIN_COM1
|
||||||
|
void byt_config_com1_and_enable(void);
|
||||||
|
#else
|
||||||
|
static inline void byt_config_com1_and_enable(void) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _BAYTRAIL_ROMSTAGE_H_ */
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 <baytrail/iosf.h>
|
||||||
|
|
||||||
|
static void bootblock_cpu_init(void)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
|
||||||
|
/* Set up the MMCONF range. The register lives in the BUNIT. The
|
||||||
|
* IO variant of the config access needs to be used initially to
|
||||||
|
* properly configure as the IOSF access registers live in PCI
|
||||||
|
* config space. */
|
||||||
|
reg = 0;
|
||||||
|
/* Clear the extended register. */
|
||||||
|
pci_io_write_config32(IOSF_PCI_DEV, MCRX_REG, reg);
|
||||||
|
reg = CONFIG_MMCONF_BASE_ADDRESS | 1;
|
||||||
|
pci_io_write_config32(IOSF_PCI_DEV, MDR_REG, reg);
|
||||||
|
reg = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) | IOSF_PORT(IOSF_PORT_BUNIT) |
|
||||||
|
IOSF_REG(BUNIT_MMCONF_REG) | IOSF_BYTE_EN;
|
||||||
|
pci_io_write_config32(IOSF_PCI_DEV, MCR_REG, reg);
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <arch/pci_ops.h>
|
||||||
|
|
||||||
|
#include <baytrail/pci_devs.h>
|
||||||
|
#include <baytrail/ramstage.h>
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
static void pci_domain_set_resources(device_t dev)
|
||||||
|
{
|
||||||
|
assign_resources(dev->link_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device_operations pci_domain_ops = {
|
||||||
|
.read_resources = pci_domain_read_resources,
|
||||||
|
.set_resources = pci_domain_set_resources,
|
||||||
|
.enable_resources = NULL,
|
||||||
|
.init = NULL,
|
||||||
|
.scan_bus = pci_domain_scan_bus,
|
||||||
|
.ops_pci_bus = pci_bus_default_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void cpu_bus_init(device_t dev)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "cpu_bus_init()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_bus_noop(device_t dev) { }
|
||||||
|
|
||||||
|
static struct device_operations cpu_bus_ops = {
|
||||||
|
.read_resources = cpu_bus_noop,
|
||||||
|
.set_resources = cpu_bus_noop,
|
||||||
|
.enable_resources = cpu_bus_noop,
|
||||||
|
.init = cpu_bus_init,
|
||||||
|
.scan_bus = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void enable_dev(device_t dev)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "enable_dev(%s, %d)\n",
|
||||||
|
dev_name(dev), dev->path.type);
|
||||||
|
/* Set the operations if it is a special bus type */
|
||||||
|
if (dev->path.type == DEVICE_PATH_DOMAIN) {
|
||||||
|
dev->ops = &pci_domain_ops;
|
||||||
|
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
|
||||||
|
dev->ops = &cpu_bus_ops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct chip_operations soc_intel_baytrail_ops = {
|
||||||
|
CHIP_NAME("Intel BayTrail SoC")
|
||||||
|
.enable_dev = enable_dev,
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 _BAYTRAIL_CHIP_H_
|
||||||
|
#define _BAYTRAIL_CHIP_H_
|
||||||
|
/* The devicetree parser expects chip.h to reside directly in the path
|
||||||
|
* specified by the devicetree. */
|
||||||
|
|
||||||
|
struct soc_intel_baytrail_config {
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct chip_operations soc_intel_baytrail_ops;
|
||||||
|
#endif /* _BAYTRAIL_CHIP_H_ */
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 <baytrail/iosf.h>
|
||||||
|
|
||||||
|
#if !defined(__PRE_RAM__)
|
||||||
|
#define IOSF_PCI_BASE (CONFIG_MMCONF_BASE_ADDRESS + (IOSF_PCI_DEV << 12))
|
||||||
|
|
||||||
|
static inline void write_iosf_reg(int reg, uint32_t value)
|
||||||
|
{
|
||||||
|
write32(IOSF_PCI_BASE + reg, value);
|
||||||
|
}
|
||||||
|
static inline uint32_t read_iosf_reg(int reg)
|
||||||
|
{
|
||||||
|
return read32(IOSF_PCI_BASE + reg);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void write_iosf_reg(int reg, uint32_t value)
|
||||||
|
{
|
||||||
|
pci_write_config32(IOSF_PCI_DEV, reg, value);
|
||||||
|
}
|
||||||
|
static inline uint32_t read_iosf_reg(int reg)
|
||||||
|
{
|
||||||
|
return pci_read_config32(IOSF_PCI_DEV, reg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t iosf_bunit_read(int reg)
|
||||||
|
{
|
||||||
|
uint32_t cr = IOSF_OPCODE(IOSF_OP_READ_BUNIT) |
|
||||||
|
IOSF_PORT(IOSF_PORT_BUNIT) | IOSF_REG(reg) | IOSF_BYTE_EN;
|
||||||
|
|
||||||
|
write_iosf_reg(MCR_REG, cr);
|
||||||
|
return read_iosf_reg(MDR_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iosf_bunit_write(int reg, uint32_t val)
|
||||||
|
{
|
||||||
|
uint32_t cr = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) |
|
||||||
|
IOSF_PORT(IOSF_PORT_BUNIT) | IOSF_REG(reg) | IOSF_BYTE_EN;
|
||||||
|
|
||||||
|
write_iosf_reg(MCR_REG, cr);
|
||||||
|
write_iosf_reg(MDR_REG, val);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 wacbmem_entryanty 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 <baytrail/iosf.h>
|
||||||
|
|
||||||
|
unsigned long get_top_of_ram(void)
|
||||||
|
{
|
||||||
|
return (unsigned long)(iosf_bunit_read(BUNIT_SMRRL) << 20);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
|
|
@ -0,0 +1,3 @@
|
||||||
|
unsigned microcode[] = {
|
||||||
|
#include "M0C3067_0000030f.h"
|
||||||
|
};
|
|
@ -0,0 +1,294 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <console/console.h>
|
||||||
|
#include <cbmem.h>
|
||||||
|
#include <ip_checksum.h>
|
||||||
|
#if CONFIG_CHROMEOS
|
||||||
|
#include <vendorcode/google/chromeos/fmap.h>
|
||||||
|
#endif
|
||||||
|
#include <baytrail/mrc_cache.h>
|
||||||
|
|
||||||
|
#define MRC_DATA_ALIGN 0x1000
|
||||||
|
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
|
||||||
|
|
||||||
|
/* The mrc_data_region describes the larger non-volatile area to store
|
||||||
|
* mrc_saved_data objects.*/
|
||||||
|
struct mrc_data_region {
|
||||||
|
void *base;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* common code */
|
||||||
|
static int mrc_cache_get_region(struct mrc_data_region *region)
|
||||||
|
{
|
||||||
|
#if CONFIG_CHROMEOS
|
||||||
|
int ret;
|
||||||
|
ret = find_fmap_entry("RW_MRC_CACHE", ®ion->base);
|
||||||
|
if (ret >= 0) {
|
||||||
|
region->size = ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE;
|
||||||
|
region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrc_cache_in_region(const struct mrc_data_region *region,
|
||||||
|
const struct mrc_saved_data *cache)
|
||||||
|
{
|
||||||
|
uintptr_t region_end;
|
||||||
|
uintptr_t cache_end;
|
||||||
|
|
||||||
|
if ((uintptr_t)cache < (uintptr_t)region->base)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
region_end = (uintptr_t)region->base;
|
||||||
|
region_end += region->size;
|
||||||
|
|
||||||
|
if ((uintptr_t)cache >= region_end)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((sizeof(*cache) + (uintptr_t)cache) >= region_end)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cache_end = (uintptr_t)cache;
|
||||||
|
cache_end += cache->size + sizeof(*cache);
|
||||||
|
|
||||||
|
if (cache_end > region_end)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mrc_cache_valid(const struct mrc_data_region *region,
|
||||||
|
const struct mrc_saved_data *cache)
|
||||||
|
{
|
||||||
|
uint32_t checksum;
|
||||||
|
|
||||||
|
if (cache->signature != MRC_DATA_SIGNATURE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cache->size > region->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cache->reserved != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
checksum = compute_ip_checksum((void *)&cache->data[0], cache->size);
|
||||||
|
|
||||||
|
if (cache->checksum != checksum)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct mrc_saved_data *
|
||||||
|
next_cache_block(const struct mrc_saved_data *cache)
|
||||||
|
{
|
||||||
|
uintptr_t next = (uintptr_t)cache;
|
||||||
|
|
||||||
|
next += ALIGN(cache->size + sizeof(*cache), MRC_DATA_ALIGN);
|
||||||
|
|
||||||
|
return (const struct mrc_saved_data *)next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate the most recently saved MRC data. */
|
||||||
|
static int __mrc_cache_get_current(const struct mrc_data_region *region,
|
||||||
|
const struct mrc_saved_data **cache)
|
||||||
|
{
|
||||||
|
const struct mrc_saved_data *msd;
|
||||||
|
const struct mrc_saved_data *verified_cache;
|
||||||
|
|
||||||
|
msd = region->base;
|
||||||
|
|
||||||
|
verified_cache = NULL;
|
||||||
|
|
||||||
|
while (mrc_cache_in_region(region, msd) &&
|
||||||
|
mrc_cache_valid(region, msd)) {
|
||||||
|
verified_cache = msd;
|
||||||
|
msd = next_cache_block(msd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verified_cache == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*cache = verified_cache;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrc_cache_get_current(const struct mrc_saved_data **cache)
|
||||||
|
{
|
||||||
|
struct mrc_data_region region;
|
||||||
|
|
||||||
|
if (mrc_cache_get_region(®ion) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return __mrc_cache_get_current(®ion, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__PRE_RAM__)
|
||||||
|
/* romstage code */
|
||||||
|
|
||||||
|
/* Fill in mrc_saved_data structure with payload. */
|
||||||
|
static void mrc_cache_fill(struct mrc_saved_data *cache, void *data,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
cache->signature = MRC_DATA_SIGNATURE;
|
||||||
|
cache->size = size;
|
||||||
|
cache->reserved = 0;
|
||||||
|
memcpy(&cache->data[0], data, size);
|
||||||
|
cache->checksum = compute_ip_checksum((void *)&cache->data[0],
|
||||||
|
cache->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mrc_cache_stash_data(void *data, size_t size)
|
||||||
|
{
|
||||||
|
int cbmem_size;
|
||||||
|
struct mrc_saved_data *cache;
|
||||||
|
|
||||||
|
cbmem_size = sizeof(*cache) + ALIGN(size, 16);
|
||||||
|
|
||||||
|
cache = cbmem_add(CBMEM_ID_MRCDATA, cbmem_size);
|
||||||
|
|
||||||
|
if (cache == NULL) {
|
||||||
|
printk(BIOS_ERR, "No space in cbmem for MRC data.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear alignment padding bytes. */
|
||||||
|
memset(&cache->data[size], 0, cbmem_size - size);
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n",
|
||||||
|
data, cache, size);
|
||||||
|
|
||||||
|
mrc_cache_fill(cache, data, size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* ramstage code */
|
||||||
|
#include <bootstate.h>
|
||||||
|
#include <baytrail/nvm.h>
|
||||||
|
|
||||||
|
static int mrc_slot_valid(const struct mrc_data_region *region,
|
||||||
|
const struct mrc_saved_data *slot,
|
||||||
|
const struct mrc_saved_data *to_save)
|
||||||
|
{
|
||||||
|
uintptr_t region_begin;
|
||||||
|
uintptr_t region_end;
|
||||||
|
uintptr_t slot_end;
|
||||||
|
uintptr_t slot_begin;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
region_begin = (uintptr_t)region->base;
|
||||||
|
region_end = region_begin + region->size;
|
||||||
|
slot_begin = (uintptr_t)slot;
|
||||||
|
size = to_save->size + sizeof(*to_save);
|
||||||
|
slot_end = slot_begin + size;
|
||||||
|
|
||||||
|
if (slot_begin < region_begin || slot_begin > region_end)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (size > region->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (slot_end > region_end || slot_end < region_begin)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!nvm_is_erased(slot, size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct mrc_saved_data *
|
||||||
|
mrc_cache_next_slot(const struct mrc_data_region *region,
|
||||||
|
const struct mrc_saved_data *current_slot)
|
||||||
|
{
|
||||||
|
const struct mrc_saved_data *next_slot;
|
||||||
|
|
||||||
|
if (current_slot == NULL) {
|
||||||
|
next_slot = region->base;
|
||||||
|
} else {
|
||||||
|
next_slot = next_cache_block(current_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_mrc_cache(void *unused)
|
||||||
|
{
|
||||||
|
const struct mrc_saved_data *current_boot;
|
||||||
|
const struct mrc_saved_data *current_saved;
|
||||||
|
const struct mrc_saved_data *next_slot;
|
||||||
|
struct mrc_data_region region;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "Updating MRC cache data.\n");
|
||||||
|
|
||||||
|
current_boot = cbmem_find(CBMEM_ID_MRCDATA);
|
||||||
|
if (!current_boot) {
|
||||||
|
printk(BIOS_ERR, "No MRC cache in cbmem.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mrc_cache_get_region(®ion)) {
|
||||||
|
printk(BIOS_ERR, "Could not obtain MRC cache region.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mrc_cache_valid(®ion, current_boot)) {
|
||||||
|
printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_saved = NULL;
|
||||||
|
|
||||||
|
if (!__mrc_cache_get_current(®ion, ¤t_saved)) {
|
||||||
|
if (current_saved->size == current_boot->size &&
|
||||||
|
!memcmp(¤t_saved->data[0], ¤t_boot->data[0],
|
||||||
|
current_saved->size)) {
|
||||||
|
printk(BIOS_DEBUG, "MRC cache up to date.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next_slot = mrc_cache_next_slot(®ion, current_saved);
|
||||||
|
|
||||||
|
if (!mrc_slot_valid(®ion, next_slot, current_boot)) {
|
||||||
|
if (nvm_erase(region.base, region.size) < 0) {
|
||||||
|
printk(BIOS_DEBUG, "Could not erase MRC region.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next_slot = region.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm_write((void *)next_slot, current_boot,
|
||||||
|
current_boot->size + sizeof(*current_boot));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOT_STATE_INIT_ENTRIES(mrc_cache_update) = {
|
||||||
|
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
|
||||||
|
update_mrc_cache, NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__PRE_RAM__) */
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <stddef.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <spi-generic.h>
|
||||||
|
#include <spi_flash.h>
|
||||||
|
#include <baytrail/nvm.h>
|
||||||
|
|
||||||
|
/* This module assumes the flash is memory mapped just below 4GiB in the
|
||||||
|
* address space for reading. Also this module assumes an area it erased
|
||||||
|
* when all bytes read as all 0xff's. */
|
||||||
|
|
||||||
|
static struct spi_flash *flash;
|
||||||
|
|
||||||
|
static int nvm_init(void)
|
||||||
|
{
|
||||||
|
if (flash != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spi_init();
|
||||||
|
flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
|
||||||
|
if (!flash) {
|
||||||
|
printk(BIOS_DEBUG, "Could not find SPI device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert memory mapped pointer to flash offset. */
|
||||||
|
static inline uint32_t to_flash_offset(void *p)
|
||||||
|
{
|
||||||
|
return CONFIG_ROM_SIZE + (uintptr_t)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nvm_is_erased(const void *start, size_t size)
|
||||||
|
{
|
||||||
|
const char *cur = start;
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
|
if (*cur != 0xff)
|
||||||
|
return 0;
|
||||||
|
cur++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nvm_erase(void *start, size_t size)
|
||||||
|
{
|
||||||
|
if (nvm_init() < 0)
|
||||||
|
return -1;
|
||||||
|
flash->erase(flash, to_flash_offset(start), size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write data to NVM. Returns 0 on success < 0 on error. */
|
||||||
|
int nvm_write(void *start, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
if (nvm_init() < 0)
|
||||||
|
return -1;
|
||||||
|
flash->write(flash, to_flash_offset(start), size, data);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
#include <arch/acpi.h>
|
||||||
|
#include <cpu/cpu.h>
|
||||||
|
#include <device/pci_rom.h>
|
||||||
|
#include <baytrail/acpi.h>
|
||||||
|
|
||||||
|
|
||||||
|
void generate_cpu_entries(void) {}
|
||||||
|
|
||||||
|
void acpi_create_intel_hpet(acpi_hpet_t * hpet) {}
|
||||||
|
|
||||||
|
void acpi_create_serialio_ssdt(acpi_header_t *ssdt) {}
|
||||||
|
|
||||||
|
unsigned long acpi_fill_mcfg(unsigned long current) { return current; }
|
||||||
|
|
||||||
|
void smm_setup_structures(void *gnvs, void *tcg, void *smi1) {}
|
||||||
|
|
||||||
|
void smm_init(void) {}
|
||||||
|
|
||||||
|
/* Rmodules don't like weak symbols. */
|
||||||
|
u32 map_oprom_vendev(u32 vendev) { return vendev; }
|
|
@ -0,0 +1,4 @@
|
||||||
|
cpu_incs += $(src)/soc/intel/baytrail/romstage/cache_as_ram.inc
|
||||||
|
romstage-y += romstage.c
|
||||||
|
romstage-y += raminit.c
|
||||||
|
romstage-$(CONFIG_ENABLE_BUILTIN_COM1) += uart.c
|
|
@ -0,0 +1,280 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
|
||||||
|
* Copyright (C) 2007-2008 coresystems GmbH
|
||||||
|
*
|
||||||
|
* 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/stack.h>
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* Enough room to cache CAR_TILE_SIZE starting at MRC_BIN_ADDRESS */
|
||||||
|
#define CACHE_MRC_BASE (CONFIG_MRC_BIN_ADDRESS)
|
||||||
|
#define CACHE_MRC_MASK (~(CONFIG_CAR_TILE_SIZE - 1))
|
||||||
|
|
||||||
|
#define CPU_PHYSMASK_HI ((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1)
|
||||||
|
|
||||||
|
#define NoEvictMod_MSR 0x2e0
|
||||||
|
#define BBL_CR_CTL3_MSR 0x11e
|
||||||
|
#define MCG_CAP_MSR 0x179
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
/* Configure the default memory type to uncacheable as well as disable
|
||||||
|
* fixed and variable range mtrrs. */
|
||||||
|
movl $MTRRdefType_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $(~0x00000cff), %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x22)
|
||||||
|
/* Zero the variable MTRRs. */
|
||||||
|
movl $MCG_CAP_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
movzx %al, %ebx
|
||||||
|
/* First variable MTRR. */
|
||||||
|
movl $0x200, %ecx
|
||||||
|
xorl %eax, %eax
|
||||||
|
xorl %edx, %edx
|
||||||
|
1:
|
||||||
|
wrmsr
|
||||||
|
inc %ecx
|
||||||
|
dec %ebx
|
||||||
|
jnz 1b
|
||||||
|
|
||||||
|
/* Zero out all fixed range and variable range MTRRs. */
|
||||||
|
movl $fixed_mtrr_table, %esi
|
||||||
|
movl $((fixed_mtrr_table_end - fixed_mtrr_table) / 2), %edi
|
||||||
|
xorl %eax, %eax
|
||||||
|
xorl %edx, %edx
|
||||||
|
1:
|
||||||
|
movw (%esi), %bx
|
||||||
|
movzx %bx, %ecx
|
||||||
|
wrmsr
|
||||||
|
add $2, %esi
|
||||||
|
dec %edi
|
||||||
|
jnz 1b
|
||||||
|
|
||||||
|
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)
|
||||||
|
/* Set Cache-as-RAM base address. */
|
||||||
|
movl $(MTRRphysBase_MSR(1)), %ecx
|
||||||
|
movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
|
||||||
|
xorl %edx, %edx
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
movl $(MTRRphysMask_MSR(1)), %ecx
|
||||||
|
movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
|
||||||
|
movl $CPU_PHYSMASK_HI, %edx
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Enable MTRR. */
|
||||||
|
movl $MTRRdefType_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $MTRRdefTypeEn, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x26)
|
||||||
|
|
||||||
|
/* Enable the L2 cache. */
|
||||||
|
movl $BBL_CR_CTL3_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $0x100, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x27)
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x28)
|
||||||
|
|
||||||
|
/* 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 no evict mode */
|
||||||
|
movl $NoEvictMod_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $2, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x29)
|
||||||
|
|
||||||
|
/* Setup the stack. */
|
||||||
|
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE), %eax
|
||||||
|
movl %eax, %esp
|
||||||
|
|
||||||
|
/* Restore the BIST result. */
|
||||||
|
movl %ebp, %eax
|
||||||
|
movl %esp, %ebp
|
||||||
|
pushl %eax
|
||||||
|
|
||||||
|
before_romstage:
|
||||||
|
post_code(0x2a)
|
||||||
|
/* 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(0x2b)
|
||||||
|
|
||||||
|
/* Disable cache. */
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $CR0_CacheDisable, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
post_code(0x2c)
|
||||||
|
|
||||||
|
/* Disable MTRR. */
|
||||||
|
movl $MTRRdefType_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $(~MTRRdefTypeEn), %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
invd
|
||||||
|
|
||||||
|
post_code(0x2d)
|
||||||
|
|
||||||
|
/* Disable the no eviction run state */
|
||||||
|
movl $NoEvictMod_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $~2, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Disable the no eviction mode */
|
||||||
|
rdmsr
|
||||||
|
andl $~1, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x2e)
|
||||||
|
|
||||||
|
/* 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(0x2f)
|
||||||
|
|
||||||
|
/* And enable cache again after setting MTRRs. */
|
||||||
|
movl %cr0, %eax
|
||||||
|
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
post_code(0x30)
|
||||||
|
|
||||||
|
/* Enable MTRR. */
|
||||||
|
movl $MTRRdefType_MSR, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $MTRRdefTypeEn, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
post_code(0x31)
|
||||||
|
|
||||||
|
__main:
|
||||||
|
post_code(POST_PREPARE_RAMSTAGE)
|
||||||
|
cld /* Clear direction flag. */
|
||||||
|
call romstage_after_car
|
||||||
|
|
||||||
|
.Lhlt:
|
||||||
|
post_code(POST_DEAD_CODE)
|
||||||
|
hlt
|
||||||
|
jmp .Lhlt
|
||||||
|
|
||||||
|
/* Fixed MTRRs */
|
||||||
|
fixed_mtrr_table:
|
||||||
|
.word 0x250, 0x258, 0x259
|
||||||
|
.word 0x268, 0x269, 0x26A
|
||||||
|
.word 0x26B, 0x26C, 0x26D
|
||||||
|
.word 0x26E, 0x26F
|
||||||
|
fixed_mtrr_table_end:
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <arch/io.h>
|
||||||
|
#include <cbfs.h>
|
||||||
|
#include <cbmem.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <device/pci_def.h>
|
||||||
|
#include <baytrail/gpio.h>
|
||||||
|
#include <baytrail/mrc_cache.h>
|
||||||
|
#include <baytrail/iomap.h>
|
||||||
|
#include <baytrail/pci_devs.h>
|
||||||
|
#include <baytrail/romstage.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void enable_smbus(void)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
const uint32_t smbus_dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
|
||||||
|
|
||||||
|
/* SMBus I/O BAR */
|
||||||
|
reg = SMBUS_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(smbus_dev, PCI_BASE_ADDRESS_4, reg);
|
||||||
|
/* Enable decode of I/O space. */
|
||||||
|
reg = pci_read_config16(smbus_dev, PCI_COMMAND);
|
||||||
|
reg |= 0x1;
|
||||||
|
pci_write_config16(smbus_dev, PCI_COMMAND, reg);
|
||||||
|
/* Enable Host Controller */
|
||||||
|
reg = pci_read_config8(smbus_dev, 0x40);
|
||||||
|
reg |= 1;
|
||||||
|
pci_write_config8(smbus_dev, 0x40, reg);
|
||||||
|
|
||||||
|
/* Configure pads to be used for SMBus */
|
||||||
|
score_select_func(PCU_SMB_CLK_PAD, 1);
|
||||||
|
score_select_func(PCU_SMB_DATA_PAD, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void raminit(struct mrc_params *mp, int prev_sleep_state)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mrc_wrapper_entry_t mrc_entry;
|
||||||
|
const struct mrc_saved_data *cache;
|
||||||
|
|
||||||
|
/* Fill in default entries. */
|
||||||
|
mp->version = MRC_PARAMS_VER;
|
||||||
|
mp->console_out = &console_tx_byte;
|
||||||
|
mp->prev_sleep_state = prev_sleep_state;
|
||||||
|
|
||||||
|
if (!mrc_cache_get_current(&cache)) {
|
||||||
|
mp->saved_data_size = cache->size;
|
||||||
|
mp->saved_data = &cache->data[0];
|
||||||
|
} else {
|
||||||
|
printk(BIOS_DEBUG, "No MRC cache found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
mrc_entry = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (mrc_entry == NULL) {
|
||||||
|
printk(BIOS_DEBUG, "Couldn't find mrc.bin\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS)
|
||||||
|
enable_smbus();
|
||||||
|
|
||||||
|
ret = mrc_entry(mp);
|
||||||
|
|
||||||
|
cbmem_initialize_empty();
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "MRC Wrapper returned %d\n", ret);
|
||||||
|
printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", mp->data_to_save,
|
||||||
|
mp->data_to_save_size);
|
||||||
|
|
||||||
|
if (mp->data_to_save != NULL && mp->data_to_save_size > 0)
|
||||||
|
mrc_cache_stash_data(mp->data_to_save, mp->data_to_save_size);
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <arch/cpu.h>
|
||||||
|
#include <arch/io.h>
|
||||||
|
#include <arch/cbfs.h>
|
||||||
|
#include <arch/stages.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <cbmem.h>
|
||||||
|
#include <cpu/x86/mtrr.h>
|
||||||
|
#include <romstage_handoff.h>
|
||||||
|
#include <baytrail/gpio.h>
|
||||||
|
#include <baytrail/iomap.h>
|
||||||
|
#include <baytrail/iosf.h>
|
||||||
|
#include <baytrail/lpc.h>
|
||||||
|
#include <baytrail/pci_devs.h>
|
||||||
|
#include <baytrail/romstage.h>
|
||||||
|
|
||||||
|
/* The cache-as-ram assembly file calls romstage_main() after setting up
|
||||||
|
* cache-as-ram. romstage_main() will then call the mainboards's
|
||||||
|
* mainboard_romstage_entry() function. That function then calls
|
||||||
|
* romstage_common() below. The reason for the back and forth is to provide
|
||||||
|
* common entry point from cache-as-ram while still allowing for code sharing.
|
||||||
|
* Because we can't use global variables the stack is used for allocations --
|
||||||
|
* thus the need to call back and forth. */
|
||||||
|
|
||||||
|
static void *setup_stack_and_mttrs(void);
|
||||||
|
|
||||||
|
static void program_base_addresses(void)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
|
||||||
|
|
||||||
|
/* Memory Mapped IO registers. */
|
||||||
|
reg = PMC_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, PBASE, reg);
|
||||||
|
reg = IO_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, IOBASE, reg);
|
||||||
|
reg = ILB_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, IBASE, reg);
|
||||||
|
reg = SPI_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, SBASE, reg);
|
||||||
|
reg = MPHY_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, MPBASE, reg);
|
||||||
|
reg = RCBA_BASE_ADDRESS | 1;
|
||||||
|
pci_write_config32(lpc_dev, RCBA, reg);
|
||||||
|
|
||||||
|
/* IO Port Registers. */
|
||||||
|
reg = ACPI_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, ABASE, reg);
|
||||||
|
reg = GPIO_BASE_ADDRESS | 2;
|
||||||
|
pci_write_config32(lpc_dev, GBASE, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry from cache-as-ram.inc. */
|
||||||
|
void * asmlinkage romstage_main(unsigned long bist)
|
||||||
|
{
|
||||||
|
/* Call into mainboard. */
|
||||||
|
mainboard_romstage_entry(bist);
|
||||||
|
|
||||||
|
return setup_stack_and_mttrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry from the mainboard. */
|
||||||
|
void romstage_common(const struct romstage_params *params)
|
||||||
|
{
|
||||||
|
struct romstage_handoff *handoff;
|
||||||
|
|
||||||
|
program_base_addresses();
|
||||||
|
|
||||||
|
byt_config_com1_and_enable();
|
||||||
|
|
||||||
|
console_init();
|
||||||
|
|
||||||
|
/* Initialize RAM */
|
||||||
|
raminit(params->mrc_params, 5);
|
||||||
|
|
||||||
|
handoff = romstage_handoff_find_or_add();
|
||||||
|
if (handoff != NULL)
|
||||||
|
handoff->s3_resume = 0;
|
||||||
|
else
|
||||||
|
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_up_spi(void)
|
||||||
|
{
|
||||||
|
const uintptr_t sbase = SPI_BASE_ADDRESS;
|
||||||
|
|
||||||
|
/* Disable generating SMI when setting WPD bit. */
|
||||||
|
write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7));
|
||||||
|
/* Disable the SMM-only BIOS write and set WPD bit. */
|
||||||
|
write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void asmlinkage romstage_after_car(void)
|
||||||
|
{
|
||||||
|
/* Allow BIOS to program SPI part. */
|
||||||
|
open_up_spi();
|
||||||
|
|
||||||
|
/* Load the ramstage. */
|
||||||
|
copy_and_run();
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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. */
|
||||||
|
static 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 MTRR 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: MTRR base 0 31:0
|
||||||
|
* +8: MTRR base 0 63:32
|
||||||
|
* +12: MTRR mask 0 31:0
|
||||||
|
* +16: MTRR mask 0 63:32
|
||||||
|
* +20: MTRR base 1 31:0
|
||||||
|
* +24: MTRR base 1 63:32
|
||||||
|
* +28: MTRR mask 1 31:0
|
||||||
|
* +32: MTRR 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 MTRRs to setup. Return the stack location
|
||||||
|
* pointing to the number of MTRRs. */
|
||||||
|
slot = stack_push(slot, num_mtrrs);
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <baytrail/gpio.h>
|
||||||
|
#include <baytrail/iomap.h>
|
||||||
|
#include <baytrail/lpc.h>
|
||||||
|
#include <baytrail/pci_devs.h>
|
||||||
|
#include <baytrail/romstage.h>
|
||||||
|
|
||||||
|
void byt_config_com1_and_enable(void)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
|
||||||
|
/* Enable the UART hardware for COM1. */
|
||||||
|
reg = 1;
|
||||||
|
pci_write_config32(PCI_DEV(0, LPC_DEV, 0), UART_CONT, reg);
|
||||||
|
|
||||||
|
/* Set up the pads to select the UART function. RXD and TXD are
|
||||||
|
* 0x520 and 0x530, respectively. */
|
||||||
|
write32(IO_BASE_ADDRESS + 0x520, read32(IO_BASE_ADDRESS + 0x520) | 1);
|
||||||
|
write32(IO_BASE_ADDRESS + 0x530, read32(IO_BASE_ADDRESS + 0x530) | 1);
|
||||||
|
}
|
|
@ -0,0 +1,654 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 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; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file is derived from the flashrom project. */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <delay.h>
|
||||||
|
#include <arch/io.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <device/pci_ids.h>
|
||||||
|
#include <spi_flash.h>
|
||||||
|
|
||||||
|
#include <baytrail/lpc.h>
|
||||||
|
#include <baytrail/pci_devs.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((unsigned long)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((unsigned long)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((unsigned long)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((unsigned long)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((unsigned long)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((unsigned long)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((uint32_t)a)
|
||||||
|
#define readw_(a) read16((uint32_t)a)
|
||||||
|
#define readl_(a) read32((uint32_t)a)
|
||||||
|
#define writeb_(val, addr) write8((uint32_t)addr, val)
|
||||||
|
#define writew_(val, addr) write16((uint32_t)addr, val)
|
||||||
|
#define writel_(val, addr) write32((uint32_t)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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
|
||||||
|
unsigned int max_hz, unsigned int mode)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ich9_spi_regs *spi_regs(void)
|
||||||
|
{
|
||||||
|
device_t dev;
|
||||||
|
uint32_t sbase;
|
||||||
|
|
||||||
|
#ifdef __SMM__
|
||||||
|
dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
|
||||||
|
#else
|
||||||
|
dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
|
||||||
|
#endif
|
||||||
|
pci_read_config_dword(dev, SBASE, &sbase);
|
||||||
|
sbase &= ~0x1ff;
|
||||||
|
|
||||||
|
return (void *)sbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_init(void)
|
||||||
|
{
|
||||||
|
ich9_spi_regs *ich9_spi = spi_regs();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_cs_activate(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
/* Handled by ICH automatically. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_cs_deactivate(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_xfer(struct spi_slave *slave, const void *dout,
|
||||||
|
unsigned int bitsout, void *din, unsigned int bitsin)
|
||||||
|
{
|
||||||
|
uint16_t control;
|
||||||
|
int16_t opcode_index;
|
||||||
|
int with_address;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
spi_transaction trans = {
|
||||||
|
dout, bitsout / 8,
|
||||||
|
din, bitsin / 8,
|
||||||
|
0xff, 0xff, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* There has to always at least be an opcode. */
|
||||||
|
if (!bitsout || !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 (bitsin != 0 && !din) {
|
||||||
|
printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Right now we don't support writing partial bytes. */
|
||||||
|
if (bitsout % 8 || bitsin % 8) {
|
||||||
|
printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\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
|
||||||
|
* bitesout 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 atempting to transfer more bytes
|
||||||
|
* than the controller can handle. Iterations for writes are not
|
||||||
|
* supported here because each SPI write command needs to be preceded
|
||||||
|
* and followed by other SPI commands, and this sequence is controlled
|
||||||
|
* by the SPI chip driver.
|
||||||
|
*/
|
||||||
|
if (trans.bytesout > 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 */
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 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 <cpu/x86/msr.h>
|
||||||
|
#include <cpu/x86/tsc.h>
|
||||||
|
#include <baytrail/msr.h>
|
||||||
|
|
||||||
|
#define BCLK 100 /* 100 MHz */
|
||||||
|
unsigned long tsc_freq_mhz(void)
|
||||||
|
{
|
||||||
|
msr_t platform_info;
|
||||||
|
|
||||||
|
platform_info = rdmsr(MSR_PLATFORM_INFO);
|
||||||
|
return BCLK * ((platform_info.lo >> 8) & 0xff);
|
||||||
|
}
|
Loading…
Reference in New Issue