Braswell: Use Baytrail as Comparison Base
Add baytrail source for comparison with Braswell. BRANCH=none BUG=None TEST=None Change-Id: I5170addf41676d95a3daf070a32bcee085f8156d Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com> Reviewed-on: http://review.coreboot.org/10117 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
b5ad827ee5
commit
77ff0b1a01
245
src/soc/intel/braswell/Kconfig
Normal file
245
src/soc/intel/braswell/Kconfig
Normal file
@ -0,0 +1,245 @@
|
||||
config SOC_INTEL_BRASWELL
|
||||
bool
|
||||
help
|
||||
Bay Trail M/D part support.
|
||||
|
||||
if SOC_INTEL_BRASWELL
|
||||
|
||||
config CPU_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select ARCH_BOOTBLOCK_X86_32
|
||||
select ARCH_VERSTAGE_X86_32
|
||||
select ARCH_ROMSTAGE_X86_32
|
||||
select ARCH_RAMSTAGE_X86_32
|
||||
select BACKUP_DEFAULT_SMM_REGION
|
||||
select CACHE_MRC_SETTINGS
|
||||
select CAR_MIGRATION
|
||||
select COLLECT_TIMESTAMPS
|
||||
select CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
|
||||
select SUPPORT_CPU_UCODE_IN_CBFS
|
||||
select HAVE_SMI_HANDLER
|
||||
select HAVE_HARD_RESET
|
||||
select MMCONF_SUPPORT
|
||||
select MMCONF_SUPPORT_DEFAULT
|
||||
select RELOCATABLE_MODULES
|
||||
select RELOCATABLE_RAMSTAGE
|
||||
select PARALLEL_MP
|
||||
select PCIEXP_ASPM
|
||||
select PCIEXP_COMMON_CLOCK
|
||||
select REG_SCRIPT
|
||||
select SMM_MODULES
|
||||
select SMM_TSEG
|
||||
select SMP
|
||||
select SPI_FLASH
|
||||
select SSE2
|
||||
select SUPPORT_CPU_UCODE_IN_CBFS
|
||||
select TSC_CONSTANT_RATE
|
||||
select TSC_MONOTONIC_TIMER
|
||||
select TSC_SYNC_MFENCE
|
||||
select UDELAY_TSC
|
||||
select SOC_INTEL_COMMON
|
||||
|
||||
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 MRC_RMT
|
||||
bool "Enable MRC RMT training + debug prints"
|
||||
default n
|
||||
|
||||
endif # HAVE_MRC
|
||||
|
||||
# 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 0xfe000000
|
||||
|
||||
config DCACHE_RAM_SIZE
|
||||
hex
|
||||
default 0x8000
|
||||
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 0x8000
|
||||
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"
|
||||
|
||||
config HAVE_REFCODE_BLOB
|
||||
depends on ARCH_X86
|
||||
bool "An external reference code blob should be put into cbfs."
|
||||
default n
|
||||
help
|
||||
The reference code blob will be placed into cbfs.
|
||||
|
||||
if HAVE_REFCODE_BLOB
|
||||
|
||||
config REFCODE_BLOB_FILE
|
||||
string "Path and filename to reference code blob."
|
||||
default "refcode.elf"
|
||||
help
|
||||
The path and filename to the file to be added to cbfs.
|
||||
|
||||
endif # HAVE_REFCODE_BLOB
|
||||
|
||||
endif
|
107
src/soc/intel/braswell/Makefile.inc
Normal file
107
src/soc/intel/braswell/Makefile.inc
Normal file
@ -0,0 +1,107 @@
|
||||
ifeq ($(CONFIG_SOC_INTEL_BRASWELL),y)
|
||||
|
||||
subdirs-y += bootblock
|
||||
subdirs-y += microcode
|
||||
subdirs-y += romstage
|
||||
subdirs-y += ../../../cpu/x86/lapic
|
||||
subdirs-y += ../../../cpu/x86/mtrr
|
||||
subdirs-y += ../../../cpu/x86/smm
|
||||
subdirs-y += ../../../cpu/x86/tsc
|
||||
subdirs-y += ../../../cpu/intel/microcode
|
||||
subdirs-y += ../../../cpu/intel/turbo
|
||||
|
||||
ramstage-y += memmap.c
|
||||
romstage-y += memmap.c
|
||||
ramstage-y += tsc_freq.c
|
||||
romstage-y += tsc_freq.c
|
||||
smm-y += tsc_freq.c
|
||||
ramstage-y += spi.c
|
||||
smm-y += spi.c
|
||||
ramstage-y += chip.c
|
||||
ramstage-y += gfx.c
|
||||
ramstage-y += iosf.c
|
||||
romstage-y += iosf.c
|
||||
smm-y += iosf.c
|
||||
ramstage-y += northcluster.c
|
||||
ramstage-y += ramstage.c
|
||||
ramstage-y += gpio.c
|
||||
romstage-y += reset.c
|
||||
ramstage-y += reset.c
|
||||
ramstage-y += cpu.c
|
||||
ramstage-y += pmutil.c
|
||||
smm-y += pmutil.c
|
||||
smm-y += smihandler.c
|
||||
ramstage-y += smm.c
|
||||
ramstage-y += ehci.c
|
||||
ramstage-y += xhci.c
|
||||
ramstage-y += southcluster.c
|
||||
ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c
|
||||
ramstage-y += sata.c
|
||||
ramstage-y += acpi.c
|
||||
ramstage-y += lpe.c
|
||||
ramstage-y += scc.c
|
||||
ramstage-y += emmc.c
|
||||
ramstage-y += lpss.c
|
||||
ramstage-y += pcie.c
|
||||
ramstage-y += sd.c
|
||||
ramstage-y += dptf.c
|
||||
ramstage-y += perf_power.c
|
||||
ramstage-y += stage_cache.c
|
||||
romstage-y += stage_cache.c
|
||||
ramstage-$(CONFIG_ELOG) += elog.c
|
||||
ramstage-y += hda.c
|
||||
|
||||
# Remove as ramstage gets fleshed out
|
||||
ramstage-y += placeholders.c
|
||||
|
||||
CPPFLAGS_common += -Isrc/soc/intel/baytrail/include
|
||||
|
||||
# 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
|
||||
|
||||
# If an MRC file is an ELF file determine the entry address and first loadable
|
||||
# section offset in the file. Subtract the offset from the entry address to
|
||||
# determine the final location.
|
||||
mrcelfoffset = $(shell $(READELF_x86_32) -S -W $(CONFIG_MRC_FILE) | sed -e 's/\[ /[0/' | awk '$$3 ~ /PROGBITS/ { print "0x"$$5; exit }' )
|
||||
mrcelfentry = $(shell $(READELF_x86_32) -h -W $(CONFIG_MRC_FILE) | grep 'Entry point address' | awk '{print $$NF }')
|
||||
|
||||
# Add memory reference code blob.
|
||||
cbfs-files-$(CONFIG_HAVE_MRC) += mrc.bin
|
||||
mrc.bin-file := $(call strip_quotes,$(CONFIG_MRC_FILE))
|
||||
mrc.bin-position := $(if $(findstring elf,$(CONFIG_MRC_FILE)),$(shell printf "0x%x" $$(( $(mrcelfentry) - $(mrcelfoffset) )) ),$(CONFIG_MRC_BIN_ADDRESS))
|
||||
mrc.bin-type := mrc
|
||||
|
||||
PHONY += baytrail_add_me
|
||||
|
||||
endif
|
511
src/soc/intel/braswell/acpi.c
Normal file
511
src/soc/intel/braswell/acpi.c
Normal file
@ -0,0 +1,511 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* 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/acpi.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <arch/io.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <console/console.h>
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/tsc.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
|
||||
#include <soc/acpi.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/msr.h>
|
||||
#include <soc/pattrs.h>
|
||||
#include <soc/pmc.h>
|
||||
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#include <vendorcode/google/chromeos/gnvs.h>
|
||||
|
||||
#define MWAIT_RES(state, sub_state) \
|
||||
{ \
|
||||
.addrl = (((state) << 4) | (sub_state)), \
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED, \
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
|
||||
.access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
|
||||
}
|
||||
|
||||
/* C-state map without S0ix */
|
||||
static acpi_cstate_t cstate_map[] = {
|
||||
{
|
||||
/* C1 */
|
||||
.ctype = 1, /* ACPI C1 */
|
||||
.latency = 1,
|
||||
.power = 1000,
|
||||
.resource = MWAIT_RES(0, 0),
|
||||
},
|
||||
{
|
||||
/* C6NS with no L2 shrink */
|
||||
/* NOTE: this substate is above CPUID limit */
|
||||
.ctype = 2, /* ACPI C2 */
|
||||
.latency = 500,
|
||||
.power = 10,
|
||||
.resource = MWAIT_RES(5, 1),
|
||||
},
|
||||
{
|
||||
/* C6FS with full L2 shrink */
|
||||
.ctype = 3, /* ACPI C3 */
|
||||
.latency = 1500, /* 1.5ms worst case */
|
||||
.power = 1,
|
||||
.resource = MWAIT_RES(5, 2),
|
||||
}
|
||||
};
|
||||
|
||||
void acpi_init_gnvs(global_nvs_t *gnvs)
|
||||
{
|
||||
/* Set unknown wake source */
|
||||
gnvs->pm1i = -1;
|
||||
|
||||
/* CPU core count */
|
||||
gnvs->pcnt = dev_count_cpu();
|
||||
|
||||
/* Top of Low Memory (start of resource allocation) */
|
||||
gnvs->tolm = nc_read_top_of_low_memory();
|
||||
|
||||
#if CONFIG_CONSOLE_CBMEM
|
||||
/* Update the mem console pointer. */
|
||||
gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE);
|
||||
#endif
|
||||
|
||||
#if CONFIG_CHROMEOS
|
||||
/* Initialize Verified Boot data */
|
||||
chromeos_init_vboot(&(gnvs->chromeos));
|
||||
#if CONFIG_EC_GOOGLE_CHROMEEC
|
||||
gnvs->chromeos.vbt2 = google_ec_running_ro() ?
|
||||
ACTIVE_ECFW_RO : ACTIVE_ECFW_RW;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static int acpi_sci_irq(void)
|
||||
{
|
||||
u32 *actl = (u32 *)(ILB_BASE_ADDRESS + ACTL);
|
||||
int scis;
|
||||
static int sci_irq;
|
||||
|
||||
if (sci_irq)
|
||||
return sci_irq;
|
||||
|
||||
/* Determine how SCI is routed. */
|
||||
scis = read32(actl) & SCIS_MASK;
|
||||
switch (scis) {
|
||||
case SCIS_IRQ9:
|
||||
case SCIS_IRQ10:
|
||||
case SCIS_IRQ11:
|
||||
sci_irq = scis - SCIS_IRQ9 + 9;
|
||||
break;
|
||||
case SCIS_IRQ20:
|
||||
case SCIS_IRQ21:
|
||||
case SCIS_IRQ22:
|
||||
case SCIS_IRQ23:
|
||||
sci_irq = scis - SCIS_IRQ20 + 20;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_DEBUG, "Invalid SCI route! Defaulting to IRQ9.\n");
|
||||
sci_irq = 9;
|
||||
break;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "SCI is IRQ%d\n", sci_irq);
|
||||
return sci_irq;
|
||||
}
|
||||
|
||||
void acpi_create_intel_hpet(acpi_hpet_t * hpet)
|
||||
{
|
||||
acpi_header_t *header = &(hpet->header);
|
||||
acpi_addr_t *addr = &(hpet->addr);
|
||||
|
||||
memset((void *) hpet, 0, sizeof(acpi_hpet_t));
|
||||
|
||||
/* fill out header fields */
|
||||
memcpy(header->signature, "HPET", 4);
|
||||
memcpy(header->oem_id, OEM_ID, 6);
|
||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
||||
|
||||
header->length = sizeof(acpi_hpet_t);
|
||||
header->revision = 1;
|
||||
|
||||
/* fill out HPET address */
|
||||
addr->space_id = 0; /* Memory */
|
||||
addr->bit_width = 64;
|
||||
addr->bit_offset = 0;
|
||||
addr->addrl = (unsigned long long)HPET_BASE_ADDRESS & 0xffffffff;
|
||||
addr->addrh = (unsigned long long)HPET_BASE_ADDRESS >> 32;
|
||||
|
||||
hpet->id = 0x8086a201; /* Intel */
|
||||
hpet->number = 0x00;
|
||||
hpet->min_tick = 0x0080;
|
||||
|
||||
header->checksum =
|
||||
acpi_checksum((void *) hpet, sizeof(acpi_hpet_t));
|
||||
}
|
||||
|
||||
unsigned long acpi_fill_mcfg(unsigned long current)
|
||||
{
|
||||
current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
|
||||
MCFG_BASE_ADDRESS, 0, 0, 255);
|
||||
return current;
|
||||
}
|
||||
|
||||
void acpi_fill_in_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
const uint16_t pmbase = ACPI_BASE_ADDRESS;
|
||||
|
||||
fadt->sci_int = acpi_sci_irq();
|
||||
fadt->smi_cmd = APM_CNT;
|
||||
fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
|
||||
fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
|
||||
fadt->s4bios_req = 0x0;
|
||||
fadt->pstate_cnt = 0;
|
||||
|
||||
fadt->pm1a_evt_blk = pmbase + PM1_STS;
|
||||
fadt->pm1b_evt_blk = 0x0;
|
||||
fadt->pm1a_cnt_blk = pmbase + PM1_CNT;
|
||||
fadt->pm1b_cnt_blk = 0x0;
|
||||
fadt->pm2_cnt_blk = pmbase + PM2A_CNT_BLK;
|
||||
fadt->pm_tmr_blk = pmbase + PM1_TMR;
|
||||
fadt->gpe0_blk = pmbase + GPE0_STS;
|
||||
fadt->gpe1_blk = 0;
|
||||
|
||||
fadt->pm1_evt_len = 4;
|
||||
fadt->pm1_cnt_len = 2;
|
||||
fadt->pm2_cnt_len = 1;
|
||||
fadt->pm_tmr_len = 4;
|
||||
fadt->gpe0_blk_len = 2 * (GPE0_EN - GPE0_STS);
|
||||
fadt->gpe1_blk_len = 0;
|
||||
fadt->gpe1_base = 0;
|
||||
fadt->cst_cnt = 0;
|
||||
fadt->p_lvl2_lat = 1;
|
||||
fadt->p_lvl3_lat = 87;
|
||||
fadt->flush_size = 1024;
|
||||
fadt->flush_stride = 16;
|
||||
fadt->duty_offset = 1;
|
||||
fadt->duty_width = 0;
|
||||
fadt->day_alrm = 0xd;
|
||||
fadt->mon_alrm = 0x00;
|
||||
fadt->century = 0x00;
|
||||
fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
|
||||
|
||||
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
|
||||
ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON |
|
||||
ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE |
|
||||
ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK;
|
||||
|
||||
fadt->reset_reg.space_id = 1;
|
||||
fadt->reset_reg.bit_width = 8;
|
||||
fadt->reset_reg.bit_offset = 0;
|
||||
fadt->reset_reg.resv = 0;
|
||||
fadt->reset_reg.addrl = 0xcf9;
|
||||
fadt->reset_reg.addrh = 0;
|
||||
fadt->reset_value = 6;
|
||||
|
||||
fadt->x_pm1a_evt_blk.space_id = 1;
|
||||
fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
|
||||
fadt->x_pm1a_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_evt_blk.resv = 0;
|
||||
fadt->x_pm1a_evt_blk.addrl = pmbase + PM1_STS;
|
||||
fadt->x_pm1a_evt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1b_evt_blk.space_id = 1;
|
||||
fadt->x_pm1b_evt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_evt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_evt_blk.resv = 0;
|
||||
fadt->x_pm1b_evt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_evt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1a_cnt_blk.space_id = 1;
|
||||
fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
|
||||
fadt->x_pm1a_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1a_cnt_blk.resv = 0;
|
||||
fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT;
|
||||
fadt->x_pm1a_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm1b_cnt_blk.space_id = 1;
|
||||
fadt->x_pm1b_cnt_blk.bit_width = 0;
|
||||
fadt->x_pm1b_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm1b_cnt_blk.resv = 0;
|
||||
fadt->x_pm1b_cnt_blk.addrl = 0x0;
|
||||
fadt->x_pm1b_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm2_cnt_blk.space_id = 1;
|
||||
fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
|
||||
fadt->x_pm2_cnt_blk.bit_offset = 0;
|
||||
fadt->x_pm2_cnt_blk.resv = 0;
|
||||
fadt->x_pm2_cnt_blk.addrl = pmbase + PM2A_CNT_BLK;
|
||||
fadt->x_pm2_cnt_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_pm_tmr_blk.space_id = 1;
|
||||
fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
|
||||
fadt->x_pm_tmr_blk.bit_offset = 0;
|
||||
fadt->x_pm_tmr_blk.resv = 0;
|
||||
fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR;
|
||||
fadt->x_pm_tmr_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_gpe0_blk.space_id = 1;
|
||||
fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
|
||||
fadt->x_gpe0_blk.bit_offset = 0;
|
||||
fadt->x_gpe0_blk.resv = 0;
|
||||
fadt->x_gpe0_blk.addrl = pmbase + GPE0_STS;
|
||||
fadt->x_gpe0_blk.addrh = 0x0;
|
||||
|
||||
fadt->x_gpe1_blk.space_id = 1;
|
||||
fadt->x_gpe1_blk.bit_width = 0;
|
||||
fadt->x_gpe1_blk.bit_offset = 0;
|
||||
fadt->x_gpe1_blk.resv = 0;
|
||||
fadt->x_gpe1_blk.addrl = 0x0;
|
||||
fadt->x_gpe1_blk.addrh = 0x0;
|
||||
}
|
||||
|
||||
static acpi_tstate_t baytrail_tss_table[] = {
|
||||
{ 100, 1000, 0, 0x00, 0 },
|
||||
{ 88, 875, 0, 0x1e, 0 },
|
||||
{ 75, 750, 0, 0x1c, 0 },
|
||||
{ 63, 625, 0, 0x1a, 0 },
|
||||
{ 50, 500, 0, 0x18, 0 },
|
||||
{ 38, 375, 0, 0x16, 0 },
|
||||
{ 25, 250, 0, 0x14, 0 },
|
||||
{ 13, 125, 0, 0x12, 0 },
|
||||
};
|
||||
|
||||
static int generate_T_state_entries(int core, int cores_per_package)
|
||||
{
|
||||
int len;
|
||||
|
||||
/* Indicate SW_ALL coordination for T-states */
|
||||
len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
|
||||
|
||||
/* Indicate FFixedHW so OS will use MSR */
|
||||
len += acpigen_write_empty_PTC();
|
||||
|
||||
/* Set NVS controlled T-state limit */
|
||||
len += acpigen_write_TPC("\\TLVL");
|
||||
|
||||
/* Write TSS table for MSR access */
|
||||
len += acpigen_write_TSS_package(
|
||||
ARRAY_SIZE(baytrail_tss_table), baytrail_tss_table);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int calculate_power(int tdp, int p1_ratio, int ratio)
|
||||
{
|
||||
u32 m;
|
||||
u32 power;
|
||||
|
||||
/*
|
||||
* M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
|
||||
*
|
||||
* Power = (ratio / p1_ratio) * m * tdp
|
||||
*/
|
||||
|
||||
m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
|
||||
m = (m * m) / 1000;
|
||||
|
||||
power = ((ratio * 100000 / p1_ratio) / 100);
|
||||
power *= (m / 100) * (tdp / 1000);
|
||||
power /= 1000;
|
||||
|
||||
return (int)power;
|
||||
}
|
||||
|
||||
static int generate_P_state_entries(int core, int cores_per_package)
|
||||
{
|
||||
int len, len_pss;
|
||||
int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2;
|
||||
int coord_type, power_max, power_unit, num_entries;
|
||||
int ratio, power, clock, clock_max;
|
||||
int vid, vid_turbo, vid_min, vid_max, vid_range_2;
|
||||
u32 control_status;
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
msr_t msr;
|
||||
|
||||
/* Inputs from CPU attributes */
|
||||
ratio_max = pattrs->iacore_ratios[IACORE_MAX];
|
||||
ratio_min = pattrs->iacore_ratios[IACORE_LFM];
|
||||
vid_max = pattrs->iacore_vids[IACORE_MAX];
|
||||
vid_min = pattrs->iacore_vids[IACORE_LFM];
|
||||
|
||||
/* Set P-states coordination type based on MSR disable bit */
|
||||
coord_type = (pattrs->num_cpus > 2) ? SW_ALL : HW_ALL;
|
||||
|
||||
/* Max Non-Turbo Frequency */
|
||||
clock_max = (ratio_max * pattrs->bclk_khz) / 1000;
|
||||
|
||||
/* Calculate CPU TDP in mW */
|
||||
msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
|
||||
power_unit = 1 << (msr.lo & 0xf);
|
||||
msr = rdmsr(MSR_PKG_POWER_LIMIT);
|
||||
power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;
|
||||
|
||||
/* Write _PCT indicating use of FFixedHW */
|
||||
len = acpigen_write_empty_PCT();
|
||||
|
||||
/* Write _PPC with NVS specified limit on supported P-state */
|
||||
len += acpigen_write_PPC_NVS();
|
||||
|
||||
/* Write PSD indicating configured coordination type */
|
||||
len += acpigen_write_PSD_package(core, 1, coord_type);
|
||||
|
||||
/* Add P-state entries in _PSS table */
|
||||
len += acpigen_write_name("_PSS");
|
||||
|
||||
/* Determine ratio points */
|
||||
ratio_step = 1;
|
||||
num_entries = (ratio_max - ratio_min) / ratio_step;
|
||||
while (num_entries > 15) { /* ACPI max is 15 ratios */
|
||||
ratio_step <<= 1;
|
||||
num_entries >>= 1;
|
||||
}
|
||||
|
||||
/* P[T] is Turbo state if enabled */
|
||||
if (get_turbo_state() == TURBO_ENABLED) {
|
||||
/* _PSS package count including Turbo */
|
||||
len_pss = acpigen_write_package(num_entries + 2);
|
||||
|
||||
ratio_turbo = pattrs->iacore_ratios[IACORE_TURBO];
|
||||
vid_turbo = pattrs->iacore_vids[IACORE_TURBO];
|
||||
control_status = (ratio_turbo << 8) | vid_turbo;
|
||||
|
||||
/* Add entry for Turbo ratio */
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock_max + 1, /*MHz*/
|
||||
power_max, /*mW*/
|
||||
10, /*lat1*/
|
||||
10, /*lat2*/
|
||||
control_status, /*control*/
|
||||
control_status); /*status*/
|
||||
} else {
|
||||
/* _PSS package count without Turbo */
|
||||
len_pss = acpigen_write_package(num_entries + 1);
|
||||
ratio_turbo = ratio_max;
|
||||
vid_turbo = vid_max;
|
||||
}
|
||||
|
||||
/* First regular entry is max non-turbo ratio */
|
||||
control_status = (ratio_max << 8) | vid_max;
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock_max, /*MHz*/
|
||||
power_max, /*mW*/
|
||||
10, /*lat1*/
|
||||
10, /*lat2*/
|
||||
control_status, /*control */
|
||||
control_status); /*status*/
|
||||
|
||||
/* Set up ratio and vid ranges for VID calculation */
|
||||
ratio_range_2 = (ratio_turbo - ratio_min) * 2;
|
||||
vid_range_2 = (vid_turbo - vid_min) * 2;
|
||||
|
||||
/* Generate the remaining entries */
|
||||
for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
|
||||
ratio >= ratio_min; ratio -= ratio_step) {
|
||||
|
||||
/* Calculate VID for this ratio */
|
||||
vid = ((ratio - ratio_min) * vid_range_2) /
|
||||
ratio_range_2 + vid_min;
|
||||
/* Round up if remainder */
|
||||
if (((ratio - ratio_min) * vid_range_2) % ratio_range_2)
|
||||
vid++;
|
||||
|
||||
/* Calculate power at this ratio */
|
||||
power = calculate_power(power_max, ratio_max, ratio);
|
||||
clock = (ratio * pattrs->bclk_khz) / 1000;
|
||||
control_status = (ratio << 8) | (vid & 0xff);
|
||||
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock, /*MHz*/
|
||||
power, /*mW*/
|
||||
10, /*lat1*/
|
||||
10, /*lat2*/
|
||||
control_status, /*control*/
|
||||
control_status); /*status*/
|
||||
}
|
||||
|
||||
/* Fix package length */
|
||||
len_pss--;
|
||||
acpigen_patch_len(len_pss);
|
||||
|
||||
return len + len_pss;
|
||||
}
|
||||
|
||||
void generate_cpu_entries(void)
|
||||
{
|
||||
int len_pr, core;
|
||||
int pcontrol_blk = get_pmbase(), plen = 6;
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
|
||||
for (core=0; core<pattrs->num_cpus; core++) {
|
||||
if (core > 0) {
|
||||
pcontrol_blk = 0;
|
||||
plen = 0;
|
||||
}
|
||||
|
||||
/* Generate processor \_PR.CPUx */
|
||||
len_pr = acpigen_write_processor(
|
||||
core, pcontrol_blk, plen);
|
||||
|
||||
/* Generate P-state tables */
|
||||
len_pr += generate_P_state_entries(
|
||||
core, pattrs->num_cpus);
|
||||
|
||||
/* Generate C-state tables */
|
||||
len_pr += acpigen_write_CST_package(
|
||||
cstate_map, ARRAY_SIZE(cstate_map));
|
||||
|
||||
/* Generate T-state tables */
|
||||
len_pr += generate_T_state_entries(
|
||||
core, pattrs->num_cpus);
|
||||
|
||||
len_pr--;
|
||||
acpigen_patch_len(len_pr);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long acpi_madt_irq_overrides(unsigned long current)
|
||||
{
|
||||
int sci_irq = acpi_sci_irq();
|
||||
acpi_madt_irqoverride_t *irqovr;
|
||||
uint16_t sci_flags = MP_IRQ_TRIGGER_LEVEL;
|
||||
|
||||
/* INT_SRC_OVR */
|
||||
irqovr = (void *)current;
|
||||
current += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0);
|
||||
|
||||
if (sci_irq >= 20)
|
||||
sci_flags |= MP_IRQ_POLARITY_LOW;
|
||||
else
|
||||
sci_flags |= MP_IRQ_POLARITY_HIGH;
|
||||
|
||||
irqovr = (void *)current;
|
||||
current += acpi_create_madt_irqoverride(irqovr, 0, sci_irq, sci_irq,
|
||||
sci_flags);
|
||||
|
||||
return current;
|
||||
}
|
77
src/soc/intel/braswell/acpi/cpu.asl
Normal file
77
src/soc/intel/braswell/acpi/cpu.asl
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* These devices are created at runtime */
|
||||
External (\_PR.CP00, DeviceObj)
|
||||
External (\_PR.CP01, DeviceObj)
|
||||
External (\_PR.CP02, DeviceObj)
|
||||
External (\_PR.CP03, DeviceObj)
|
||||
|
||||
/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
|
||||
Method (PNOT)
|
||||
{
|
||||
If (LGreaterEqual (\PCNT, 2)) {
|
||||
Notify (\_PR.CP00, 0x81) // _CST
|
||||
Notify (\_PR.CP01, 0x81) // _CST
|
||||
}
|
||||
If (LGreaterEqual (\PCNT, 4)) {
|
||||
Notify (\_PR.CP02, 0x81) // _CST
|
||||
Notify (\_PR.CP03, 0x81) // _CST
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
|
||||
Method (PPCN)
|
||||
{
|
||||
If (LGreaterEqual (\PCNT, 2)) {
|
||||
Notify (\_PR.CP00, 0x80) // _PPC
|
||||
Notify (\_PR.CP01, 0x80) // _PPC
|
||||
}
|
||||
If (LGreaterEqual (\PCNT, 4)) {
|
||||
Notify (\_PR.CP02, 0x80) // _PPC
|
||||
Notify (\_PR.CP03, 0x80) // _PPC
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
|
||||
Method (TNOT)
|
||||
{
|
||||
If (LGreaterEqual (\PCNT, 2)) {
|
||||
Notify (\_PR.CP00, 0x82) // _TPC
|
||||
Notify (\_PR.CP01, 0x82) // _TPC
|
||||
}
|
||||
If (LGreaterEqual (\PCNT, 4)) {
|
||||
Notify (\_PR.CP02, 0x82) // _TPC
|
||||
Notify (\_PR.CP03, 0x82) // _TPC
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a package containing enabled processor entries */
|
||||
Method (PPKG)
|
||||
{
|
||||
If (LGreaterEqual (\PCNT, 4)) {
|
||||
Return (Package() {\_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03})
|
||||
} ElseIf (LGreaterEqual (\PCNT, 2)) {
|
||||
Return (Package() {\_PR.CP00, \_PR.CP01})
|
||||
} Else {
|
||||
Return (Package() {\_PR.CP00})
|
||||
}
|
||||
}
|
87
src/soc/intel/braswell/acpi/device_nvs.asl
Normal file
87
src/soc/intel/braswell/acpi/device_nvs.asl
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Device Enabled in ACPI Mode */
|
||||
|
||||
S0EN, 8, // SDMA Enable
|
||||
S1EN, 8, // I2C1 Enable
|
||||
S2EN, 8, // I2C2 Enable
|
||||
S3EN, 8, // I2C3 Enable
|
||||
S4EN, 8, // I2C4 Enable
|
||||
S5EN, 8, // I2C5 Enable
|
||||
S6EN, 8, // I2C6 Enable
|
||||
S7EN, 8, // I2C7 Enable
|
||||
S8EN, 8, // SDMA2 Enable
|
||||
S9EN, 8, // SPI Enable
|
||||
SAEN, 8, // PWM1 Enable
|
||||
SBEN, 8, // PWM2 Enable
|
||||
SCEN, 8, // UART2 Enable
|
||||
SDEN, 8, // UART2 Enable
|
||||
C0EN, 8, // MMC Enable
|
||||
C1EN, 8, // SDIO Enable
|
||||
C2EN, 8, // SD Card Enable
|
||||
LPEN, 8, // LPE Enable
|
||||
|
||||
/* BAR 0 */
|
||||
|
||||
S0B0, 32, // SDMA BAR0
|
||||
S1B0, 32, // I2C1 BAR0
|
||||
S2B0, 32, // I2C2 BAR0
|
||||
S3B0, 32, // I2C3 BAR0
|
||||
S4B0, 32, // I2C4 BAR0
|
||||
S5B0, 32, // I2C5 BAR0
|
||||
S6B0, 32, // I2C6 BAR0
|
||||
S7B0, 32, // I2C7 BAR0
|
||||
S8B0, 32, // SDMA2 BAR0
|
||||
S9B0, 32, // SPI BAR0
|
||||
SAB0, 32, // PWM1 BAR0
|
||||
SBB0, 32, // PWM2 BAR0
|
||||
SCB0, 32, // UART1 BAR0
|
||||
SDB0, 32, // UART2 BAR0
|
||||
C0B0, 32, // MMC BAR0
|
||||
C1B0, 32, // SDIO BAR0
|
||||
C2B0, 32, // SD Card BAR0
|
||||
LPB0, 32, // LPE BAR0
|
||||
|
||||
/* BAR 1 */
|
||||
|
||||
S0B1, 32, // SDMA BAR1
|
||||
S1B1, 32, // I2C1 BAR1
|
||||
S2B1, 32, // I2C2 BAR1
|
||||
S3B1, 32, // I2C3 BAR1
|
||||
S4B1, 32, // I2C4 BAR1
|
||||
S5B1, 32, // I2C5 BAR1
|
||||
S6B1, 32, // I2C6 BAR1
|
||||
S7B1, 32, // I2C7 BAR1
|
||||
S8B1, 32, // SDMA2 BAR1
|
||||
S9B1, 32, // SPI BAR1
|
||||
SAB1, 32, // PWM1 BAR1
|
||||
SBB1, 32, // PWM2 BAR1
|
||||
SCB1, 32, // UART1 BAR1
|
||||
SDB1, 32, // UART2 BAR1
|
||||
C0B1, 32, // MMC BAR1
|
||||
C1B1, 32, // SDIO BAR1
|
||||
C2B1, 32, // SD Card BAR1
|
||||
LPB1, 32, // LPE BAR1
|
||||
|
||||
/* Extra */
|
||||
|
||||
LPFW, 32, // LPE BAR2 Firmware
|
59
src/soc/intel/braswell/acpi/dptf/charger.asl
Normal file
59
src/soc/intel/braswell/acpi/dptf/charger.asl
Normal file
@ -0,0 +1,59 @@
|
||||
Device (TCHG)
|
||||
{
|
||||
Name (_HID, "INT3403")
|
||||
Name (_UID, 0)
|
||||
Name (PTYP, 0x0B)
|
||||
Name (_STR, Unicode("Battery Charger"))
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return charger performance states defined by mainboard */
|
||||
Method (PPSS)
|
||||
{
|
||||
Return (\_SB.CHPS)
|
||||
}
|
||||
|
||||
/* Return maximum charger current limit */
|
||||
Method (PPPC)
|
||||
{
|
||||
/* Convert size of PPSS table to index */
|
||||
Store (SizeOf (\_SB.CHPS), Local0)
|
||||
Decrement (Local0)
|
||||
|
||||
/* Check if charging is disabled (AC removed) */
|
||||
If (LEqual (\PWRS, Zero)) {
|
||||
/* Return last power state */
|
||||
Return (Local0)
|
||||
} Else {
|
||||
/* Return highest power state */
|
||||
Return (0)
|
||||
}
|
||||
|
||||
Return (0)
|
||||
}
|
||||
|
||||
/* Set charger current limit */
|
||||
Method (SPPC, 1)
|
||||
{
|
||||
/* Retrieve Control (index 4) for specified PPSS level */
|
||||
Store (DeRefOf (Index (DeRefOf (Index
|
||||
(\_SB.CHPS, ToInteger (Arg0))), 4)), Local0)
|
||||
|
||||
/* Pass Control value to EC to limit charging */
|
||||
\_SB.PCI0.LPCB.EC0.CHGS (Local0)
|
||||
}
|
||||
|
||||
/* Initialize charger participant */
|
||||
Method (INIT)
|
||||
{
|
||||
/* Disable charge limit */
|
||||
\_SB.PCI0.LPCB.EC0.CHGD ()
|
||||
}
|
||||
}
|
144
src/soc/intel/braswell/acpi/dptf/cpu.asl
Normal file
144
src/soc/intel/braswell/acpi/dptf/cpu.asl
Normal file
@ -0,0 +1,144 @@
|
||||
External (\_PR.CP00._TSS, MethodObj)
|
||||
External (\_PR.CP00._TPC, MethodObj)
|
||||
External (\_PR.CP00._PTC, PkgObj)
|
||||
External (\_PR.CP00._TSD, PkgObj)
|
||||
External (\_PR.CP00._PSS, MethodObj)
|
||||
|
||||
Device (TCPU)
|
||||
{
|
||||
Name (_HID, EISAID ("INT3401"))
|
||||
Name (_UID, 0)
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Processor Throttling Controls
|
||||
*/
|
||||
|
||||
Method (_TSS)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._TSS)) {
|
||||
Return (\_PR.CP00._TSS)
|
||||
} Else {
|
||||
Return (Package ()
|
||||
{
|
||||
Package () { 0, 0, 0, 0, 0 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TPC)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._TPC)) {
|
||||
Return (\_PR.CP00._TPC)
|
||||
} Else {
|
||||
Return (0)
|
||||
}
|
||||
}
|
||||
|
||||
Method (_PTC)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._PTC)) {
|
||||
Return (\_PR.CP00._PTC)
|
||||
} Else {
|
||||
Return (Package ()
|
||||
{
|
||||
Buffer () { 0 },
|
||||
Buffer () { 0 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TSD)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._TSD)) {
|
||||
Return (\_PR.CP00._TSD)
|
||||
} Else {
|
||||
Return (Package ()
|
||||
{
|
||||
Package () { 5, 0, 0, 0, 0 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TDL)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._TSS)) {
|
||||
Store (SizeOf (\_PR.CP00._TSS ()), Local0)
|
||||
Decrement (Local0)
|
||||
Return (Local0)
|
||||
} Else {
|
||||
Return (0)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Processor Performance Control
|
||||
*/
|
||||
|
||||
Method (_PPC)
|
||||
{
|
||||
Return (0)
|
||||
}
|
||||
|
||||
Method (SPPC, 1)
|
||||
{
|
||||
Store (Arg0, \PPCM)
|
||||
|
||||
/* Notify OS to re-read _PPC limit on each CPU */
|
||||
\PPCN ()
|
||||
}
|
||||
|
||||
Method (_PSS)
|
||||
{
|
||||
If (CondRefOf (\_PR.CP00._PSS)) {
|
||||
Return (\_PR.CP00._PSS)
|
||||
} Else {
|
||||
Return (Package ()
|
||||
{
|
||||
Package () { 0, 0, 0, 0, 0, 0 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Method (_PDL)
|
||||
{
|
||||
/* Check for mainboard specific _PDL override */
|
||||
If (CondRefOf (\_SB.MPDL)) {
|
||||
Return (\_SB.MPDL)
|
||||
} ElseIf (CondRefOf (\_PR.CP00._PSS)) {
|
||||
Store (SizeOf (\_PR.CP00._PSS ()), Local0)
|
||||
Decrement (Local0)
|
||||
Return (Local0)
|
||||
} Else {
|
||||
Return (0)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return PPCC table defined by mainboard */
|
||||
Method (PPCC)
|
||||
{
|
||||
Return (\_SB.MPPC)
|
||||
}
|
||||
|
||||
#ifdef DPTF_CPU_CRITICAL
|
||||
Method (_CRT)
|
||||
{
|
||||
Return (^^CTOK (DPTF_CPU_CRITICAL))
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DPTF_CPU_PASSIVE
|
||||
Method (_PSV)
|
||||
{
|
||||
Return (^^CTOK (DPTF_CPU_PASSIVE))
|
||||
}
|
||||
#endif
|
||||
}
|
78
src/soc/intel/braswell/acpi/dptf/dptf.asl
Normal file
78
src/soc/intel/braswell/acpi/dptf/dptf.asl
Normal file
@ -0,0 +1,78 @@
|
||||
Device (DPTF)
|
||||
{
|
||||
Name (_HID, EISAID ("INT3400"))
|
||||
Name (_UID, 0)
|
||||
|
||||
Name (IDSP, Package()
|
||||
{
|
||||
/* DPPM Passive Policy 1.0 */
|
||||
ToUUID ("42A441D6-AE6A-462B-A84B-4A8CE79027D3"),
|
||||
|
||||
/* DPPM Critical Policy */
|
||||
ToUUID ("97C68AE7-15FA-499c-B8C9-5DA81D606E0A"),
|
||||
|
||||
/* DPPM Cooling Policy */
|
||||
ToUUID ("16CAF1B7-DD38-40ED-B1C1-1B8A1913D531"),
|
||||
})
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
/* Arg0: Buffer containing UUID
|
||||
* Arg1: Integer containing Revision ID of buffer format
|
||||
* Arg2: Integer containing count of entries in Arg3
|
||||
* Arg3: Buffer containing list of DWORD capabilities
|
||||
* Return: Buffer containing list of DWORD capabilities
|
||||
*/
|
||||
Method (_OSC, 4, Serialized)
|
||||
{
|
||||
/* Check for Passive Policy UUID */
|
||||
If (LEqual (DeRefOf (Index (IDSP, 0)), Arg0)) {
|
||||
/* Initialize Thermal Devices */
|
||||
^TINI ()
|
||||
|
||||
#ifdef DPTF_ENABLE_CHARGER
|
||||
/* Initialize Charger Device */
|
||||
^TCHG.INIT ()
|
||||
#endif
|
||||
}
|
||||
|
||||
Return (Arg3)
|
||||
}
|
||||
|
||||
/* Priority based _TRT */
|
||||
Name (TRTR, 1)
|
||||
|
||||
Method (_TRT)
|
||||
{
|
||||
Return (\_SB.DTRT)
|
||||
}
|
||||
|
||||
/* Convert from Degrees C to 1/10 Kelvin for ACPI */
|
||||
Method (CTOK, 1) {
|
||||
/* 10th of Degrees C */
|
||||
Multiply (Arg0, 10, Local0)
|
||||
|
||||
/* Convert to Kelvin */
|
||||
Add (Local0, 2732, Local0)
|
||||
|
||||
Return (Local0)
|
||||
}
|
||||
|
||||
/* Include CPU Participant */
|
||||
#include "cpu.asl"
|
||||
|
||||
/* Include Thermal Participants */
|
||||
#include "thermal.asl"
|
||||
|
||||
#ifdef DPTF_ENABLE_CHARGER
|
||||
/* Include Charger Participant */
|
||||
#include "charger.asl"
|
||||
#endif
|
||||
}
|
203
src/soc/intel/braswell/acpi/dptf/thermal.asl
Normal file
203
src/soc/intel/braswell/acpi/dptf/thermal.asl
Normal file
@ -0,0 +1,203 @@
|
||||
/* Thermal Threshold Event Handler */
|
||||
Method (TEVT, 1, NotSerialized)
|
||||
{
|
||||
Store (ToInteger (Arg0), Local0)
|
||||
|
||||
#ifdef DPTF_TSR0_SENSOR_ID
|
||||
If (LEqual (Local0, DPTF_TSR0_SENSOR_ID)) {
|
||||
Notify (^TSR0, 0x90)
|
||||
}
|
||||
#endif
|
||||
#ifdef DPTF_TSR1_SENSOR_ID
|
||||
If (LEqual (Local0, DPTF_TSR1_SENSOR_ID)) {
|
||||
Notify (^TSR1, 0x90)
|
||||
}
|
||||
#endif
|
||||
#ifdef DPTF_TSR2_SENSOR_ID
|
||||
If (LEqual (Local0, DPTF_TSR2_SENSOR_ID)) {
|
||||
Notify (^TSR2, 0x90)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Thermal device initialization - Disable Aux Trip Points */
|
||||
Method (TINI)
|
||||
{
|
||||
#ifdef DPTF_TSR0_SENSOR_ID
|
||||
^TSR0.PATD ()
|
||||
#endif
|
||||
#ifdef DPTF_TSR1_SENSOR_ID
|
||||
^TSR1.PATD ()
|
||||
#endif
|
||||
#ifdef DPTF_TSR2_SENSOR_ID
|
||||
^TSR2.PATD ()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DPTF_TSR0_SENSOR_ID
|
||||
Device (TSR0)
|
||||
{
|
||||
Name (_HID, EISAID ("INT3403"))
|
||||
Name (_UID, 1)
|
||||
Name (PTYP, 0x03)
|
||||
Name (TMPI, DPTF_TSR0_SENSOR_ID)
|
||||
Name (_STR, Unicode (DPTF_TSR0_SENSOR_NAME))
|
||||
Name (GTSH, 20) /* 2 degree hysteresis */
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TMP, 0, Serialized)
|
||||
{
|
||||
Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
|
||||
}
|
||||
|
||||
Method (_PSV)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR0_PASSIVE))
|
||||
}
|
||||
|
||||
Method (_CRT)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR0_CRITICAL))
|
||||
}
|
||||
|
||||
Name (PATC, 2)
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT0, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT1, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Disable Aux Trip Point */
|
||||
Method (PATD, 0, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PATD (TMPI)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DPTF_TSR1_SENSOR_ID
|
||||
Device (TSR1)
|
||||
{
|
||||
Name (_HID, EISAID ("INT3403"))
|
||||
Name (_UID, 2)
|
||||
Name (PTYP, 0x03)
|
||||
Name (TMPI, DPTF_TSR1_SENSOR_ID)
|
||||
Name (_STR, Unicode (DPTF_TSR1_SENSOR_NAME))
|
||||
Name (GTSH, 20) /* 2 degree hysteresis */
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TMP, 0, Serialized)
|
||||
{
|
||||
Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
|
||||
}
|
||||
|
||||
Method (_PSV)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR1_PASSIVE))
|
||||
}
|
||||
|
||||
Method (_CRT)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR1_CRITICAL))
|
||||
}
|
||||
|
||||
Name (PATC, 2)
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT0, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT1, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Disable Aux Trip Point */
|
||||
Method (PATD, 0, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PATD (TMPI)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DPTF_TSR2_SENSOR_ID
|
||||
Device (TSR2)
|
||||
{
|
||||
Name (_HID, EISAID ("INT3403"))
|
||||
Name (_UID, 3)
|
||||
Name (PTYP, 0x03)
|
||||
Name (TMPI, DPTF_TSR2_SENSOR_ID)
|
||||
Name (_STR, Unicode (DPTF_TSR2_SENSOR_NAME))
|
||||
Name (GTSH, 20) /* 2 degree hysteresis */
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\DPTE, One)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
Method (_TMP, 0, Serialized)
|
||||
{
|
||||
Return (\_SB.PCI0.LPCB.EC0.TSRD (TMPI))
|
||||
}
|
||||
|
||||
Method (_PSV)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR2_PASSIVE))
|
||||
}
|
||||
|
||||
Method (_CRT)
|
||||
{
|
||||
Return (^^CTOK (DPTF_TSR2_CRITICAL))
|
||||
}
|
||||
|
||||
Name (PATC, 2)
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT0, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT0 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Set Aux Trip Point */
|
||||
Method (PAT1, 1, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PAT1 (TMPI, Arg0)
|
||||
}
|
||||
|
||||
/* Disable Aux Trip Point */
|
||||
Method (PATD, 0, Serialized)
|
||||
{
|
||||
\_SB.PCI0.LPCB.EC0.PATD (TMPI)
|
||||
}
|
||||
}
|
||||
#endif
|
108
src/soc/intel/braswell/acpi/globalnvs.asl
Normal file
108
src/soc/intel/braswell/acpi/globalnvs.asl
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* 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, 0x2000)
|
||||
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)
|
||||
PCNT, 8, // 0x11 - Processor count
|
||||
TPMP, 8, // 0x12 - TPM Present and Enabled
|
||||
TLVL, 8, // 0x13 - Throttle Level
|
||||
PPCM, 8, // 0x14 - Maximum P-state usable by OS
|
||||
PM1I, 32, // 0x15 - System Wake Source - PM1 Index
|
||||
|
||||
/* Device Config */
|
||||
Offset (0x20),
|
||||
S5U0, 8, // 0x20 - Enable USB0 in S5
|
||||
S5U1, 8, // 0x21 - Enable USB1 in S5
|
||||
S3U0, 8, // 0x22 - Enable USB0 in S3
|
||||
S3U1, 8, // 0x23 - Enable USB1 in S3
|
||||
TACT, 8, // 0x24 - Thermal Active trip point
|
||||
TPSV, 8, // 0x25 - Thermal Passive trip point
|
||||
TCRT, 8, // 0x26 - Thermal Critical trip point
|
||||
DPTE, 8, // 0x27 - Enable DPTF
|
||||
|
||||
/* Base addresses */
|
||||
Offset (0x30),
|
||||
CMEM, 32, // 0x30 - CBMEM TOC
|
||||
TOLM, 32, // 0x34 - Top of Low Memory
|
||||
CBMC, 32, // 0x38 - coreboot mem console pointer
|
||||
|
||||
/* ChromeOS specific */
|
||||
Offset (0x100),
|
||||
#include <vendorcode/google/chromeos/acpi/gnvs.asl>
|
||||
|
||||
Offset (0x1000),
|
||||
#include <soc/intel/baytrail/acpi/device_nvs.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)
|
||||
}
|
110
src/soc/intel/braswell/acpi/gpio.asl
Normal file
110
src/soc/intel/braswell/acpi/gpio.asl
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 <soc/iomap.h>
|
||||
#include <soc/irq.h>
|
||||
|
||||
/* SouthCluster GPIO */
|
||||
Device (GPSC)
|
||||
{
|
||||
Name (_HID, "INT33FC")
|
||||
Name (_CID, "INT33FC")
|
||||
Name (_UID, 1)
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,,)
|
||||
{
|
||||
GPIO_SC_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add (IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSCORE, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
Return (0xF)
|
||||
}
|
||||
}
|
||||
|
||||
/* NorthCluster GPIO */
|
||||
Device (GPNC)
|
||||
{
|
||||
Name (_HID, "INT33FC")
|
||||
Name (_CID, "INT33FC")
|
||||
Name (_UID, 2)
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,,)
|
||||
{
|
||||
GPIO_NC_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add (IO_BASE_ADDRESS, IO_BASE_OFFSET_GPNCORE, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
Return (0xF)
|
||||
}
|
||||
}
|
||||
|
||||
/* SUS GPIO */
|
||||
Device (GPSS)
|
||||
{
|
||||
Name (_HID, "INT33FC")
|
||||
Name (_CID, "INT33FC")
|
||||
Name (_UID, 3)
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, RMEM)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,,)
|
||||
{
|
||||
GPIO_SUS_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^RMEM._BAS, RBAS)
|
||||
Add (IO_BASE_ADDRESS, IO_BASE_OFFSET_GPSSUS, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
Return (0xF)
|
||||
}
|
||||
}
|
48
src/soc/intel/braswell/acpi/irq_helper.h
Normal file
48
src/soc/intel/braswell/acpi/irq_helper.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#undef PCI_DEV_PIRQ_ROUTES
|
||||
#undef ACPI_DEV_APIC_IRQ
|
||||
#undef PCI_DEV_PIRQ_ROUTE
|
||||
#undef PIRQ_PIC_ROUTES
|
||||
#undef PIRQ_PIC
|
||||
|
||||
#if defined(PIC_MODE)
|
||||
|
||||
#define ACPI_DEV_APIC_IRQ(dev_, pin_, pin_name_) \
|
||||
Package() { ## dev_ ## ffff, pin_, \_SB.PCI0.LPCB.LNK ## pin_name_, 0 }
|
||||
|
||||
#else /* defined(PIC_MODE) */
|
||||
|
||||
#define ACPI_DEV_APIC_IRQ(dev_, pin_, pin_name_) \
|
||||
Package() { ## dev_ ## ffff, pin_, 0, PIRQ ## pin_name_ ## _APIC_IRQ }
|
||||
|
||||
#endif
|
||||
|
||||
#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
|
||||
ACPI_DEV_APIC_IRQ(dev_, 0, a_), \
|
||||
ACPI_DEV_APIC_IRQ(dev_, 1, b_), \
|
||||
ACPI_DEV_APIC_IRQ(dev_, 2, c_), \
|
||||
ACPI_DEV_APIC_IRQ(dev_, 3, d_)
|
||||
|
||||
/* Empty PIRQ_PIC definition. */
|
||||
#define PIRQ_PIC(pirq_, pic_irq_)
|
||||
|
||||
/* Include the mainboard irq route definition. */
|
||||
#include "irqroute.h"
|
492
src/soc/intel/braswell/acpi/irqlinks.asl
Normal file
492
src/soc/intel/braswell/acpi/irqlinks.asl
Normal file
@ -0,0 +1,492 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
Device (LNKA)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 1)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTA)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 10, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLA, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLA, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTA
|
||||
ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLA)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTA)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTA, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKB)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 2)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTB)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLB, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLB, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTB
|
||||
ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLB)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTB)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTB, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKC)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 3)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTC)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 10, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLC, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLC, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTC
|
||||
ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLC)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTC)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTC, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKD)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 4)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTD)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLD, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLD, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTD
|
||||
ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLD)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTD)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTD, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKE)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 5)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTE)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 10, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLE, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLE, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTE
|
||||
ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLE)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTE)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTE, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKF)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 6)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTF)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLF, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLF, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTF
|
||||
ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLF)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTF)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTF, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKG)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 7)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTG)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 10, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLG, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLG, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTG
|
||||
ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLG)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTG)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTG, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (LNKH)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C0F"))
|
||||
Name (_UID, 8)
|
||||
|
||||
// Disable method
|
||||
Method (_DIS, 0, Serialized)
|
||||
{
|
||||
Store (0x80, PRTH)
|
||||
}
|
||||
|
||||
// Possible Resource Settings for this Link
|
||||
Name (_PRS, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared)
|
||||
{ 3, 4, 5, 6, 7, 11, 12, 14, 15 }
|
||||
})
|
||||
|
||||
// Current Resource Settings for this link
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (RTLH, ResourceTemplate()
|
||||
{
|
||||
IRQ(Level, ActiveLow, Shared) {}
|
||||
})
|
||||
CreateWordField(RTLH, 1, IRQ0)
|
||||
|
||||
// Clear the WordField
|
||||
Store (Zero, IRQ0)
|
||||
|
||||
// Set the bit from PRTH
|
||||
ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
|
||||
|
||||
Return (RTLH)
|
||||
}
|
||||
|
||||
// Set Resource Setting for this IRQ link
|
||||
Method (_SRS, 1, Serialized)
|
||||
{
|
||||
CreateWordField(Arg0, 1, IRQ0)
|
||||
|
||||
// Which bit is set?
|
||||
FindSetRightBit(IRQ0, Local0)
|
||||
|
||||
Decrement(Local0)
|
||||
Store(Local0, PRTH)
|
||||
}
|
||||
|
||||
// Status
|
||||
Method (_STA, 0, Serialized)
|
||||
{
|
||||
If(And(PRTH, 0x80)) {
|
||||
Return (0x9)
|
||||
} Else {
|
||||
Return (0xb)
|
||||
}
|
||||
}
|
||||
}
|
37
src/soc/intel/braswell/acpi/irqroute.asl
Normal file
37
src/soc/intel/braswell/acpi/irqroute.asl
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* 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
|
||||
*/
|
||||
|
||||
// PCI Interrupt Routing
|
||||
Method(_PRT)
|
||||
{
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTES
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTES
|
||||
})
|
||||
}
|
||||
}
|
167
src/soc/intel/braswell/acpi/lpc.asl
Normal file
167
src/soc/intel/braswell/acpi/lpc.asl
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* 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
|
||||
*/
|
||||
|
||||
// Intel LPC Bus Device - 0:1f.0
|
||||
|
||||
Device (LPCB)
|
||||
{
|
||||
Name(_ADR, 0x001f0000)
|
||||
|
||||
#include "irqlinks.asl"
|
||||
|
||||
#include "acpi/ec.asl"
|
||||
|
||||
Device (DMAC) // DMA Controller
|
||||
{
|
||||
Name(_HID, EISAID("PNP0200"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO (Decode16, 0x00, 0x00, 0x01, 0x20)
|
||||
IO (Decode16, 0x81, 0x81, 0x01, 0x11)
|
||||
IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
|
||||
IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
|
||||
DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
|
||||
})
|
||||
}
|
||||
|
||||
Device (FWH) // Firmware Hub
|
||||
{
|
||||
Name (_HID, EISAID("INT0800"))
|
||||
Name (_CRS, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
|
||||
})
|
||||
}
|
||||
|
||||
Device (HPET)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0103"))
|
||||
Name (_CID, 0x010CD041)
|
||||
|
||||
Method (_STA, 0) // Device Status
|
||||
{
|
||||
Return (0xf) // Enable and show device
|
||||
}
|
||||
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed(ReadOnly, 0xfed00000, 0x400)
|
||||
})
|
||||
}
|
||||
|
||||
Device(PIC) // 8259 Interrupt Controller
|
||||
{
|
||||
Name(_HID,EISAID("PNP0000"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO (Decode16, 0x20, 0x20, 0x01, 0x02)
|
||||
IO (Decode16, 0x24, 0x24, 0x01, 0x02)
|
||||
IO (Decode16, 0x28, 0x28, 0x01, 0x02)
|
||||
IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
|
||||
IO (Decode16, 0x30, 0x30, 0x01, 0x02)
|
||||
IO (Decode16, 0x34, 0x34, 0x01, 0x02)
|
||||
IO (Decode16, 0x38, 0x38, 0x01, 0x02)
|
||||
IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
|
||||
IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
|
||||
IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
|
||||
IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
|
||||
IO (Decode16, 0xac, 0xac, 0x01, 0x02)
|
||||
IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
|
||||
IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
|
||||
IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
|
||||
IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
|
||||
IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
|
||||
IRQNoFlags () { 2 }
|
||||
})
|
||||
}
|
||||
|
||||
Device(LDRC) // LPC device: Resource consumption
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C02"))
|
||||
Name (_UID, 2)
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
|
||||
IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
|
||||
IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
|
||||
IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
|
||||
IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
|
||||
IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
|
||||
IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
|
||||
})
|
||||
|
||||
Method (_CRS, 0, NotSerialized)
|
||||
{
|
||||
Return (RBUF)
|
||||
}
|
||||
}
|
||||
|
||||
Device (RTC) // Real Time Clock
|
||||
{
|
||||
Name (_HID, EISAID("PNP0B00"))
|
||||
Name (_CRS, ResourceTemplate()
|
||||
{
|
||||
IO (Decode16, 0x70, 0x70, 1, 8)
|
||||
// Disable as Windows doesn't like it, and systems don't seem to use it.
|
||||
// IRQNoFlags() { 8 }
|
||||
})
|
||||
}
|
||||
|
||||
Device (TIMR) // Intel 8254 timer
|
||||
{
|
||||
Name(_HID, EISAID("PNP0100"))
|
||||
Name(_CRS, ResourceTemplate()
|
||||
{
|
||||
IO (Decode16, 0x40, 0x40, 0x01, 0x04)
|
||||
IO (Decode16, 0x50, 0x50, 0x10, 0x04)
|
||||
IRQNoFlags() {0}
|
||||
})
|
||||
}
|
||||
|
||||
// Include mainboard's superio.asl file.
|
||||
#include "acpi/superio.asl"
|
||||
|
||||
#ifdef ENABLE_TPM
|
||||
Device (TPM) // Trusted Platform Module
|
||||
{
|
||||
Name(_HID, EISAID("IFX0102"))
|
||||
Name(_CID, 0x310cd041)
|
||||
Name(_UID, 1)
|
||||
|
||||
Method(_STA, 0)
|
||||
{
|
||||
If (TPMP) {
|
||||
Return (0xf)
|
||||
}
|
||||
Return (0x0)
|
||||
}
|
||||
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
|
||||
IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10)
|
||||
Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
|
||||
IRQ (Edge, Activehigh, Exclusive) { 6 }
|
||||
})
|
||||
}
|
||||
#endif
|
||||
}
|
119
src/soc/intel/braswell/acpi/lpe.asl
Normal file
119
src/soc/intel/braswell/acpi/lpe.asl
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
Device (LPEA)
|
||||
{
|
||||
Name (_HID, "80860F28")
|
||||
Name (_CID, "80860F28")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "Low Power Audio Controller")
|
||||
Name (_PR0, Package () { PLPE })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x00200000, BAR0)
|
||||
Memory32Fixed (ReadWrite, 0, 0x00001000, BAR1)
|
||||
Memory32Fixed (ReadWrite, 0, 0x00100000, BAR2)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_DMA0_IRQ
|
||||
}
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_DMA1_IRQ
|
||||
}
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_SSP0_IRQ
|
||||
}
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_SSP1_IRQ
|
||||
}
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_SSP2_IRQ
|
||||
}
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPE_IPC2HOST_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
/* Update BAR0 from NVS */
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, BAS0)
|
||||
Store (\LPB0, BAS0)
|
||||
|
||||
/* Update BAR1 from NVS */
|
||||
CreateDwordField (^RBUF, ^BAR1._BAS, BAS1)
|
||||
Store (\LPB1, BAS1)
|
||||
|
||||
/* Update LPE FW from NVS */
|
||||
CreateDwordField (^RBUF, ^BAR2._BAS, BAS2)
|
||||
Store (\LPFW, BAS2)
|
||||
|
||||
/* Append any Mainboard defined GPIOs */
|
||||
If (CondRefOf (^GBUF, Local0)) {
|
||||
ConcatenateResTemplate (^RBUF, ^GBUF, Local1)
|
||||
Return (Local1)
|
||||
}
|
||||
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\LPEN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, LPB1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
PowerResource (PLPE, 0, 0)
|
||||
{
|
||||
Method (_STA)
|
||||
{
|
||||
Return (1)
|
||||
}
|
||||
|
||||
Method (_OFF)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_ON)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
}
|
712
src/soc/intel/braswell/acpi/lpss.asl
Normal file
712
src/soc/intel/braswell/acpi/lpss.asl
Normal file
@ -0,0 +1,712 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
Device (SDM1)
|
||||
{
|
||||
Name (_HID, "INTL9C60")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "DMA Controller #1")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_DMA1_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S0B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S0EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (SDM2)
|
||||
{
|
||||
Name (_HID, "INTL9C60")
|
||||
Name (_UID, 2)
|
||||
Name (_DDN, "DMA Controller #2")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_DMA2_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S8B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S8EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C1)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "I2C Controller #1")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C1_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S1B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S1EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S1B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C2)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 2)
|
||||
Name (_DDN, "I2C Controller #2")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C2_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S2B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S2EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S2B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C3)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 3)
|
||||
Name (_DDN, "I2C Controller #3")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C3_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S3B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S3EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S3B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C4)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 4)
|
||||
Name (_DDN, "I2C Controller #4")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C4_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S4B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S4EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S4B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C5)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 5)
|
||||
Name (_DDN, "I2C Controller #5")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C5_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S5B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S5EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S5B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C6)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 6)
|
||||
Name (_DDN, "I2C Controller #6")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C6_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S6B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S6EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S6B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (I2C7)
|
||||
{
|
||||
Name (_HID, "80860F41")
|
||||
Name (_UID, 7)
|
||||
Name (_DDN, "I2C Controller #7")
|
||||
|
||||
/* Standard Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (SSCN, Package () { 0x200, 0x200, 0x6 })
|
||||
|
||||
/* Fast Mode: HCNT, LCNT, SDA Hold Time */
|
||||
Name (FMCN, Package () { 0x55, 0x99, 0x6 })
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_I2C7_IRQ
|
||||
}
|
||||
FixedDMA (0x10, 0x0, Width32Bit, )
|
||||
FixedDMA (0x11, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S7B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S7EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S7B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (SPI1)
|
||||
{
|
||||
Name (_HID, "80860F0E")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "SPI Controller #2")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_SPI_IRQ
|
||||
}
|
||||
FixedDMA (0x0, 0x0, Width32Bit, )
|
||||
FixedDMA (0x1, 0x1, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\S9B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\S9EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, S9B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (PWM1)
|
||||
{
|
||||
Name (_HID, "80860F09")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "PWM Controller #1")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\SAB0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\SAEN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (PWM2)
|
||||
{
|
||||
Name (_HID, "80860F09")
|
||||
Name (_UID, 2)
|
||||
Name (_DDN, "PWM Controller #2")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\SBB0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\SBEN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (UAR1)
|
||||
{
|
||||
Name (_HID, "80860F0A")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "HS-UART Controller #1")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_HSUART1_IRQ
|
||||
}
|
||||
FixedDMA (0x2, 0x2, Width32Bit, )
|
||||
FixedDMA (0x3, 0x3, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\SCB0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\SCEN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, SCB1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (UAR2)
|
||||
{
|
||||
Name (_HID, "80860F0A")
|
||||
Name (_UID, 2)
|
||||
Name (_DDN, "HS-UART Controller #2")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
LPSS_HSUART2_IRQ
|
||||
}
|
||||
FixedDMA (0x4, 0x4, Width32Bit, )
|
||||
FixedDMA (0x5, 0x5, Width32Bit, )
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\SDB0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\SDEN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, SDB1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
109
src/soc/intel/braswell/acpi/pcie.asl
Normal file
109
src/soc/intel/braswell/acpi/pcie.asl
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Intel SOC PCIe support */
|
||||
|
||||
Device (RP01)
|
||||
{
|
||||
Name (_ADR, 0x001c0000)
|
||||
|
||||
Method (_PRT)
|
||||
{
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, A, B, C, D)
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, A, B, C, D)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (RP02)
|
||||
{
|
||||
Name (_ADR, 0x001c0001)
|
||||
|
||||
Method (_PRT)
|
||||
{
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, B, C, D, A)
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, B, C, D, A)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (RP03)
|
||||
{
|
||||
Name (_ADR, 0x001c0002)
|
||||
|
||||
Method (_PRT)
|
||||
{
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, C, D, A, B)
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, C, D, A, B)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (RP04)
|
||||
{
|
||||
Name (_ADR, 0x001c0003)
|
||||
|
||||
Method (_PRT)
|
||||
{
|
||||
If (PICM) {
|
||||
Return (Package() {
|
||||
#undef PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, D, A, B, C)
|
||||
})
|
||||
} Else {
|
||||
Return (Package() {
|
||||
#define PIC_MODE
|
||||
#include <soc/intel/baytrail/acpi/irq_helper.h>
|
||||
PCI_DEV_PIRQ_ROUTE(0x0, D, A, B, C)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
78
src/soc/intel/braswell/acpi/platform.asl
Normal file
78
src/soc/intel/braswell/acpi/platform.asl
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2012 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
|
||||
*/
|
||||
|
||||
/* The APM port can be used for generating software SMIs */
|
||||
|
||||
OperationRegion (APMP, SystemIO, 0xb2, 2)
|
||||
Field (APMP, ByteAcc, NoLock, Preserve)
|
||||
{
|
||||
APMC, 8, // APM command
|
||||
APMS, 8 // APM status
|
||||
}
|
||||
|
||||
/* Port 80 POST */
|
||||
|
||||
OperationRegion (POST, SystemIO, 0x80, 1)
|
||||
Field (POST, ByteAcc, Lock, Preserve)
|
||||
{
|
||||
DBG0, 8
|
||||
}
|
||||
|
||||
/* SMI I/O Trap */
|
||||
Method(TRAP, 1, Serialized)
|
||||
{
|
||||
Store (Arg0, SMIF) // SMI Function
|
||||
Store (0, TRP0) // Generate trap
|
||||
Return (SMIF) // Return value of SMI handler
|
||||
}
|
||||
|
||||
/* The _PIC method is called by the OS to choose between interrupt
|
||||
* routing via the i8259 interrupt controller or the APIC.
|
||||
*
|
||||
* _PIC is called with a parameter of 0 for i8259 configuration and
|
||||
* with a parameter of 1 for Local Apic/IOAPIC configuration.
|
||||
*/
|
||||
|
||||
Method(_PIC, 1)
|
||||
{
|
||||
// Remember the OS' IRQ routing choice.
|
||||
Store(Arg0, PICM)
|
||||
}
|
||||
|
||||
/* The _PTS method (Prepare To Sleep) is called before the OS is
|
||||
* entering a sleep state. The sleep state number is passed in Arg0
|
||||
*/
|
||||
|
||||
Method(_PTS,1)
|
||||
{
|
||||
}
|
||||
|
||||
/* The _WAK method is called on system wakeup */
|
||||
|
||||
Method(_WAK,1)
|
||||
{
|
||||
Return(Package(){0,0})
|
||||
}
|
||||
|
||||
Method (_SWS)
|
||||
{
|
||||
/* Index into PM1 for device that caused wake */
|
||||
Return (\PM1I)
|
||||
}
|
187
src/soc/intel/braswell/acpi/scc.asl
Normal file
187
src/soc/intel/braswell/acpi/scc.asl
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
Device (EMMC)
|
||||
{
|
||||
Name (_HID, "80860F14")
|
||||
Name (_CID, "PNP0D40")
|
||||
Name (_UID, 1)
|
||||
Name (_DDN, "eMMC Controller 4.5")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
SCC_EMMC_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\C0B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\C0EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, C0B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Device (EM45)
|
||||
{
|
||||
/* Slot 0, Function 8 */
|
||||
Name (_ADR, 0x8)
|
||||
|
||||
Method (_RMV, 0, NotSerialized)
|
||||
{
|
||||
Return (0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Device (SDIO)
|
||||
{
|
||||
Name (_HID, "INT33BB")
|
||||
Name (_CID, "PNP0D40")
|
||||
Name (_UID, 2)
|
||||
Name (_DDN, "SDIO Controller")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
SCC_SDIO_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\C1B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\C1EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, C1B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
||||
|
||||
Device (SDCD)
|
||||
{
|
||||
Name (_HID, "80860F16")
|
||||
Name (_CID, "PNP0D40")
|
||||
Name (_UID, 3)
|
||||
Name (_DDN, "SD Card Controller")
|
||||
|
||||
Name (RBUF, ResourceTemplate()
|
||||
{
|
||||
Memory32Fixed (ReadWrite, 0, 0x1000, BAR0)
|
||||
Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,)
|
||||
{
|
||||
SCC_SD_IRQ
|
||||
}
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^BAR0._BAS, RBAS)
|
||||
Store (\C2B0, RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
|
||||
Method (_STA)
|
||||
{
|
||||
If (LEqual (\C2EN, 1)) {
|
||||
Return (0xF)
|
||||
} Else {
|
||||
Return (0x0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationRegion (KEYS, SystemMemory, C2B1, 0x100)
|
||||
Field (KEYS, DWordAcc, NoLock, WriteAsZeros)
|
||||
{
|
||||
Offset (0x84),
|
||||
PSAT, 32,
|
||||
}
|
||||
|
||||
Method (_PS3)
|
||||
{
|
||||
Or (PSAT, 0x00000003, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
|
||||
Method (_PS0)
|
||||
{
|
||||
And (PSAT, 0xfffffffc, PSAT)
|
||||
Or (PSAT, 0x00000000, PSAT)
|
||||
}
|
||||
}
|
26
src/soc/intel/braswell/acpi/sleepstates.asl
Normal file
26
src/soc/intel/braswell/acpi/sleepstates.asl
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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})
|
274
src/soc/intel/braswell/acpi/southcluster.asl
Normal file
274
src/soc/intel/braswell/acpi/southcluster.asl
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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 <soc/iomap.h>
|
||||
#include <soc/irq.h>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Intel Legacy Block
|
||||
OperationRegion(ILBS, SystemMemory, ILB_BASE_ADDRESS, ILB_BASE_SIZE)
|
||||
Field (ILBS, AnyAcc, NoLock, Preserve)
|
||||
{
|
||||
Offset (0x8),
|
||||
PRTA, 8,
|
||||
PRTB, 8,
|
||||
PRTC, 8,
|
||||
PRTD, 8,
|
||||
PRTE, 8,
|
||||
PRTF, 8,
|
||||
PRTG, 8,
|
||||
PRTH, 8,
|
||||
}
|
||||
}
|
||||
|
||||
Name(_HID,EISAID("PNP0A08")) // PCIe
|
||||
Name(_CID,EISAID("PNP0A03")) // PCI
|
||||
|
||||
Name(_ADR, 0)
|
||||
Name(_BBN, 0)
|
||||
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Name (MCRS, ResourceTemplate()
|
||||
{
|
||||
// Bus Numbers
|
||||
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
|
||||
0x0000, 0x0000, 0x00ff, 0x0000, 0x0100,,, PB00)
|
||||
|
||||
// IO Region 0
|
||||
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8,,, PI00)
|
||||
|
||||
// PCI Config Space
|
||||
Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008)
|
||||
|
||||
// IO Region 1
|
||||
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
|
||||
0x0000, 0x0d00, 0xffff, 0x0000, 0xf300,,, PI01)
|
||||
|
||||
// VGA memory (0xa0000-0xbffff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000a0000, 0x000bffff, 0x00000000,
|
||||
0x00020000,,, ASEG)
|
||||
|
||||
// OPROM reserved (0xc0000-0xc3fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c0000, 0x000c3fff, 0x00000000,
|
||||
0x00004000,,, OPR0)
|
||||
|
||||
// OPROM reserved (0xc4000-0xc7fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c4000, 0x000c7fff, 0x00000000,
|
||||
0x00004000,,, OPR1)
|
||||
|
||||
// OPROM reserved (0xc8000-0xcbfff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000c8000, 0x000cbfff, 0x00000000,
|
||||
0x00004000,,, OPR2)
|
||||
|
||||
// OPROM reserved (0xcc000-0xcffff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000cc000, 0x000cffff, 0x00000000,
|
||||
0x00004000,,, OPR3)
|
||||
|
||||
// OPROM reserved (0xd0000-0xd3fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d0000, 0x000d3fff, 0x00000000,
|
||||
0x00004000,,, OPR4)
|
||||
|
||||
// OPROM reserved (0xd4000-0xd7fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d4000, 0x000d7fff, 0x00000000,
|
||||
0x00004000,,, OPR5)
|
||||
|
||||
// OPROM reserved (0xd8000-0xdbfff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000d8000, 0x000dbfff, 0x00000000,
|
||||
0x00004000,,, OPR6)
|
||||
|
||||
// OPROM reserved (0xdc000-0xdffff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000dc000, 0x000dffff, 0x00000000,
|
||||
0x00004000,,, OPR7)
|
||||
|
||||
// BIOS Extension (0xe0000-0xe3fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e0000, 0x000e3fff, 0x00000000,
|
||||
0x00004000,,, ESG0)
|
||||
|
||||
// BIOS Extension (0xe4000-0xe7fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e4000, 0x000e7fff, 0x00000000,
|
||||
0x00004000,,, ESG1)
|
||||
|
||||
// BIOS Extension (0xe8000-0xebfff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000e8000, 0x000ebfff, 0x00000000,
|
||||
0x00004000,,, ESG2)
|
||||
|
||||
// BIOS Extension (0xec000-0xeffff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000ec000, 0x000effff, 0x00000000,
|
||||
0x00004000,,, ESG3)
|
||||
|
||||
// System BIOS (0xf0000-0xfffff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x000f0000, 0x000fffff, 0x00000000,
|
||||
0x00010000,,, FSEG)
|
||||
|
||||
// PCI Memory Region (Top of memory-CONFIG_MMCONF_BASE_ADDRESS)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000,,, PMEM)
|
||||
|
||||
// TPM Area (0xfed40000-0xfed44fff)
|
||||
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
|
||||
Cacheable, ReadWrite,
|
||||
0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
|
||||
0x00005000,,, TPMR)
|
||||
})
|
||||
|
||||
// Update PCI resource area
|
||||
CreateDwordField(MCRS, PMEM._MIN, PMIN)
|
||||
CreateDwordField(MCRS, PMEM._MAX, PMAX)
|
||||
CreateDwordField(MCRS, PMEM._LEN, PLEN)
|
||||
|
||||
// TOLM is BMBOUND accessible from IOSF so is saved in NVS
|
||||
Store (\TOLM, PMIN)
|
||||
Store (Subtract(CONFIG_MMCONF_BASE_ADDRESS, 1), PMAX)
|
||||
Add (Subtract (PMAX, PMIN), 1, PLEN)
|
||||
|
||||
Return (MCRS)
|
||||
}
|
||||
|
||||
/* Device Resource Consumption */
|
||||
Device (PDRC)
|
||||
{
|
||||
Name (_HID, EISAID("PNP0C02"))
|
||||
Name (_UID, 1)
|
||||
|
||||
Name (PDRS, ResourceTemplate() {
|
||||
Memory32Fixed(ReadWrite, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, MCFG_BASE_ADDRESS, MCFG_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, PMC_BASE_ADDRESS, PMC_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, ILB_BASE_ADDRESS, ILB_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, SPI_BASE_ADDRESS, SPI_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, MPHY_BASE_ADDRESS, MPHY_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, PUNIT_BASE_ADDRESS, PUNIT_BASE_SIZE)
|
||||
Memory32Fixed(ReadWrite, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE)
|
||||
})
|
||||
|
||||
// Current Resource Settings
|
||||
Method (_CRS, 0, Serialized)
|
||||
{
|
||||
Return(PDRS)
|
||||
}
|
||||
}
|
||||
|
||||
Method (_OSC, 4)
|
||||
{
|
||||
/* Check for proper GUID */
|
||||
If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
|
||||
{
|
||||
/* Let OS control everything */
|
||||
Return (Arg3)
|
||||
}
|
||||
Else
|
||||
{
|
||||
/* Unrecognized UUID */
|
||||
CreateDWordField (Arg3, 0, CDW1)
|
||||
Or (CDW1, 4, CDW1)
|
||||
Return (Arg3)
|
||||
}
|
||||
}
|
||||
|
||||
/* IOSF MBI Interface for kernel access */
|
||||
Device (IOSF)
|
||||
{
|
||||
Name (_HID, "INT33BD")
|
||||
Name (_CID, "INT33BD")
|
||||
Name (_UID, 1)
|
||||
|
||||
Name (RBUF, ResourceTemplate ()
|
||||
{
|
||||
/* MCR / MDR / MCRX */
|
||||
Memory32Fixed (ReadWrite, 0, 12, RBAR)
|
||||
})
|
||||
|
||||
Method (_CRS)
|
||||
{
|
||||
CreateDwordField (^RBUF, ^RBAR._BAS, RBAS)
|
||||
Store (Add (MCFG_BASE_ADDRESS, 0xD0), RBAS)
|
||||
Return (^RBUF)
|
||||
}
|
||||
}
|
||||
|
||||
// LPC Bridge 0:1f.0
|
||||
#include "lpc.asl"
|
||||
|
||||
// USB XHCI 0:14.0
|
||||
#include "xhci.asl"
|
||||
|
||||
// IRQ routing for each PCI device
|
||||
#include "irqroute.asl"
|
||||
|
||||
// PCI Express Ports 0:1c.x
|
||||
#include "pcie.asl"
|
||||
|
||||
Scope (\_SB)
|
||||
{
|
||||
// GPIO Devices
|
||||
#include "gpio.asl"
|
||||
|
||||
// LPSS Devices
|
||||
#include "lpss.asl"
|
||||
|
||||
// SCC Devices
|
||||
#include "scc.asl"
|
||||
|
||||
// LPE Device
|
||||
#include "lpe.asl"
|
||||
}
|
36
src/soc/intel/braswell/acpi/xhci.asl
Normal file
36
src/soc/intel/braswell/acpi/xhci.asl
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
Device (XHCI)
|
||||
{
|
||||
Name (_ADR, 0x00140000)
|
||||
Name (_PRW, Package () { 0x0d, 3 })
|
||||
Name (_S3D, 3) /* Highest D state in S3 state */
|
||||
|
||||
Device (RHUB)
|
||||
{
|
||||
Name (_ADR, 0x00000000)
|
||||
Device (PRT1) { Name (_ADR, 1) }
|
||||
Device (PRT2) { Name (_ADR, 2) }
|
||||
Device (PRT3) { Name (_ADR, 3) }
|
||||
Device (PRT4) { Name (_ADR, 4) }
|
||||
}
|
||||
}
|
1
src/soc/intel/braswell/bootblock/Makefile.inc
Normal file
1
src/soc/intel/braswell/bootblock/Makefile.inc
Normal file
@ -0,0 +1 @@
|
||||
chipset_bootblock_inc += $(src)/soc/intel/baytrail/bootblock/timestamp.inc
|
79
src/soc/intel/braswell/bootblock/bootblock.c
Normal file
79
src/soc/intel/braswell/bootblock/bootblock.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 <cpu/x86/cache.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <cpu/intel/microcode/microcode.c>
|
||||
|
||||
static void set_var_mtrr(int reg, uint32_t base, uint32_t size, int type)
|
||||
{
|
||||
msr_t basem, maskm;
|
||||
basem.lo = base | type;
|
||||
basem.hi = 0;
|
||||
wrmsr(MTRRphysBase_MSR(reg), basem);
|
||||
maskm.lo = ~(size - 1) | MTRRphysMaskValid;
|
||||
maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
|
||||
wrmsr(MTRRphysMask_MSR(reg), maskm);
|
||||
}
|
||||
|
||||
static void enable_rom_caching(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
disable_cache();
|
||||
/* Why only top 4MiB ? */
|
||||
set_var_mtrr(1, 0xffc00000, 4*1024*1024, MTRR_TYPE_WRPROT);
|
||||
enable_cache();
|
||||
|
||||
/* Enable Variable MTRRs */
|
||||
msr.hi = 0x00000000;
|
||||
msr.lo = 0x00000800;
|
||||
wrmsr(MTRRdefType_MSR, msr);
|
||||
}
|
||||
|
||||
static void setup_mmconfig(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);
|
||||
}
|
||||
|
||||
static void bootblock_cpu_init(void)
|
||||
{
|
||||
/* Allow memory-mapped PCI config access. */
|
||||
setup_mmconfig();
|
||||
|
||||
/* Load microcode before any caching. */
|
||||
intel_update_microcode_from_cbfs();
|
||||
enable_rom_caching();
|
||||
}
|
18
src/soc/intel/braswell/bootblock/timestamp.inc
Normal file
18
src/soc/intel/braswell/bootblock/timestamp.inc
Normal file
@ -0,0 +1,18 @@
|
||||
/* Store the initial timestamp for booting in mmx registers. This works
|
||||
* because the bootblock isn't being compiled with MMX support so mm0 and
|
||||
* mm1 will be preserved into romstage. */
|
||||
.code32
|
||||
|
||||
.global stash_timestamp
|
||||
stash_timestamp:
|
||||
|
||||
/* Save the BIST value */
|
||||
movl %eax, %ebp
|
||||
|
||||
finit
|
||||
rdtsc
|
||||
movd %eax, %mm0
|
||||
movd %edx, %mm1
|
||||
|
||||
/* Restore the BIST value to %eax */
|
||||
movl %ebp, %eax
|
93
src/soc/intel/braswell/chip.c
Normal file
93
src/soc/intel/braswell/chip.c
Normal file
@ -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 <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <arch/pci_ops.h>
|
||||
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/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 struct device_operations cpu_bus_ops = {
|
||||
.read_resources = DEVICE_NOOP,
|
||||
.set_resources = DEVICE_NOOP,
|
||||
.enable_resources = DEVICE_NOOP,
|
||||
.init = baytrail_init_cpus,
|
||||
.scan_bus = NULL,
|
||||
};
|
||||
|
||||
|
||||
static void enable_dev(device_t dev)
|
||||
{
|
||||
/* 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;
|
||||
} else if (dev->path.type == DEVICE_PATH_PCI) {
|
||||
/* Handle south cluster enablement. */
|
||||
if (PCI_SLOT(dev->path.pci.devfn) > GFX_DEV &&
|
||||
(dev->ops == NULL || dev->ops->enable == NULL)) {
|
||||
southcluster_enable_dev(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called at BS_DEV_INIT_CHIPS time -- very early. Just after BS_PRE_DEVICE. */
|
||||
static void soc_init(void *chip_info)
|
||||
{
|
||||
baytrail_init_pre_device(chip_info);
|
||||
}
|
||||
|
||||
struct chip_operations soc_intel_baytrail_ops = {
|
||||
CHIP_NAME("Intel BayTrail SoC")
|
||||
.enable_dev = enable_dev,
|
||||
.init = soc_init,
|
||||
};
|
||||
|
||||
static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
||||
{
|
||||
if (!vendor || !device) {
|
||||
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
pci_read_config32(dev, PCI_VENDOR_ID));
|
||||
} else {
|
||||
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
((device & 0xffff) << 16) | (vendor & 0xffff));
|
||||
}
|
||||
}
|
||||
|
||||
struct pci_operations soc_pci_ops = {
|
||||
.set_subsystem = &pci_set_subsystem,
|
||||
};
|
95
src/soc/intel/braswell/chip.h
Normal file
95
src/soc/intel/braswell/chip.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* The devicetree parser expects chip.h to reside directly in the path
|
||||
* specified by the devicetree. */
|
||||
|
||||
#ifndef _BAYTRAIL_CHIP_H_
|
||||
#define _BAYTRAIL_CHIP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct soc_intel_baytrail_config {
|
||||
uint8_t enable_xdp_tap;
|
||||
uint8_t sata_port_map;
|
||||
uint8_t sata_ahci;
|
||||
uint8_t ide_legacy_combined;
|
||||
uint8_t clkreq_enable;
|
||||
|
||||
/* VR low power settings -- enable PS2 mode for gfx and core */
|
||||
int vnn_ps2_enable;
|
||||
int vcc_ps2_enable;
|
||||
|
||||
/* Disable SLP_X stretching after SUS power well loss. */
|
||||
int disable_slp_x_stretch_sus_fail;
|
||||
|
||||
/* USB Port Disable mask */
|
||||
uint16_t usb2_port_disable_mask;
|
||||
uint16_t usb3_port_disable_mask;
|
||||
|
||||
/* USB routing */
|
||||
int usb_route_to_xhci;
|
||||
|
||||
/* USB PHY settings specific to the board */
|
||||
uint32_t usb2_per_port_lane0;
|
||||
uint32_t usb2_per_port_rcomp_hs_pullup0;
|
||||
uint32_t usb2_per_port_lane1;
|
||||
uint32_t usb2_per_port_rcomp_hs_pullup1;
|
||||
uint32_t usb2_per_port_lane2;
|
||||
uint32_t usb2_per_port_rcomp_hs_pullup2;
|
||||
uint32_t usb2_per_port_lane3;
|
||||
uint32_t usb2_per_port_rcomp_hs_pullup3;
|
||||
uint32_t usb2_comp_bg;
|
||||
|
||||
/* LPE Audio Clock configuration. */
|
||||
int lpe_codec_clk_freq; /* 19 or 25 are valid. */
|
||||
int lpe_codec_clk_num; /* Platform clock pins. [0:5] are valid. */
|
||||
|
||||
/* Native SD Card controller - override controller capabilities. */
|
||||
uint32_t sdcard_cap_low;
|
||||
uint32_t sdcard_cap_high;
|
||||
|
||||
/* Enable devices in ACPI mode */
|
||||
int lpss_acpi_mode;
|
||||
int scc_acpi_mode;
|
||||
int lpe_acpi_mode;
|
||||
|
||||
/* Allow PCIe devices to wake system from suspend. */
|
||||
int pcie_wake_enable;
|
||||
|
||||
int gpu_pipea_port_select; /* Port select: 1=DP_B 2=DP_C */
|
||||
uint16_t gpu_pipea_power_on_delay;
|
||||
uint16_t gpu_pipea_light_on_delay;
|
||||
uint16_t gpu_pipea_power_off_delay;
|
||||
uint16_t gpu_pipea_light_off_delay;
|
||||
uint16_t gpu_pipea_power_cycle_delay;
|
||||
int gpu_pipea_pwm_freq_hz;
|
||||
|
||||
int gpu_pipeb_port_select; /* Port select: 1=DP_B 2=DP_C */
|
||||
uint16_t gpu_pipeb_power_on_delay;
|
||||
uint16_t gpu_pipeb_light_on_delay;
|
||||
uint16_t gpu_pipeb_power_off_delay;
|
||||
uint16_t gpu_pipeb_light_off_delay;
|
||||
uint16_t gpu_pipeb_power_cycle_delay;
|
||||
int gpu_pipeb_pwm_freq_hz;
|
||||
int disable_ddr_2x_refresh_rate;
|
||||
};
|
||||
|
||||
extern struct chip_operations soc_intel_baytrail_ops;
|
||||
#endif /* _BAYTRAIL_CHIP_H_ */
|
309
src/soc/intel/braswell/cpu.c
Normal file
309
src/soc/intel/braswell/cpu.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/intel/microcode.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/lapic.h>
|
||||
#include <cpu/x86/mp.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/msr.h>
|
||||
#include <soc/pattrs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
static void smm_relocate(void *unused);
|
||||
static void enable_smis(void *unused);
|
||||
|
||||
static struct mp_flight_record mp_steps[] = {
|
||||
MP_FR_BLOCK_APS(smm_relocate, NULL, smm_relocate, NULL),
|
||||
MP_FR_BLOCK_APS(mp_initialize_cpu, NULL, mp_initialize_cpu, NULL),
|
||||
/* Wait for APs to finish initialization before proceeding. */
|
||||
MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
|
||||
};
|
||||
|
||||
/* The APIC id space on Bay Trail is sparse. Each id is separated by 2. */
|
||||
static int adjust_apic_id(int index, int apic_id)
|
||||
{
|
||||
return 2 * index;
|
||||
}
|
||||
|
||||
/* Package level MSRs */
|
||||
const struct reg_script package_msr_script[] = {
|
||||
/* Set Package TDP to ~7W */
|
||||
REG_MSR_WRITE(MSR_PKG_POWER_LIMIT, 0x3880fa),
|
||||
REG_MSR_RMW(MSR_PP1_POWER_LIMIT, ~(0x7f << 17), 0),
|
||||
REG_MSR_WRITE(MSR_PKG_TURBO_CFG1, 0x702),
|
||||
REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG1, 0x200b),
|
||||
REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG2, 0),
|
||||
REG_MSR_WRITE(MSR_CPU_THERM_CFG1, 0x00000305),
|
||||
REG_MSR_WRITE(MSR_CPU_THERM_CFG2, 0x0405500d),
|
||||
REG_MSR_WRITE(MSR_CPU_THERM_SENS_CFG, 0x27),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
/* Core level MSRs */
|
||||
const struct reg_script core_msr_script[] = {
|
||||
/* Dynamic L2 shrink enable and threshold, clear SINGLE_PCTL bit 11 */
|
||||
REG_MSR_RMW(MSR_PMG_CST_CONFIG_CONTROL, ~0x3f080f, 0xe0008),
|
||||
REG_MSR_RMW(MSR_POWER_MISC,
|
||||
~(ENABLE_ULFM_AUTOCM_MASK | ENABLE_INDP_AUTOCM_MASK), 0),
|
||||
/* Disable C1E */
|
||||
REG_MSR_RMW(MSR_POWER_CTL, ~0x2, 0),
|
||||
REG_MSR_OR(MSR_POWER_MISC, 0x44),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
void baytrail_init_cpus(device_t dev)
|
||||
{
|
||||
struct bus *cpu_bus = dev->link_list;
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
struct mp_params mp_params;
|
||||
uint32_t bsmrwac;
|
||||
void *default_smm_area;
|
||||
|
||||
/* Set up MTRRs based on physical address size. */
|
||||
x86_setup_fixed_mtrrs();
|
||||
x86_setup_var_mtrrs(pattrs->address_bits, 2);
|
||||
x86_mtrr_check();
|
||||
|
||||
mp_params.num_cpus = pattrs->num_cpus,
|
||||
mp_params.parallel_microcode_load = 1,
|
||||
mp_params.adjust_apic_id = adjust_apic_id;
|
||||
mp_params.flight_plan = &mp_steps[0];
|
||||
mp_params.num_records = ARRAY_SIZE(mp_steps);
|
||||
mp_params.microcode_pointer = pattrs->microcode_patch;
|
||||
|
||||
default_smm_area = backup_default_smm_area();
|
||||
|
||||
/*
|
||||
* Configure the BUNIT to allow dirty cache line evictions in non-SMM
|
||||
* mode for the lines that were dirtied while in SMM mode. Otherwise
|
||||
* the writes would be silently dropped.
|
||||
*/
|
||||
bsmrwac = iosf_bunit_read(BUNIT_SMRWAC) | SAI_IA_UNTRUSTED;
|
||||
iosf_bunit_write(BUNIT_SMRWAC, bsmrwac);
|
||||
|
||||
/* Set package MSRs */
|
||||
reg_script_run(package_msr_script);
|
||||
|
||||
/* Enable Turbo Mode on BSP and siblings of the BSP's building block. */
|
||||
enable_turbo();
|
||||
|
||||
if (mp_init(cpu_bus, &mp_params)) {
|
||||
printk(BIOS_ERR, "MP initialization failure.\n");
|
||||
}
|
||||
|
||||
restore_default_smm_area(default_smm_area);
|
||||
}
|
||||
|
||||
static void baytrail_core_init(device_t cpu)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Init BayTrail core.\n");
|
||||
|
||||
/* On bay trail the turbo disable bit is actually scoped at building
|
||||
* block level -- not package. For non-bsp cores that are within a
|
||||
* building block enable turbo. The cores within the BSP's building
|
||||
* block will just see it already enabled and move on. */
|
||||
if (lapicid())
|
||||
enable_turbo();
|
||||
|
||||
/* Set core MSRs */
|
||||
reg_script_run(core_msr_script);
|
||||
|
||||
/* Set this core to max frequency ratio */
|
||||
set_max_freq();
|
||||
}
|
||||
|
||||
static struct device_operations cpu_dev_ops = {
|
||||
.init = baytrail_core_init,
|
||||
};
|
||||
|
||||
static struct cpu_device_id cpu_table[] = {
|
||||
{ X86_VENDOR_INTEL, 0x30673 },
|
||||
{ X86_VENDOR_INTEL, 0x30678 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const struct cpu_driver driver __cpu_driver = {
|
||||
.ops = &cpu_dev_ops,
|
||||
.id_table = cpu_table,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SMM loading and initialization.
|
||||
*/
|
||||
|
||||
struct smm_relocation_attrs {
|
||||
uint32_t smbase;
|
||||
uint32_t smrr_base;
|
||||
uint32_t smrr_mask;
|
||||
};
|
||||
|
||||
static struct smm_relocation_attrs relo_attrs;
|
||||
|
||||
static void adjust_apic_id_map(struct smm_loader_params *smm_params)
|
||||
{
|
||||
int i;
|
||||
struct smm_runtime *runtime = smm_params->runtime;
|
||||
|
||||
for (i = 0; i < CONFIG_MAX_CPUS; i++)
|
||||
runtime->apic_id_to_cpu[i] = mp_get_apic_id(i);
|
||||
}
|
||||
|
||||
static void asmlinkage cpu_smm_do_relocation(void *arg)
|
||||
{
|
||||
msr_t smrr;
|
||||
em64t100_smm_state_save_area_t *smm_state;
|
||||
const struct smm_module_params *p;
|
||||
const struct smm_runtime *runtime;
|
||||
int cpu;
|
||||
|
||||
p = arg;
|
||||
runtime = p->runtime;
|
||||
cpu = p->cpu;
|
||||
|
||||
if (cpu >= CONFIG_MAX_CPUS) {
|
||||
printk(BIOS_CRIT,
|
||||
"Invalid CPU number assigned in SMM stub: %d\n", cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up SMRR. */
|
||||
smrr.lo = relo_attrs.smrr_base;
|
||||
smrr.hi = 0;
|
||||
wrmsr(SMRRphysBase_MSR, smrr);
|
||||
smrr.lo = relo_attrs.smrr_mask;
|
||||
smrr.hi = 0;
|
||||
wrmsr(SMRRphysMask_MSR, smrr);
|
||||
|
||||
/* The relocated handler runs with all CPUs concurrently. Therefore
|
||||
* stagger the entry points adjusting SMBASE downwards by save state
|
||||
* size * CPU num. */
|
||||
smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + runtime->smbase);
|
||||
smm_state->smbase = relo_attrs.smbase - cpu * runtime->save_state_size;
|
||||
printk(BIOS_DEBUG, "New SMBASE 0x%08x\n", smm_state->smbase);
|
||||
}
|
||||
|
||||
static int install_relocation_handler(int num_cpus)
|
||||
{
|
||||
const int save_state_size = sizeof(em64t100_smm_state_save_area_t);
|
||||
|
||||
struct smm_loader_params smm_params = {
|
||||
.per_cpu_stack_size = save_state_size,
|
||||
.num_concurrent_stacks = num_cpus,
|
||||
.per_cpu_save_state_size = save_state_size,
|
||||
.num_concurrent_save_states = 1,
|
||||
.handler = (smm_handler_t)&cpu_smm_do_relocation,
|
||||
};
|
||||
|
||||
if (smm_setup_relocation_handler(&smm_params))
|
||||
return -1;
|
||||
|
||||
adjust_apic_id_map(&smm_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int install_permanent_handler(int num_cpus)
|
||||
{
|
||||
/* There are num_cpus concurrent stacks and num_cpus concurrent save
|
||||
* state areas. Lastly, set the stack size to the save state size. */
|
||||
int save_state_size = sizeof(em64t100_smm_state_save_area_t);
|
||||
struct smm_loader_params smm_params = {
|
||||
.per_cpu_stack_size = save_state_size,
|
||||
.num_concurrent_stacks = num_cpus,
|
||||
.per_cpu_save_state_size = save_state_size,
|
||||
.num_concurrent_save_states = num_cpus,
|
||||
};
|
||||
const int tseg_size = smm_region_size() - CONFIG_SMM_RESERVED_SIZE;
|
||||
|
||||
printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n",
|
||||
relo_attrs.smbase);
|
||||
|
||||
if (smm_load_module((void *)relo_attrs.smbase, tseg_size, &smm_params))
|
||||
return -1;
|
||||
|
||||
adjust_apic_id_map(&smm_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smm_load_handlers(void)
|
||||
{
|
||||
/* All range registers are aligned to 4KiB */
|
||||
const uint32_t rmask = ~((1 << 12) - 1);
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
|
||||
/* Initialize global tracking state. */
|
||||
relo_attrs.smbase = (uint32_t)smm_region_start();
|
||||
relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK;
|
||||
relo_attrs.smrr_mask = ~(smm_region_size() - 1) & rmask;
|
||||
relo_attrs.smrr_mask |= MTRRphysMaskValid;
|
||||
|
||||
/* Install handlers. */
|
||||
if (install_relocation_handler(pattrs->num_cpus) < 0) {
|
||||
printk(BIOS_ERR, "Unable to install SMM relocation handler.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (install_permanent_handler(pattrs->num_cpus) < 0) {
|
||||
printk(BIOS_ERR, "Unable to install SMM permanent handler.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure the SMM handlers hit DRAM before performing first SMI. */
|
||||
wbinvd();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smm_relocate(void *unused)
|
||||
{
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
|
||||
/* Load relocation and permanent handler. */
|
||||
if (boot_cpu()) {
|
||||
if (smm_load_handlers() < 0) {
|
||||
printk(BIOS_ERR, "Error loading SMM handlers.\n");
|
||||
return;
|
||||
}
|
||||
southcluster_smm_clear_state();
|
||||
}
|
||||
|
||||
/* Relocate SMM space. */
|
||||
smm_initiate_relocation();
|
||||
|
||||
/* Load microcode after SMM relocation. */
|
||||
intel_microcode_load_unlocked(pattrs->microcode_patch);
|
||||
}
|
||||
|
||||
static void enable_smis(void *unused)
|
||||
{
|
||||
southcluster_smm_enable_smi();
|
||||
}
|
52
src/soc/intel/braswell/dptf.c
Normal file
52
src/soc/intel/braswell/dptf.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/io.h>
|
||||
#include <bootstate.h>
|
||||
#include <console/console.h>
|
||||
#include <reg_script.h>
|
||||
#include <soc/iosf.h>
|
||||
|
||||
static const struct reg_script dptf_init_settings[] = {
|
||||
/* SocThermInit */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PTMC, 0x00030708),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_GFXT, 0x0000C000),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_VEDT, 0x00000004),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_ISPT, 0x00000004),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PTPS, 0x00000000),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TE_AUX3, 0x00061029),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TTE_VRIccMax, 0x00061029),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TTE_VRHot, 0x00061029),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TTE_XXPROCHOT, 0x00061029),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TTE_SLM0, 0x00001029),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_TTE_SLM1, 0x00001029),
|
||||
/* ratio 11 = 1466mhz for mid and entry celeron */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_SOC_POWER_BUDGET, 0x00000B00),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_SOC_ENERGY_CREDIT, 0x00000002),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static void dptf_init(void *unused)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Applying SOC Thermal settings for DPTF.\n");
|
||||
reg_script_run(dptf_init_settings);
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, dptf_init, NULL);
|
181
src/soc/intel/braswell/ehci.c
Normal file
181
src/soc/intel/braswell/ehci.c
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 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/acpi.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <stdint.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/ehci.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
static const struct reg_script ehci_init_script[] = {
|
||||
/* Enable S0 PLL shutdown
|
||||
* D29:F0:7A[12,10,7,6,4,3,2,1]=11111111b */
|
||||
REG_PCI_OR16(0x7a, 0x14de),
|
||||
/* Enable SB local clock gating
|
||||
* D29:F0:7C[14,3,2]=111b (14 set in clock gating step) */
|
||||
REG_PCI_OR32(0x7c, 0x0000000c),
|
||||
REG_PCI_OR32(0x8c, 0x00000001),
|
||||
/* Enable dynamic clock gating 0x4001=0xCE */
|
||||
REG_IOSF_RMW(IOSF_PORT_USBPHY, 0x4001, 0xFFFFFF00, 0xCE),
|
||||
/* Magic RCBA register set sequence */
|
||||
/* RCBA + 0x200=0x1 */
|
||||
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x200, 0x00000001),
|
||||
/* RCBA + 0x204=0x2 */
|
||||
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x204, 0x00000002),
|
||||
/* RCBA + 0x208=0x0 */
|
||||
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x208, 0x00000000),
|
||||
/* RCBA + 0x240[4,3,2,1,0]=00000b */
|
||||
REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x240, ~0x0000001f, 0),
|
||||
/* RCBA + 0x318[9,8,6,5,4,3,2,1,0]=000000111b */
|
||||
REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x318, ~0x00000378, 0x00000007),
|
||||
/* RCBA + 0x31c[3,2,1,0]=0011b */
|
||||
REG_MMIO_RMW32(RCBA_BASE_ADDRESS + 0x31c, ~0x0000000c, 0x00000003),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static const struct reg_script ehci_clock_gating_script[] = {
|
||||
/* Enable SB local clock gating */
|
||||
REG_PCI_OR32(0x7c, 0x00004000),
|
||||
/* RCBA + 0x284=0xbe (step B0+) */
|
||||
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + 0x284, 0x000000be),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static const struct reg_script ehci_disable_script[] = {
|
||||
/* Clear Run/Stop Bit */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD, ~USB2CMD_RS, 0),
|
||||
/* Wait for HC Halted */
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, USB2STS,
|
||||
USB2STS_HCHALT, USB2STS_HCHALT, 10000),
|
||||
/* Disable Interrupts */
|
||||
REG_PCI_OR32(EHCI_CMD_STS, INTRDIS),
|
||||
/* Disable Asynchronous and Periodic Scheduler */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, USB2CMD,
|
||||
~(USB2CMD_ASE | USB2CMD_PSE), 0),
|
||||
/* Disable port wake */
|
||||
REG_PCI_RMW32(EHCI_SBRN_FLA_PWC, ~(PORTWKIMP | PORTWKCAPMASK), 0),
|
||||
/* Set Function Disable bit in RCBA */
|
||||
REG_MMIO_OR32(RCBA_BASE_ADDRESS + RCBA_FUNC_DIS, RCBA_EHCI_DIS),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static const struct reg_script ehci_hc_reset[] = {
|
||||
REG_RES_OR16(PCI_BASE_ADDRESS_0, USB2CMD, USB2CMD_HCRESET),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static void usb2_phy_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
u32 usb2_comp_bg = (config->usb2_comp_bg == 0 ?
|
||||
0x4700 : config->usb2_comp_bg);
|
||||
struct reg_script usb2_phy_script[] = {
|
||||
/* USB3PHYInit() */
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_COMPBG,
|
||||
usb2_comp_bg),
|
||||
/* Per port phy settings, set in devicetree.cb */
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE0,
|
||||
config->usb2_per_port_lane0),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY,
|
||||
USBPHY_PER_PORT_RCOMP_HS_PULLUP0,
|
||||
config->usb2_per_port_rcomp_hs_pullup0),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE1,
|
||||
config->usb2_per_port_lane1),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY,
|
||||
USBPHY_PER_PORT_RCOMP_HS_PULLUP1,
|
||||
config->usb2_per_port_rcomp_hs_pullup1),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE2,
|
||||
config->usb2_per_port_lane2),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY,
|
||||
USBPHY_PER_PORT_RCOMP_HS_PULLUP2,
|
||||
config->usb2_per_port_rcomp_hs_pullup2),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY, USBPHY_PER_PORT_LANE3,
|
||||
config->usb2_per_port_lane3),
|
||||
REG_IOSF_WRITE(IOSF_PORT_USBPHY,
|
||||
USBPHY_PER_PORT_RCOMP_HS_PULLUP3,
|
||||
config->usb2_per_port_rcomp_hs_pullup3),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
reg_script_run(usb2_phy_script);
|
||||
}
|
||||
|
||||
static void ehci_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
struct reg_script ehci_hc_init[] = {
|
||||
/* Controller init */
|
||||
REG_SCRIPT_NEXT(ehci_init_script),
|
||||
/* Enable clock gating */
|
||||
REG_SCRIPT_NEXT(ehci_clock_gating_script),
|
||||
/*
|
||||
* Disable ports if requested
|
||||
*/
|
||||
/* Open per-port disable control override */
|
||||
REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~0, UPRWC_WR_EN),
|
||||
REG_PCI_WRITE8(EHCI_USB2PDO, config->usb2_port_disable_mask),
|
||||
/* Close per-port disable control override */
|
||||
REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~UPRWC_WR_EN, 0),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
/* Don't reset controller in S3 resume path */
|
||||
if (!acpi_is_wakeup_s3())
|
||||
reg_script_run_on_dev(dev, ehci_hc_reset);
|
||||
|
||||
/* Disable controller if ports are routed to XHCI */
|
||||
if (config->usb_route_to_xhci) {
|
||||
/* Disable controller */
|
||||
reg_script_run_on_dev(dev, ehci_disable_script);
|
||||
|
||||
/* Hide device with southcluster function */
|
||||
dev->enabled = 0;
|
||||
southcluster_enable_dev(dev);
|
||||
} else {
|
||||
/* Initialize EHCI controller */
|
||||
reg_script_run_on_dev(dev, ehci_hc_init);
|
||||
}
|
||||
|
||||
/* Setup USB2 PHY based on board config */
|
||||
usb2_phy_init(dev);
|
||||
}
|
||||
|
||||
static struct device_operations ehci_device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = ehci_init,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver baytrail_ehci __pci_driver = {
|
||||
.ops = &ehci_device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = EHCI_DEVID
|
||||
};
|
122
src/soc/intel/braswell/elog.c
Normal file
122
src/soc/intel/braswell/elog.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <stdint.h>
|
||||
#include <console/console.h>
|
||||
#include <cbmem.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <elog.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/pmc.h>
|
||||
|
||||
static void log_power_and_resets(const struct chipset_power_state *ps)
|
||||
{
|
||||
if (ps->gen_pmcon1 & PWR_FLR) {
|
||||
elog_add_event(ELOG_TYPE_POWER_FAIL);
|
||||
elog_add_event(ELOG_TYPE_PWROK_FAIL);
|
||||
}
|
||||
|
||||
if (ps->gen_pmcon1 & SUS_PWR_FLR) {
|
||||
elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
|
||||
}
|
||||
|
||||
if (ps->gen_pmcon1 & RPS) {
|
||||
elog_add_event(ELOG_TYPE_RTC_RESET);
|
||||
}
|
||||
|
||||
if (ps->tco_sts & SECOND_TO_STS) {
|
||||
elog_add_event(ELOG_TYPE_TCO_RESET);
|
||||
}
|
||||
|
||||
if (ps->pm1_sts & PRBTNOR_STS) {
|
||||
elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
|
||||
}
|
||||
|
||||
if (ps->gen_pmcon1 & SRS) {
|
||||
elog_add_event(ELOG_TYPE_RESET_BUTTON);
|
||||
}
|
||||
|
||||
if (ps->gen_pmcon1 & GEN_RST_STS) {
|
||||
elog_add_event(ELOG_TYPE_SYSTEM_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_wake_events(const struct chipset_power_state *ps)
|
||||
{
|
||||
const uint32_t pcie_wake_mask = PCI_EXP_STS | PCIE_WAKE3_STS |
|
||||
PCIE_WAKE2_STS | PCIE_WAKE1_STS |
|
||||
PCIE_WAKE0_STS;
|
||||
uint32_t gpe0_sts;
|
||||
uint32_t gpio_mask;
|
||||
int i;
|
||||
|
||||
/* Mask off disabled events. */
|
||||
gpe0_sts = ps->gpe0_sts & ps->gpe0_en;
|
||||
|
||||
if (ps->pm1_sts & WAK_STS) {
|
||||
elog_add_event_byte(ELOG_TYPE_ACPI_WAKE,
|
||||
acpi_is_wakeup_s3() ? 3 : 5);
|
||||
}
|
||||
|
||||
if (ps->pm1_sts & PWRBTN_STS) {
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
|
||||
}
|
||||
|
||||
if (ps->pm1_sts & RTC_STS) {
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
|
||||
}
|
||||
|
||||
if (gpe0_sts & PME_B0_EN) {
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
|
||||
}
|
||||
|
||||
if (gpe0_sts & pcie_wake_mask) {
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
|
||||
}
|
||||
|
||||
gpio_mask = SUS_GPIO_STS0;
|
||||
i = 0;
|
||||
while (gpio_mask) {
|
||||
if (gpio_mask & gpe0_sts) {
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i);
|
||||
}
|
||||
gpio_mask <<= 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void southcluster_log_state(void)
|
||||
{
|
||||
struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
|
||||
|
||||
if (ps == NULL) {
|
||||
printk(BIOS_DEBUG, "Not logging power state information. "
|
||||
"Power state not found in cbmem.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
log_power_and_resets(ps);
|
||||
log_wake_events(ps);
|
||||
}
|
77
src/soc/intel/braswell/emmc.c
Normal file
77
src/soc/intel/braswell/emmc.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include "chip.h"
|
||||
|
||||
static const struct reg_script emmc_ops[] = {
|
||||
/* Enable 2ms card stable feature. */
|
||||
REG_PCI_OR32(0xa8, (1 << 24)),
|
||||
/* Enable HS200 */
|
||||
REG_PCI_WRITE32(0xa0, 0x446cc801),
|
||||
REG_PCI_WRITE32(0xa4, 0x80000807),
|
||||
/* cfio_regs_score_special_bits.sdio1_dummy_loopback_en=1 */
|
||||
REG_IOSF_OR(IOSF_PORT_SCORE, 0x49c0, (1 << 3)),
|
||||
/* CLKGATE_EN_1 . cr_scc_mipihsi_clkgate_en = 1 */
|
||||
REG_IOSF_RMW(IOSF_PORT_CCU, 0x1c, ~(3 << 26), (1 << 26)),
|
||||
/* Set slew for HS200 */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c0, ~0x3c, 0x3c),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c4, ~0x3c, 0x3c),
|
||||
/* Max timeout */
|
||||
REG_RES_WRITE8(PCI_BASE_ADDRESS_0, 0x002e, 0x0e),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static void emmc_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
|
||||
printk(BIOS_DEBUG, "eMMC init\n");
|
||||
reg_script_run_on_dev(dev, emmc_ops);
|
||||
|
||||
if (config->scc_acpi_mode)
|
||||
scc_enable_acpi_mode(dev, SCC_MMC_CTL, SCC_NVS_MMC);
|
||||
}
|
||||
|
||||
static struct device_operations device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = emmc_init,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = MMC_DEVID,
|
||||
};
|
398
src/soc/intel/braswell/gfx.c
Normal file
398
src/soc/intel/braswell/gfx.c
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 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 <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <soc/gfx.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
#define GFX_TIMEOUT 100000 /* 100ms */
|
||||
|
||||
/*
|
||||
* Lock Power Context Base Register to point to a 24KB block
|
||||
* of memory in GSM. Power context save data is stored here.
|
||||
*/
|
||||
static void gfx_lock_pcbase(device_t dev)
|
||||
{
|
||||
struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
const u16 gms_size_map[17] = { 0,32,64,96,128,160,192,224,256,
|
||||
288,320,352,384,416,448,480,512 };
|
||||
u32 pcsize = 24 << 10; /* 24KB */
|
||||
u32 wopcmsz = 0x100000; /* PAVP offset */
|
||||
u32 gms, gmsize, pcbase;
|
||||
|
||||
gms = pci_read_config32(dev, GGC) & GGC_GSM_SIZE_MASK;
|
||||
gms >>= 3;
|
||||
if (gms > ARRAY_SIZE(gms_size_map))
|
||||
return;
|
||||
gmsize = gms_size_map[gms];
|
||||
|
||||
/* PcBase = BDSM + GMS Size - WOPCMSZ - PowerContextSize */
|
||||
pcbase = pci_read_config32(dev, GSM_BASE) & 0xfff00000;
|
||||
pcbase += (gmsize-1) * wopcmsz - pcsize;
|
||||
pcbase |= 1; /* Lock */
|
||||
|
||||
write32((u32 *)(uintptr_t)(res->base + 0x182120), pcbase);
|
||||
}
|
||||
|
||||
static const struct reg_script gfx_init_script[] = {
|
||||
/* Allow-Wake render/media wells */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x130090, ~1, 1),
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x130094, 1, 1, GFX_TIMEOUT),
|
||||
/* Render Force-Wake */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1300b0, 0x80008000),
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x1300b4, 0x8000, 0x8000,
|
||||
GFX_TIMEOUT),
|
||||
/* Media Force-Wake */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1300b8, 0x80008000),
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x1300bc, 0x8000, 0x8000,
|
||||
GFX_TIMEOUT),
|
||||
/* Workaround - X0:261954/A0:261955 */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x182060, ~0xf, 1),
|
||||
|
||||
/*
|
||||
* PowerMeter Weights
|
||||
*/
|
||||
|
||||
/* SET1 */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA800, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA804, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA808, 0x0000ff0A),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA80C, 0x1D000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA810, 0xAC004900),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA814, 0x000F0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA818, 0x5A000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA81C, 0x2600001F),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA820, 0x00090000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA824, 0x2000ff00),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA828, 0xff090016),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA82C, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA830, 0x00000100),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA834, 0x00A00F51),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA838, 0x000B0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA83C, 0xcb7D3307),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA840, 0x003C0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA844, 0xFFFF0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA848, 0x00220000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA84c, 0x43000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA850, 0x00000800),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA854, 0x00000F00),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA858, 0x00000021),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA85c, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA860, 0x00190000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xAA80, 0x00FF00FF),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xAA84, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x1300A4, 0x00000000),
|
||||
/* SET2 */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA900, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA904, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA908, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa90c, 0x1D000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa910, 0xAC005000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa914, 0x000F0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa918, 0x5A000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa91c, 0x2600001F),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa920, 0x00090000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa924, 0x2000ff00),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa928, 0xff090016),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa92c, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa930, 0x00000100),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa934, 0x00A00F51),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xa938, 0x000B0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA93C, 0xcb7D3307),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA940, 0x003C0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA944, 0xFFFF0000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA948, 0x00220000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA94C, 0x43000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA950, 0x00000800),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA954, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA960, 0x00000000),
|
||||
/* SET3 */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xaa3c, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xaa54, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xaa60, 0x00000000),
|
||||
/* Enable PowerMeter Counters */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA248, 0x00000058),
|
||||
|
||||
/* Program PUNIT_GPU_EC_VIRUS based on DPTF SDP */
|
||||
/* SDP Profile 4 == 0x11940, others 0xcf08 */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_GPU_EC_VIRUS, 0xcf08),
|
||||
|
||||
/* GfxPause */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa000, 0x00071388),
|
||||
|
||||
/* Dynamic EU Control Settings */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa080, 0x00000004),
|
||||
|
||||
/* Lock ECO Bit Settings */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa180, 0x80000000),
|
||||
|
||||
/* DOP Clock Gating */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9424, 0x00000001),
|
||||
|
||||
/* MBCunit will send the VCR (Fuse) writes as NP-W */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x907c, 0xfffeffff, 0x00010000),
|
||||
|
||||
/*
|
||||
* RC6 Settings
|
||||
*/
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA090, 0x00000000),
|
||||
/* RC1e - RC6/6p - RC6pp Wake Rate Limits */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA09C, 0x00280000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA0A8, 0x0001E848),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA0AC, 0x00000019),
|
||||
/* RC Sleep / RCx Thresholds */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA0B0, 0x00000000),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA0B8, 0x00000557),
|
||||
|
||||
/*
|
||||
* Turbo Settings
|
||||
*/
|
||||
|
||||
/* Render/Video/Blitter Idle Max Count */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x2054, 0x0000000A),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x12054, 0x0000000A),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x22054, 0x0000000A),
|
||||
/* RP Down Timeout */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA010, 0x000F4240),
|
||||
|
||||
/*
|
||||
* Turbo Control Settings
|
||||
*/
|
||||
|
||||
/* RP Up/Down Threshold */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA02C, 0x0000E8E8),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA030, 0x0003BD08),
|
||||
/* RP Up/Down EI */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA068, 0x000101D0),
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0xA06C, 0x00055730),
|
||||
|
||||
/* RP Idle Hysteresis */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa070, 0x0000000a),
|
||||
|
||||
/* HW RC6 Control Settings */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa090, 0x11000000),
|
||||
|
||||
/* RP Control */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa024, 0x00000592),
|
||||
|
||||
/* Enable PM Interrupts */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x44024, 0x03000000),
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x4402c, 0x03000076),
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0xa168, 0x0000007e),
|
||||
|
||||
/* Aggressive Clock Gating */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9400, 0),
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9404, 0),
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x9408, 0),
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x940c, 0),
|
||||
|
||||
/* Enable Gfx Turbo. */
|
||||
REG_IOSF_RMW(IOSF_PORT_PMC, SB_BIOS_CONFIG,
|
||||
~SB_BIOS_CONFIG_GFX_TURBO_DIS, 0),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static const struct reg_script gpu_pre_vbios_script[] = {
|
||||
/* Make sure GFX is bus master with MMIO access */
|
||||
REG_PCI_OR32(PCI_COMMAND, PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY),
|
||||
/* Display */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xc0),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xc0, 0xc0,
|
||||
GFX_TIMEOUT),
|
||||
/* Tx/Rx Lanes */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xfff0c0),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xfff0c0, 0xfff0c0,
|
||||
GFX_TIMEOUT),
|
||||
/* Common Lane */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xfffcc0),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xfffcc0, 0xfffcc0,
|
||||
GFX_TIMEOUT),
|
||||
/* Ungating Tx only */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xf00cc0),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xfffcc0, 0xf00cc0,
|
||||
GFX_TIMEOUT),
|
||||
/* Ungating Common Lane only */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xf000c0),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xffffc0, 0xf000c0,
|
||||
GFX_TIMEOUT),
|
||||
/* Ungating Display */
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xf00000),
|
||||
REG_IOSF_POLL(IOSF_PORT_PMC, PUNIT_PWRGT_STATUS, 0xfffff0, 0xf00000,
|
||||
GFX_TIMEOUT),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static const struct reg_script gfx_post_vbios_script[] = {
|
||||
/* Deassert Render Force-Wake */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1300b0, 0x80000000),
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x1300b4, 0x8000, 0, GFX_TIMEOUT),
|
||||
/* Deassert Media Force-Wake */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x1300b8, 0x80000000),
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, 0x1300bc, 0x8000, 0, GFX_TIMEOUT),
|
||||
/* Set Lock bits */
|
||||
REG_PCI_RMW32(GGC, 0xffffffff, 1),
|
||||
REG_PCI_RMW32(GSM_BASE, 0xffffffff, 1),
|
||||
REG_PCI_RMW32(GTT_BASE, 0xffffffff, 1),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
static inline void gfx_run_script(device_t dev, const struct reg_script *ops)
|
||||
{
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
}
|
||||
|
||||
static void gfx_pre_vbios_init(device_t dev)
|
||||
{
|
||||
printk(BIOS_INFO, "GFX: Pre VBIOS Init\n");
|
||||
gfx_run_script(dev, gpu_pre_vbios_script);
|
||||
}
|
||||
|
||||
static void gfx_pm_init(device_t dev)
|
||||
{
|
||||
printk(BIOS_INFO, "GFX: Power Management Init\n");
|
||||
gfx_run_script(dev, gfx_init_script);
|
||||
|
||||
/* Lock power context base */
|
||||
gfx_lock_pcbase(dev);
|
||||
}
|
||||
|
||||
static void gfx_post_vbios_init(device_t dev)
|
||||
{
|
||||
printk(BIOS_INFO, "GFX: Post VBIOS Init\n");
|
||||
gfx_run_script(dev, gfx_post_vbios_script);
|
||||
}
|
||||
|
||||
static void set_backlight_pwm(device_t dev, uint32_t bklt_reg, int req_hz)
|
||||
{
|
||||
int divider;
|
||||
struct resource *res;
|
||||
|
||||
res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
/* Default to 200 Hz if nothing is set. */
|
||||
if (req_hz == 0)
|
||||
req_hz = 200;
|
||||
|
||||
/* Base clock is 25MHz */
|
||||
divider = 25 * 1000 * 1000 / (16 * req_hz);
|
||||
|
||||
/* Do not set duty cycle (lower 16 bits). Just set the divider. */
|
||||
write32((u32 *)(uintptr_t)(res->base + bklt_reg), divider << 16);
|
||||
}
|
||||
|
||||
static void gfx_panel_setup(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
struct reg_script gfx_pipea_init[] = {
|
||||
/* CONTROL */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEA_REG(PP_CONTROL),
|
||||
PP_CONTROL_UNLOCK | PP_CONTROL_EDP_FORCE_VDD),
|
||||
/* POWER ON */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEA_REG(PP_ON_DELAYS),
|
||||
(config->gpu_pipea_port_select << 30 |
|
||||
config->gpu_pipea_power_on_delay << 16 |
|
||||
config->gpu_pipea_light_on_delay)),
|
||||
/* POWER OFF */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEA_REG(PP_OFF_DELAYS),
|
||||
(config->gpu_pipea_power_off_delay << 16 |
|
||||
config->gpu_pipea_light_off_delay)),
|
||||
/* DIVISOR */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, PIPEA_REG(PP_DIVISOR),
|
||||
~0x1f, config->gpu_pipea_power_cycle_delay),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
struct reg_script gfx_pipeb_init[] = {
|
||||
/* CONTROL */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEB_REG(PP_CONTROL),
|
||||
PP_CONTROL_UNLOCK | PP_CONTROL_EDP_FORCE_VDD),
|
||||
/* POWER ON */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEB_REG(PP_ON_DELAYS),
|
||||
(config->gpu_pipeb_port_select << 30 |
|
||||
config->gpu_pipeb_power_on_delay << 16 |
|
||||
config->gpu_pipeb_light_on_delay)),
|
||||
/* POWER OFF */
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, PIPEB_REG(PP_OFF_DELAYS),
|
||||
(config->gpu_pipeb_power_off_delay << 16 |
|
||||
config->gpu_pipeb_light_off_delay)),
|
||||
/* DIVISOR */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, PIPEB_REG(PP_DIVISOR),
|
||||
~0x1f, config->gpu_pipeb_power_cycle_delay),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
if (config->gpu_pipea_port_select) {
|
||||
printk(BIOS_INFO, "GFX: Initialize PIPEA\n");
|
||||
reg_script_run_on_dev(dev, gfx_pipea_init);
|
||||
set_backlight_pwm(dev, PIPEA_REG(BACKLIGHT_CTL),
|
||||
config->gpu_pipea_pwm_freq_hz);
|
||||
}
|
||||
|
||||
if (config->gpu_pipeb_port_select) {
|
||||
printk(BIOS_INFO, "GFX: Initialize PIPEB\n");
|
||||
reg_script_run_on_dev(dev, gfx_pipeb_init);
|
||||
set_backlight_pwm(dev, PIPEB_REG(BACKLIGHT_CTL),
|
||||
config->gpu_pipeb_pwm_freq_hz);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_init(device_t dev)
|
||||
{
|
||||
/* Pre VBIOS Init */
|
||||
gfx_pre_vbios_init(dev);
|
||||
|
||||
/* Power Management Init */
|
||||
gfx_pm_init(dev);
|
||||
|
||||
gfx_panel_setup(dev);
|
||||
|
||||
/* Run VBIOS */
|
||||
pci_dev_init(dev);
|
||||
|
||||
/* Post VBIOS Init */
|
||||
gfx_post_vbios_init(dev);
|
||||
}
|
||||
|
||||
static struct device_operations gfx_device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = gfx_init,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver gfx_driver __pci_driver = {
|
||||
.ops = &gfx_device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = GFX_DEVID,
|
||||
};
|
245
src/soc/intel/braswell/gpio.c
Normal file
245
src/soc/intel/braswell/gpio.c
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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 <device/pci.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
/* GPIO-to-Pad LUTs */
|
||||
static const u8 gpncore_gpio_to_pad[GPNCORE_COUNT] =
|
||||
{ 19, 18, 17, 20, 21, 22, 24, 25, /* [ 0: 7] */
|
||||
23, 16, 14, 15, 12, 26, 27, 1, /* [ 8:15] */
|
||||
4, 8, 11, 0, 3, 6, 10, 13, /* [16:23] */
|
||||
2, 5, 9 }; /* [24:26] */
|
||||
|
||||
static const u8 gpscore_gpio_to_pad[GPSCORE_COUNT] =
|
||||
{ 85, 89, 93, 96, 99, 102, 98, 101, /* [ 0: 7] */
|
||||
34, 37, 36, 38, 39, 35, 40, 84, /* [ 8: 15] */
|
||||
62, 61, 64, 59, 54, 56, 60, 55, /* [16: 23] */
|
||||
63, 57, 51, 50, 53, 47, 52, 49, /* [24: 31] */
|
||||
48, 43, 46, 41, 45, 42, 58, 44, /* [32: 39] */
|
||||
95, 105, 70, 68, 67, 66, 69, 71, /* [40: 47] */
|
||||
65, 72, 86, 90, 88, 92, 103, 77, /* [48: 55] */
|
||||
79, 83, 78, 81, 80, 82, 13, 12, /* [56: 63] */
|
||||
15, 14, 17, 18, 19, 16, 2, 1, /* [64: 71] */
|
||||
0, 4, 6, 7, 9, 8, 33, 32, /* [72: 79] */
|
||||
31, 30, 29, 27, 25, 28, 26, 23, /* [80: 87] */
|
||||
21, 20, 24, 22, 5, 3, 10, 11, /* [88: 95] */
|
||||
106, 87, 91, 104, 97, 100 }; /* [96:101] */
|
||||
|
||||
static const u8 gpssus_gpio_to_pad[GPSSUS_COUNT] =
|
||||
{ 29, 33, 30, 31, 32, 34, 36, 35, /* [ 0: 7] */
|
||||
38, 37, 18, 7, 11, 20, 17, 1, /* [ 8:15] */
|
||||
8, 10, 19, 12, 0, 2, 23, 39, /* [16:23] */
|
||||
28, 27, 22, 21, 24, 25, 26, 51, /* [24:31] */
|
||||
56, 54, 49, 55, 48, 57, 50, 58, /* [32:39] */
|
||||
52, 53, 59, 40 }; /* [40:43] */
|
||||
|
||||
/* GPIO bank descriptions */
|
||||
static const struct gpio_bank gpncore_bank = {
|
||||
.gpio_count = GPNCORE_COUNT,
|
||||
.gpio_to_pad = gpncore_gpio_to_pad,
|
||||
.legacy_base = GP_LEGACY_BASE_NONE,
|
||||
.pad_base = GPNCORE_PAD_BASE,
|
||||
.has_wake_en = 0,
|
||||
.gpio_f1_range_start = GPNCORE_GPIO_F1_RANGE_START,
|
||||
.gpio_f1_range_end = GPNCORE_GPIO_F1_RANGE_END,
|
||||
};
|
||||
|
||||
static const struct gpio_bank gpscore_bank = {
|
||||
.gpio_count = GPSCORE_COUNT,
|
||||
.gpio_to_pad = gpscore_gpio_to_pad,
|
||||
.legacy_base = GPSCORE_LEGACY_BASE,
|
||||
.pad_base = GPSCORE_PAD_BASE,
|
||||
.has_wake_en = 0,
|
||||
.gpio_f1_range_start = GPSCORE_GPIO_F1_RANGE_START,
|
||||
.gpio_f1_range_end = GPSCORE_GPIO_F1_RANGE_END,
|
||||
};
|
||||
|
||||
static const struct gpio_bank gpssus_bank = {
|
||||
.gpio_count = GPSSUS_COUNT,
|
||||
.gpio_to_pad = gpssus_gpio_to_pad,
|
||||
.legacy_base = GPSSUS_LEGACY_BASE,
|
||||
.pad_base = GPSSUS_PAD_BASE,
|
||||
.has_wake_en = 1,
|
||||
.gpio_f1_range_start = GPSSUS_GPIO_F1_RANGE_START,
|
||||
.gpio_f1_range_end = GPSSUS_GPIO_F1_RANGE_END,
|
||||
};
|
||||
|
||||
static void setup_gpios(const struct soc_gpio_map *gpios,
|
||||
const struct gpio_bank *bank)
|
||||
{
|
||||
const struct soc_gpio_map *config;
|
||||
int gpio = 0;
|
||||
u32 reg, pad_conf0;
|
||||
u8 set, bit;
|
||||
|
||||
u32 use_sel[4] = {0};
|
||||
u32 io_sel[4] = {0};
|
||||
u32 gp_lvl[4] = {0};
|
||||
u32 tpe[4] = {0};
|
||||
u32 tne[4] = {0};
|
||||
u32 wake_en[4] = {0};
|
||||
|
||||
if (!gpios)
|
||||
return;
|
||||
|
||||
for (config = gpios; config->pad_conf0 != GPIO_LIST_END;
|
||||
config++, gpio++) {
|
||||
if (gpio > bank->gpio_count)
|
||||
break;
|
||||
|
||||
set = gpio >> 5;
|
||||
bit = gpio % 32;
|
||||
|
||||
if (bank->legacy_base != GP_LEGACY_BASE_NONE) {
|
||||
/* Legacy IO configuration */
|
||||
use_sel[set] |= config->use_sel << bit;
|
||||
io_sel[set] |= config->io_sel << bit;
|
||||
gp_lvl[set] |= config->gp_lvl << bit;
|
||||
tpe[set] |= config->tpe << bit;
|
||||
tne[set] |= config->tne << bit;
|
||||
|
||||
/* Some banks do not have wake_en ability */
|
||||
if (bank->has_wake_en)
|
||||
wake_en[set] |= config->wake_en << bit;
|
||||
}
|
||||
|
||||
/* Pad configuration registers */
|
||||
reg = bank->pad_base + 16 * bank->gpio_to_pad[gpio];
|
||||
|
||||
/* Add correct func to GPIO pad config */
|
||||
pad_conf0 = config->pad_conf0;
|
||||
if (config->is_gpio)
|
||||
{
|
||||
if (gpio >= bank->gpio_f1_range_start &&
|
||||
gpio <= bank->gpio_f1_range_end)
|
||||
pad_conf0 |= PAD_FUNC1;
|
||||
else
|
||||
pad_conf0 |= PAD_FUNC0;
|
||||
}
|
||||
|
||||
#ifdef GPIO_DEBUG
|
||||
printk(BIOS_DEBUG, "Write Pad: Base(%x) - %x %x %x\n",
|
||||
reg, pad_conf0, config->pad_conf1, config->pad_val);
|
||||
#endif
|
||||
|
||||
write32((u32 *)(reg + PAD_CONF0_REG), pad_conf0);
|
||||
write32((u32 *)(reg + PAD_CONF1_REG), config->pad_conf1);
|
||||
write32((u32 *)(reg + PAD_VAL_REG), config->pad_val);
|
||||
}
|
||||
|
||||
if (bank->legacy_base != GP_LEGACY_BASE_NONE)
|
||||
for (set = 0; set <= (bank->gpio_count - 1) / 32; ++set) {
|
||||
reg = bank->legacy_base + 0x20 * set;
|
||||
|
||||
#ifdef GPIO_DEBUG
|
||||
printk(BIOS_DEBUG,
|
||||
"Write GPIO: Reg(%x) - %x %x %x %x %x\n",
|
||||
reg, use_sel[set], io_sel[set], gp_lvl[set],
|
||||
tpe[set], tne[set]);
|
||||
#endif
|
||||
|
||||
outl(use_sel[set], reg + LEGACY_USE_SEL_REG);
|
||||
outl(io_sel[set], reg + LEGACY_IO_SEL_REG);
|
||||
outl(gp_lvl[set], reg + LEGACY_GP_LVL_REG);
|
||||
outl(tpe[set], reg + LEGACY_TPE_REG);
|
||||
outl(tne[set], reg + LEGACY_TNE_REG);
|
||||
|
||||
/* TS registers are WOC */
|
||||
outl(0, reg + LEGACY_TS_REG);
|
||||
|
||||
if (bank->has_wake_en)
|
||||
outl(wake_en[set], reg + LEGACY_WAKE_EN_REG);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_gpio_route(const struct soc_gpio_map *sus,
|
||||
const struct soc_gpio_map *core)
|
||||
{
|
||||
uint32_t route_reg = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* SMI takes precedence and wake_en implies SCI. */
|
||||
if (sus[i].smi) {
|
||||
route_reg |= ROUTE_SMI << (2 * i);
|
||||
} else if (sus[i].sci) {
|
||||
route_reg |= ROUTE_SCI << (2 * i);
|
||||
}
|
||||
|
||||
if (core[i].smi) {
|
||||
route_reg |= ROUTE_SMI << (2 * (i + 8));
|
||||
} else if (core[i].sci) {
|
||||
route_reg |= ROUTE_SCI << (2 * (i + 8));
|
||||
}
|
||||
}
|
||||
southcluster_smm_save_param(SMM_SAVE_PARAM_GPIO_ROUTE, route_reg);
|
||||
}
|
||||
|
||||
static void setup_dirqs(const u8 dirq[GPIO_MAX_DIRQS],
|
||||
const struct gpio_bank *bank)
|
||||
{
|
||||
u32 *reg = (u32 *)(bank->pad_base + PAD_BASE_DIRQ_OFFSET);
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
/* Write all four DIRQ registers */
|
||||
for (i=0; i<4; ++i) {
|
||||
val = dirq[i * 4 + 3] << 24 | dirq[i * 4 + 2] << 16 |
|
||||
dirq[i * 4 + 1] << 8 | dirq[i * 4];
|
||||
write32(reg + i, val);
|
||||
#ifdef GPIO_DEBUG
|
||||
printk(BIOS_DEBUG, "Write DIRQ reg(%x) - %x\n",
|
||||
reg + i, val);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setup_soc_gpios(struct soc_gpio_config *config, u8 enable_xdp_tap)
|
||||
{
|
||||
if (config) {
|
||||
setup_gpios(config->ncore, &gpncore_bank);
|
||||
setup_gpios(config->score, &gpscore_bank);
|
||||
setup_gpios(config->ssus, &gpssus_bank);
|
||||
setup_gpio_route(config->ssus, config->score);
|
||||
|
||||
if (config->core_dirq)
|
||||
setup_dirqs(*config->core_dirq, &gpscore_bank);
|
||||
if (config->sus_dirq)
|
||||
setup_dirqs(*config->sus_dirq, &gpssus_bank);
|
||||
}
|
||||
|
||||
/* Set on die termination feature with pull up value and
|
||||
* drive the pad high for TAP_TDO and TAP_TMS
|
||||
*/
|
||||
if (!enable_xdp_tap) {
|
||||
printk(BIOS_DEBUG, "Tri-state TDO and TMS\n");
|
||||
write32((u32 *)(GPSSUS_PAD_BASE + 0x2fc), 0xc);
|
||||
write32((u32 *)(GPSSUS_PAD_BASE + 0x2cc), 0xc);
|
||||
}
|
||||
}
|
||||
|
||||
struct soc_gpio_config* __attribute__((weak)) mainboard_get_gpios(void)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Default/empty GPIO config\n");
|
||||
return NULL;
|
||||
}
|
118
src/soc/intel/braswell/hda.c
Normal file
118
src/soc/intel/braswell/hda.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/intel/common/hda_verb.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
|
||||
static const struct reg_script init_ops[] = {
|
||||
/* Enable no snoop traffic. */
|
||||
REG_PCI_OR16(0x78, 1 << 11),
|
||||
/* Configure HDMI codec connection. */
|
||||
REG_PCI_OR32(0xc4, 1 << 1),
|
||||
REG_PCI_OR8(0x43, (1 << 3) | (1 << 6)),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0xc0),
|
||||
REG_IOSF_WRITE(IOSF_PORT_PMC, PUNIT_PWRGT_CONTROL, 0x00),
|
||||
/* Configure internal settings. */
|
||||
REG_PCI_OR32(0xc0, 0x7 << 21),
|
||||
REG_PCI_OR32(0xc4, (0x3 << 26) | (1 << 13) | (1 << 10)),
|
||||
REG_PCI_WRITE32(0xc8, 0x82a30000),
|
||||
REG_PCI_RMW32(0xd0, ~(1 << 31), 0x0),
|
||||
/* Disable docking. */
|
||||
REG_PCI_RMW8(0x4d, ~(1 << 7), 0),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static const uint32_t hdmi_codec_verb_table[] = {
|
||||
/* coreboot specific header */
|
||||
0x80862882, /* vid did for hdmi codec */
|
||||
0x00000000, /* subsystem id */
|
||||
0x00000003, /* number of jacks */
|
||||
|
||||
/* pin widget 5 - port B */
|
||||
0x20471c10,
|
||||
0x20471d00,
|
||||
0x20471e56,
|
||||
0x20471f18,
|
||||
|
||||
/* pin widget 6 - port C */
|
||||
0x20571c20,
|
||||
0x20571d00,
|
||||
0x20571e56,
|
||||
0x20571f18,
|
||||
|
||||
/* pin widget 7 - port D */
|
||||
0x20671c30,
|
||||
0x20671d00,
|
||||
0x20671e56,
|
||||
0x20671f58,
|
||||
};
|
||||
|
||||
static void hda_init(device_t dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int codec_mask;
|
||||
int i;
|
||||
u8 *base;
|
||||
|
||||
reg_script_run_on_dev(dev, init_ops);
|
||||
|
||||
res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
base = res2mmio(res, 0, 0);
|
||||
codec_mask = hda_codec_detect(base);
|
||||
|
||||
printk(BIOS_DEBUG, "codec mask = %x\n", codec_mask);
|
||||
if (!codec_mask)
|
||||
return;
|
||||
|
||||
for (i = 3; i >= 0; i--) {
|
||||
if (!((1 << i) & codec_mask))
|
||||
continue;
|
||||
hda_codec_init(base, i, sizeof(hdmi_codec_verb_table),
|
||||
hdmi_codec_verb_table);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct device_operations device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = hda_init,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = HDA_DEVID,
|
||||
};
|
31
src/soc/intel/braswell/include/soc/acpi.h
Normal file
31
src/soc/intel/braswell/include/soc/acpi.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_ACPI_H_
|
||||
#define _BAYTRAIL_ACPI_H_
|
||||
|
||||
#include <arch/acpi.h>
|
||||
#include <soc/nvs.h>
|
||||
|
||||
void acpi_create_intel_hpet(acpi_hpet_t * hpet);
|
||||
void acpi_fill_in_fadt(acpi_fadt_t *fadt);
|
||||
unsigned long acpi_madt_irq_overrides(unsigned long current);
|
||||
void acpi_init_gnvs(global_nvs_t *gnvs);
|
||||
|
||||
#endif /* _BAYTRAIL_ACPI_H_ */
|
68
src/soc/intel/braswell/include/soc/device_nvs.h
Normal file
68
src/soc/intel/braswell/include/soc/device_nvs.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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_DEVICE_NVS_H_
|
||||
#define _BAYTRAIL_DEVICE_NVS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Offset in Global NVS where this structure lives */
|
||||
#define DEVICE_NVS_OFFSET 0x1000
|
||||
|
||||
#define LPSS_NVS_SIO_DMA1 0
|
||||
#define LPSS_NVS_I2C1 1
|
||||
#define LPSS_NVS_I2C2 2
|
||||
#define LPSS_NVS_I2C3 3
|
||||
#define LPSS_NVS_I2C4 4
|
||||
#define LPSS_NVS_I2C5 5
|
||||
#define LPSS_NVS_I2C6 6
|
||||
#define LPSS_NVS_I2C7 7
|
||||
#define LPSS_NVS_SIO_DMA2 8
|
||||
#define LPSS_NVS_SPI 9
|
||||
#define LPSS_NVS_PWM1 10
|
||||
#define LPSS_NVS_PWM2 11
|
||||
#define LPSS_NVS_HSUART1 12
|
||||
#define LPSS_NVS_HSUART2 13
|
||||
|
||||
#define SCC_NVS_MMC 0
|
||||
#define SCC_NVS_SDIO 1
|
||||
#define SCC_NVS_SD 2
|
||||
|
||||
typedef struct {
|
||||
/* Device Enabled in ACPI Mode */
|
||||
u8 lpss_en[14];
|
||||
u8 scc_en[3];
|
||||
u8 lpe_en;
|
||||
|
||||
/* BAR 0 */
|
||||
u32 lpss_bar0[14];
|
||||
u32 scc_bar0[3];
|
||||
u32 lpe_bar0;
|
||||
|
||||
/* BAR 0 */
|
||||
u32 lpss_bar1[14];
|
||||
u32 scc_bar1[3];
|
||||
u32 lpe_bar1;
|
||||
|
||||
/* Extra */
|
||||
u32 lpe_fw; /* LPE Firmware */
|
||||
u8 rsvd1[3930]; /* Add padding so sizeof(device_nvs_t) == 0x1000 */
|
||||
} __attribute__((packed)) device_nvs_t;
|
||||
|
||||
#endif
|
52
src/soc/intel/braswell/include/soc/efi_wrapper.h
Normal file
52
src/soc/intel/braswell/include/soc/efi_wrapper.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* PEI EFI entry point
|
||||
*
|
||||
* 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 __EFI_WRAPPER_H__
|
||||
#define __EFI_WRAPPER_H__
|
||||
|
||||
#define EFI_WRAPPER_VER 2
|
||||
|
||||
/* Provide generic x86 calling conventions. */
|
||||
#define ABI_X86 __attribute((regparm(0)))
|
||||
|
||||
/* Errors returned by the EFI wrapper. */
|
||||
enum efi_wrapper_error {
|
||||
INVALID_VER = -1,
|
||||
};
|
||||
|
||||
struct efi_wrapper_params {
|
||||
/* Mainboard Inputs */
|
||||
int version;
|
||||
|
||||
void ABI_X86 (*console_out)(unsigned char byte);
|
||||
|
||||
unsigned int tsc_ticks_per_microsecond;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef int ABI_X86 (*efi_wrapper_entry_t)(struct efi_wrapper_params *);
|
||||
#endif
|
44
src/soc/intel/braswell/include/soc/ehci.h
Normal file
44
src/soc/intel/braswell/include/soc/ehci.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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_EHCI_H
|
||||
#define BAYTRAIL_EHCI_H
|
||||
|
||||
/* EHCI PCI Registers */
|
||||
#define EHCI_CMD_STS 0x04
|
||||
# define INTRDIS (1 << 10)
|
||||
#define EHCI_SBRN_FLA_PWC 0x60
|
||||
# define PORTWKIMP (1 << 16)
|
||||
# define PORTWKCAPMASK (0x3ff << 17)
|
||||
#define EHCI_USB2PDO 0x64
|
||||
|
||||
/* EHCI Memory Registers */
|
||||
#define USB2CMD 0x20
|
||||
# define USB2CMD_ASE (1 << 5)
|
||||
# define USB2CMD_PSE (1 << 4)
|
||||
# define USB2CMD_HCRESET (1 << 1)
|
||||
# define USB2CMD_RS (1 << 0)
|
||||
#define USB2STS 0x24
|
||||
# define USB2STS_HCHALT (1 << 12)
|
||||
|
||||
/* RCBA EHCI Registers */
|
||||
#define RCBA_FUNC_DIS 0x220
|
||||
# define RCBA_EHCI_DIS (1 << 0)
|
||||
|
||||
#endif /* BAYTRAIL_EHCI_H */
|
64
src/soc/intel/braswell/include/soc/gfx.h
Normal file
64
src/soc/intel/braswell/include/soc/gfx.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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_GFX_H_
|
||||
#define _BAYTRAIL_GFX_H_
|
||||
|
||||
/*
|
||||
* PCI config registers.
|
||||
*/
|
||||
|
||||
#define GGC 0x50
|
||||
# define GGC_VGA_DISABLE (1 << 1)
|
||||
# define GGC_GTT_SIZE_MASK (3 << 8)
|
||||
# define GGC_GTT_SIZE_0MB (0 << 8)
|
||||
# define GGC_GTT_SIZE_1MB (1 << 8)
|
||||
# define GGC_GTT_SIZE_2MB (2 << 8)
|
||||
# define GGC_GSM_SIZE_MASK (0x1f << 3)
|
||||
# define GGC_GSM_SIZE_0MB (0 << 3)
|
||||
# define GGC_GSM_SIZE_32MB (1 << 3)
|
||||
# define GGC_GSM_SIZE_64MB (2 << 3)
|
||||
# define GGC_GSM_SIZE_128MB (4 << 3)
|
||||
|
||||
#define GSM_BASE 0x5c
|
||||
#define GTT_BASE 0x70
|
||||
|
||||
#define MSAC 0x62
|
||||
#define APERTURE_SIZE_MASK (3 << 1)
|
||||
#define APERTURE_SIZE_128MB (0 << 1)
|
||||
#define APERTURE_SIZE_256MB (1 << 1)
|
||||
#define APERTURE_SIZE_512MB (3 << 1)
|
||||
|
||||
#define VLV_DISPLAY_BASE 0x180000
|
||||
#define PIPEA_REG(reg) (VLV_DISPLAY_BASE + (reg))
|
||||
#define PIPEB_REG(reg) (VLV_DISPLAY_BASE + 0x100 + (reg))
|
||||
|
||||
/* Panel control registers */
|
||||
#define HOTPLUG_CTRL 0x61110
|
||||
#define PP_CONTROL 0x61204
|
||||
#define PP_CONTROL_UNLOCK 0xabcd0000
|
||||
#define PP_CONTROL_EDP_FORCE_VDD (1 << 3)
|
||||
#define PP_ON_DELAYS 0x61208
|
||||
#define PP_OFF_DELAYS 0x6120c
|
||||
#define PP_DIVISOR 0x61210
|
||||
#define BACKLIGHT_CTL2 0x61250
|
||||
#define BACKLIGHT_ENABLE (1 << 31)
|
||||
#define BACKLIGHT_CTL 0x61254
|
||||
|
||||
#endif /* _BAYTRAIL_GFX_H_ */
|
459
src/soc/intel/braswell/include/soc/gpio.h
Normal file
459
src/soc/intel/braswell/include/soc/gpio.h
Normal file
@ -0,0 +1,459 @@
|
||||
/*
|
||||
* 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 <soc/iomap.h>
|
||||
|
||||
/* #define GPIO_DEBUG */
|
||||
|
||||
/* Pad base, ex. PAD_CONF0[n]= PAD_BASE+16*n */
|
||||
#define GPSCORE_PAD_BASE (IO_BASE_ADDRESS + IO_BASE_OFFSET_GPSCORE)
|
||||
#define GPNCORE_PAD_BASE (IO_BASE_ADDRESS + IO_BASE_OFFSET_GPNCORE)
|
||||
#define GPSSUS_PAD_BASE (IO_BASE_ADDRESS + IO_BASE_OFFSET_GPSSUS)
|
||||
|
||||
/* DIRQ registers start at pad base + 0x980 */
|
||||
#define PAD_BASE_DIRQ_OFFSET 0x980
|
||||
|
||||
/* Pad register offset */
|
||||
#define PAD_CONF0_REG 0x0
|
||||
#define PAD_CONF1_REG 0x4
|
||||
#define PAD_VAL_REG 0x8
|
||||
|
||||
/* Legacy IO register base */
|
||||
#define GPSCORE_LEGACY_BASE (GPIO_BASE_ADDRESS + 0x00)
|
||||
#define GPSSUS_LEGACY_BASE (GPIO_BASE_ADDRESS + 0x80)
|
||||
/* Some banks have no legacy GPIO interface */
|
||||
#define GP_LEGACY_BASE_NONE 0xFFFF
|
||||
|
||||
#define LEGACY_USE_SEL_REG 0x00
|
||||
#define LEGACY_IO_SEL_REG 0x04
|
||||
#define LEGACY_GP_LVL_REG 0x08
|
||||
#define LEGACY_TPE_REG 0x0C
|
||||
#define LEGACY_TNE_REG 0x10
|
||||
#define LEGACY_TS_REG 0x14
|
||||
#define LEGACY_WAKE_EN_REG 0x18
|
||||
|
||||
/* Number of GPIOs in each bank */
|
||||
#define GPNCORE_COUNT 27
|
||||
#define GPSCORE_COUNT 102
|
||||
#define GPSSUS_COUNT 44
|
||||
|
||||
/* GPIO legacy IO register settings */
|
||||
#define GPIO_USE_MMIO 0
|
||||
#define GPIO_USE_LEGACY 1
|
||||
|
||||
#define GPIO_DIR_OUTPUT 0
|
||||
#define GPIO_DIR_INPUT 1
|
||||
|
||||
#define GPIO_LEVEL_LOW 0
|
||||
#define GPIO_LEVEL_HIGH 1
|
||||
|
||||
#define GPIO_PEDGE_DISABLE 0
|
||||
#define GPIO_PEDGE_ENABLE 1
|
||||
|
||||
#define GPIO_NEDGE_DISABLE 0
|
||||
#define GPIO_NEDGE_ENABLE 1
|
||||
|
||||
/* config0[29] - Disable second mask */
|
||||
#define PAD_MASK2_DISABLE (1 << 29)
|
||||
|
||||
/* config0[27] - Direct Irq En */
|
||||
#define PAD_IRQ_EN (1 << 27)
|
||||
|
||||
/* config0[26] - gd_tne */
|
||||
#define PAD_TNE_IRQ (1 << 26)
|
||||
|
||||
/* config0[25] - gd_tpe */
|
||||
#define PAD_TPE_IRQ (1 << 25)
|
||||
|
||||
/* config0[24] - Gd Level */
|
||||
#define PAD_LEVEL_IRQ (1 << 24)
|
||||
#define PAD_EDGE_IRQ (0 << 24)
|
||||
|
||||
/* config0[17] - Slow clkgate / glitch filter */
|
||||
#define PAD_SLOWGF_ENABLE (1 << 17)
|
||||
|
||||
/* config0[16] - Fast clkgate / glitch filter */
|
||||
#define PAD_FASTGF_ENABLE (1 << 16)
|
||||
|
||||
/* config0[15] - Hysteresis enable (inverted) */
|
||||
#define PAD_HYST_DISABLE (1 << 15)
|
||||
#define PAD_HYST_ENABLE (0 << 15)
|
||||
|
||||
/* config0[14:13] - Hysteresis control */
|
||||
#define PAD_HYST_CTRL_DEFAULT (2 << 13)
|
||||
|
||||
/* config0[11] - Bypass Flop */
|
||||
#define PAD_FLOP_BYPASS (1 << 11)
|
||||
#define PAD_FLOP_ENABLE (0 << 11)
|
||||
|
||||
/* config0[10:9] - Pull str */
|
||||
#define PAD_PU_2K (0 << 9)
|
||||
#define PAD_PU_10K (1 << 9)
|
||||
#define PAD_PU_20K (2 << 9)
|
||||
#define PAD_PU_40K (3 << 9)
|
||||
|
||||
/* config0[8:7] - Pull assign */
|
||||
#define PAD_PULL_DISABLE (0 << 7)
|
||||
#define PAD_PULL_UP (1 << 7)
|
||||
#define PAD_PULL_DOWN (2 << 7)
|
||||
|
||||
/* config0[2:0] - Func. pin mux */
|
||||
#define PAD_FUNC0 0x0
|
||||
#define PAD_FUNC1 0x1
|
||||
#define PAD_FUNC2 0x2
|
||||
#define PAD_FUNC3 0x3
|
||||
#define PAD_FUNC4 0x4
|
||||
#define PAD_FUNC5 0x5
|
||||
#define PAD_FUNC6 0x6
|
||||
|
||||
/* pad config0 power-on values - We will not often want to change these */
|
||||
#define PAD_CONFIG0_DEFAULT (PAD_MASK2_DISABLE | PAD_SLOWGF_ENABLE | \
|
||||
PAD_FASTGF_ENABLE | PAD_HYST_DISABLE | \
|
||||
PAD_HYST_CTRL_DEFAULT | PAD_FLOP_BYPASS)
|
||||
|
||||
/* pad config1 reg power-on values - Shouldn't need to change this */
|
||||
#define PAD_CONFIG1_DEFAULT 0x8000
|
||||
|
||||
/* pad_val[2] - Iinenb - active low */
|
||||
#define PAD_VAL_INPUT_DISABLE (1 << 2)
|
||||
#define PAD_VAL_INPUT_ENABLE (0 << 2)
|
||||
|
||||
/* pad_val[1] - Ioutenb - active low */
|
||||
#define PAD_VAL_OUTPUT_DISABLE (1 << 1)
|
||||
#define PAD_VAL_OUTPUT_ENABLE (0 << 1)
|
||||
|
||||
/* Input / Output state should usually be mutually exclusive */
|
||||
#define PAD_VAL_INPUT (PAD_VAL_INPUT_ENABLE | PAD_VAL_OUTPUT_DISABLE)
|
||||
#define PAD_VAL_OUTPUT (PAD_VAL_OUTPUT_ENABLE | PAD_VAL_INPUT_DISABLE)
|
||||
|
||||
/* pad_val[0] - Value */
|
||||
#define PAD_VAL_HIGH (1 << 0)
|
||||
#define PAD_VAL_LOW (0 << 0)
|
||||
|
||||
/* pad_val reg power-on default varies by pad, and apparently can cause issues
|
||||
* if not set correctly, even if the pin isn't configured as GPIO. */
|
||||
#define PAD_VAL_DEFAULT PAD_VAL_INPUT
|
||||
|
||||
/* Configure GPIOs as MMIO by default */
|
||||
#define GPIO_INPUT_PU_10K \
|
||||
{ .pad_conf0 = PAD_PU_10K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_MMIO, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_INPUT_PU_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_MMIO, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_INPUT_PD_10K \
|
||||
{ .pad_conf0 = PAD_PU_10K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_MMIO, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_INPUT_PD_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_MMIO, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_INPUT_NOPU \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_MMIO, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_INPUT_LEGACY_NOPU \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_INPUT, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TPE_IRQ | PAD_LEVEL_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_LEVELHIGH_NO_PULL \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TPE_IRQ | PAD_LEVEL_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_LEVELLOW_PU_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TNE_IRQ | PAD_LEVEL_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_EDGELOW_PU_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TNE_IRQ | PAD_EDGE_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_EDGEHIGH_PD_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TPE_IRQ | PAD_EDGE_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_EDGELOW_PD_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TNE_IRQ | PAD_EDGE_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
/* Direct / dedicated IRQ input - pass signal directly to apic */
|
||||
#define GPIO_DIRQ_EDGEBOTH_PU_20K \
|
||||
{ .pad_conf0 = PAD_PU_20K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT \
|
||||
| PAD_FUNC0 | PAD_IRQ_EN | PAD_TPE_IRQ| PAD_TNE_IRQ | PAD_EDGE_IRQ, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, }
|
||||
|
||||
#define GPIO_OUT_LOW \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_OUTPUT | PAD_VAL_LOW, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_OUTPUT, \
|
||||
.gp_lvl = GPIO_LEVEL_LOW, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
#define GPIO_OUT_HIGH \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_OUTPUT | PAD_VAL_HIGH, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_OUTPUT, \
|
||||
.gp_lvl = GPIO_LEVEL_HIGH, \
|
||||
.is_gpio = 1 }
|
||||
|
||||
/* Define no-pull / PU / PD configs for each functional config option */
|
||||
#define GPIO_FUNC(_func, _pudir, _str) \
|
||||
{ .use_sel = GPIO_USE_MMIO, \
|
||||
.pad_conf0 = PAD_FUNC##_func | PAD_##_pudir | PAD_PU_##_str | \
|
||||
PAD_CONFIG0_DEFAULT, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_DEFAULT }
|
||||
|
||||
/* Default functional configs -- no PU */
|
||||
#define GPIO_FUNC0 GPIO_FUNC(0, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC1 GPIO_FUNC(1, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC2 GPIO_FUNC(2, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC3 GPIO_FUNC(3, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC4 GPIO_FUNC(4, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC5 GPIO_FUNC(5, PULL_DISABLE, 20K)
|
||||
#define GPIO_FUNC6 GPIO_FUNC(6, PULL_DISABLE, 20K)
|
||||
|
||||
/* ACPI GPIO routing. Assume everything is externally pulled and negative edge
|
||||
* triggered. SCI implies WAKE, but WAKE doesn't imply SCI. */
|
||||
#define GPIO_ACPI_SCI \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT | PAD_FUNC0, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_INPUT, \
|
||||
.tne = 1, \
|
||||
.sci = 1, \
|
||||
.wake_en = 1, }
|
||||
#define GPIO_ACPI_WAKE \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT | PAD_FUNC0, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_INPUT, \
|
||||
.tne = 1, \
|
||||
.wake_en = 1, }
|
||||
#define GPIO_ACPI_SMI \
|
||||
{ .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT | PAD_FUNC0, \
|
||||
.pad_conf1 = PAD_CONFIG1_DEFAULT, \
|
||||
.pad_val = PAD_VAL_INPUT, \
|
||||
.use_sel = GPIO_USE_LEGACY, \
|
||||
.io_sel = GPIO_DIR_INPUT, \
|
||||
.tne = 1, \
|
||||
.smi = 1}
|
||||
|
||||
/* End marker */
|
||||
#define GPIO_LIST_END 0xffffffff
|
||||
|
||||
#define GPIO_END \
|
||||
{ .pad_conf0 = GPIO_LIST_END }
|
||||
|
||||
/* Common default GPIO settings */
|
||||
#define GPIO_INPUT GPIO_INPUT_NOPU
|
||||
#define GPIO_INPUT_LEGACY GPIO_INPUT_LEGACY_NOPU
|
||||
#define GPIO_INPUT_PU GPIO_INPUT_PU_20K
|
||||
#define GPIO_INPUT_PD GPIO_INPUT_PD_20K
|
||||
#define GPIO_NC GPIO_OUT_HIGH
|
||||
#define GPIO_DEFAULT GPIO_FUNC0
|
||||
|
||||
/* 16 DirectIRQs per supported bank */
|
||||
#define GPIO_MAX_DIRQS 16
|
||||
|
||||
/* Most pins are GPIO function 0. Some banks have a range of pins with GPIO
|
||||
* function 1. Indicate first / last GPIOs with function 1. */
|
||||
#define GPIO_NONE 255
|
||||
/* All NCORE GPIOs are function 0 */
|
||||
#define GPNCORE_GPIO_F1_RANGE_START GPIO_NONE
|
||||
#define GPNCORE_GPIO_F1_RANGE_END GPIO_NONE
|
||||
/* SCORE GPIO [92:93] are function 1 */
|
||||
#define GPSCORE_GPIO_F1_RANGE_START 92
|
||||
#define GPSCORE_GPIO_F1_RANGE_END 93
|
||||
/* SSUS GPIO [11:21] are function 1 */
|
||||
#define GPSSUS_GPIO_F1_RANGE_START 11
|
||||
#define GPSSUS_GPIO_F1_RANGE_END 21
|
||||
|
||||
struct soc_gpio_map {
|
||||
u32 pad_conf0;
|
||||
u32 pad_conf1;
|
||||
u32 pad_val;
|
||||
u32 use_sel : 1;
|
||||
u32 io_sel : 1;
|
||||
u32 gp_lvl : 1;
|
||||
u32 tpe : 1;
|
||||
u32 tne : 1;
|
||||
u32 wake_en : 1;
|
||||
u32 smi : 1;
|
||||
u32 is_gpio : 1;
|
||||
u32 sci : 1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct soc_gpio_config {
|
||||
const struct soc_gpio_map *ncore;
|
||||
const struct soc_gpio_map *score;
|
||||
const struct soc_gpio_map *ssus;
|
||||
const u8 (*core_dirq)[GPIO_MAX_DIRQS];
|
||||
const u8 (*sus_dirq)[GPIO_MAX_DIRQS];
|
||||
};
|
||||
|
||||
/* Description of GPIO 'bank' ex. {ncore, score. ssus} */
|
||||
struct gpio_bank {
|
||||
const int gpio_count;
|
||||
const u8* gpio_to_pad;
|
||||
const int legacy_base;
|
||||
const unsigned long pad_base;
|
||||
const u8 has_wake_en :1;
|
||||
const u8 gpio_f1_range_start;
|
||||
const u8 gpio_f1_range_end;
|
||||
};
|
||||
|
||||
void setup_soc_gpios(struct soc_gpio_config *config, u8 enable_xdp_tap);
|
||||
/* This function is weak and can be overridden by a mainboard function. */
|
||||
struct soc_gpio_config* mainboard_get_gpios(void);
|
||||
|
||||
/* Functions / defines for changing GPIOs in romstage */
|
||||
/* SCORE Pad definitions. */
|
||||
#define UART_RXD_PAD 82
|
||||
#define UART_TXD_PAD 83
|
||||
#define PCU_SMB_CLK_PAD 88
|
||||
#define PCU_SMB_DATA_PAD 90
|
||||
#define SOC_DDI1_VDDEN_PAD 16
|
||||
|
||||
static inline u32 *ncore_pconf0(int pad_num)
|
||||
{
|
||||
return (u32 *)(GPNCORE_PAD_BASE + pad_num * 16);
|
||||
}
|
||||
|
||||
static inline void ncore_select_func(int pad, int func)
|
||||
{
|
||||
uint32_t reg;
|
||||
u32 *pconf0_addr = ncore_pconf0(pad);
|
||||
|
||||
reg = read32(pconf0_addr);
|
||||
reg &= ~0x7;
|
||||
reg |= func & 0x7;
|
||||
write32(pconf0_addr, reg);
|
||||
}
|
||||
|
||||
static inline u32 *score_pconf0(int pad_num)
|
||||
{
|
||||
return (u32 *)(GPSCORE_PAD_BASE + pad_num * 16);
|
||||
}
|
||||
|
||||
static inline u32 *ssus_pconf0(int pad_num)
|
||||
{
|
||||
return (u32 *)(GPSSUS_PAD_BASE + 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);
|
||||
}
|
||||
|
||||
/* These functions require that the input pad be configured as an input GPIO */
|
||||
static inline int score_get_gpio(int pad)
|
||||
{
|
||||
uint32_t *val_addr = score_pconf0(pad) + (PAD_VAL_REG/sizeof(uint32_t));
|
||||
|
||||
return read32(val_addr) & PAD_VAL_HIGH;
|
||||
}
|
||||
|
||||
static inline int ssus_get_gpio(int pad)
|
||||
{
|
||||
uint32_t *val_addr = ssus_pconf0(pad) + (PAD_VAL_REG/sizeof(uint32_t));
|
||||
|
||||
return read32(val_addr) & PAD_VAL_HIGH;
|
||||
}
|
||||
|
||||
static inline void ssus_disable_internal_pull(int pad)
|
||||
{
|
||||
const uint32_t pull_mask = ~(0xf << 7);
|
||||
write32(ssus_pconf0(pad), read32(ssus_pconf0(pad)) & pull_mask);
|
||||
}
|
||||
|
||||
#endif /* _BAYTRAIL_GPIO_H_ */
|
90
src/soc/intel/braswell/include/soc/iomap.h
Normal file
90
src/soc/intel/braswell/include/soc/iomap.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* PCI Configuration Space */
|
||||
#define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS
|
||||
#define MCFG_BASE_SIZE 0x10000000
|
||||
|
||||
/* Transactions in this range will abort */
|
||||
#define ABORT_BASE_ADDRESS 0xfeb00000
|
||||
#define ABORT_BASE_SIZE 0x00100000
|
||||
|
||||
/* Power Management Controller */
|
||||
#define PMC_BASE_ADDRESS 0xfed03000
|
||||
#define PMC_BASE_SIZE 0x400
|
||||
|
||||
/* IO Memory */
|
||||
#define IO_BASE_ADDRESS 0xfed0c000
|
||||
#define IO_BASE_OFFSET_GPSCORE 0x0000
|
||||
#define IO_BASE_OFFSET_GPNCORE 0x1000
|
||||
#define IO_BASE_OFFSET_GPSSUS 0x2000
|
||||
#define IO_BASE_SIZE 0x4000
|
||||
|
||||
/* Intel Legacy Block */
|
||||
#define ILB_BASE_ADDRESS 0xfed08000
|
||||
#define ILB_BASE_SIZE 0x400
|
||||
|
||||
/* SPI Bus */
|
||||
#define SPI_BASE_ADDRESS 0xfed01000
|
||||
#define SPI_BASE_SIZE 0x400
|
||||
|
||||
/* MODPHY */
|
||||
#define MPHY_BASE_ADDRESS 0xfef00000
|
||||
#define MPHY_BASE_SIZE 0x100000
|
||||
|
||||
/* Power Management Unit */
|
||||
#define PUNIT_BASE_ADDRESS 0xfed05000
|
||||
#define PUNIT_BASE_SIZE 0x800
|
||||
|
||||
/* Root Complex Base Address */
|
||||
#define RCBA_BASE_ADDRESS 0xfed1c000
|
||||
#define RCBA_BASE_SIZE 0x400
|
||||
|
||||
/* High Performance Event Timer */
|
||||
#define HPET_BASE_ADDRESS 0xfed00000
|
||||
#define HPET_BASE_SIZE 0x400
|
||||
|
||||
/* Temporary Base Address */
|
||||
#define TEMP_BASE_ADDRESS 0xfd000000
|
||||
|
||||
/*
|
||||
* IO Port bases.
|
||||
*/
|
||||
#define ACPI_BASE_ADDRESS 0x0400
|
||||
#define ACPI_BASE_SIZE 0x80
|
||||
|
||||
#define GPIO_BASE_ADDRESS 0x0500
|
||||
#define GPIO_BASE_SIZE 0x100
|
||||
|
||||
#define SMBUS_BASE_ADDRESS 0xefa0
|
||||
|
||||
#ifndef __ACPI__
|
||||
/* Read Top of Low Memory (BMBOUND) */
|
||||
uint32_t nc_read_top_of_low_memory(void);
|
||||
#endif
|
||||
|
||||
#endif /* _BAYTRAIL_IOMAP_H_ */
|
349
src/soc/intel/braswell/include/soc/iosf.h
Normal file
349
src/soc/intel/braswell/include/soc/iosf.h
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* 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_IOSF_H_
|
||||
#define _BAYTRAIL_IOSF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <soc/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_REG_UPPER(x) (((~0xff) & (x)))
|
||||
#define IOSF_BYTE_EN_0 0x10
|
||||
#define IOSF_BYTE_EN_1 0x20
|
||||
#define IOSF_BYTE_EN_2 0x40
|
||||
#define IOSF_BYTE_EN_3 0x80
|
||||
#define IOSF_BYTE_EN \
|
||||
(IOSF_BYTE_EN_0 | IOSF_BYTE_EN_1 | IOSF_BYTE_EN_2 | IOSF_BYTE_EN_3)
|
||||
#define MDR_REG 0xd4
|
||||
#define MCRX_REG 0xd8
|
||||
|
||||
uint32_t iosf_aunit_read(int reg);
|
||||
void iosf_aunit_write(int reg, uint32_t val);
|
||||
uint32_t iosf_cpu_bus_read(int reg);
|
||||
void iosf_cpu_bus_write(int reg, uint32_t val);
|
||||
uint32_t iosf_bunit_read(int reg);
|
||||
void iosf_bunit_write(int reg, uint32_t val);
|
||||
uint32_t iosf_dunit_read(int reg);
|
||||
void iosf_dunit_write(int reg, uint32_t val);
|
||||
/* Some registers are per channel while the globals live in dunit 0 */
|
||||
uint32_t iosf_dunit_ch0_read(int reg);
|
||||
uint32_t iosf_dunit_ch1_read(int reg);
|
||||
uint32_t iosf_punit_read(int reg);
|
||||
void iosf_punit_write(int reg, uint32_t val);
|
||||
uint32_t iosf_usbphy_read(int reg);
|
||||
void iosf_usbphy_write(int reg, uint32_t val);
|
||||
uint32_t iosf_ushphy_read(int reg);
|
||||
void iosf_ushphy_write(int reg, uint32_t val);
|
||||
uint32_t iosf_sec_read(int reg);
|
||||
void iosf_sec_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port45_read(int reg);
|
||||
void iosf_port45_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port46_read(int reg);
|
||||
void iosf_port46_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port47_read(int reg);
|
||||
void iosf_port47_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port55_read(int reg);
|
||||
void iosf_port55_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port58_read(int reg);
|
||||
void iosf_port58_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port59_read(int reg);
|
||||
void iosf_port59_write(int reg, uint32_t val);
|
||||
uint32_t iosf_port5a_read(int reg);
|
||||
void iosf_port5a_write(int reg, uint32_t val);
|
||||
uint32_t iosf_lpss_read(int reg);
|
||||
void iosf_lpss_write(int reg, uint32_t val);
|
||||
uint32_t iosf_ccu_read(int reg);
|
||||
void iosf_ccu_write(int reg, uint32_t val);
|
||||
uint32_t iosf_score_read(int reg);
|
||||
void iosf_score_write(int reg, uint32_t val);
|
||||
uint32_t iosf_scc_read(int reg);
|
||||
void iosf_scc_write(int reg, uint32_t val);
|
||||
uint32_t iosf_porta2_read(int reg);
|
||||
void iosf_porta2_write(int reg, uint32_t val);
|
||||
uint32_t iosf_ssus_read(int reg);
|
||||
void iosf_ssus_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_DUNIT_CH0 0x07 /* DUNIT Channel 0 */
|
||||
#define IOSF_PORT_CPU_BUS 0x02 /* CPU Bus Interface Controller */
|
||||
#define IOSF_PORT_BUNIT 0x03 /* System Memory Arbiter/Bunit */
|
||||
#define IOSF_PORT_PMC 0x04 /* Power Management Controller */
|
||||
#define IOSF_PORT_GFX 0x06 /* Graphics Adapter */
|
||||
#define IOSF_PORT_DUNIT_CH1 0x07 /* DUNIT Channel 1 */
|
||||
#define IOSF_PORT_SYSMEMIO 0x0c /* System Memory IO */
|
||||
#define IOSF_PORT_USBPHY 0x43 /* USB PHY */
|
||||
#define IOSF_PORT_SEC 0x44 /* SEC */
|
||||
#define IOSF_PORT_0x45 0x45
|
||||
#define IOSF_PORT_0x46 0x46
|
||||
#define IOSF_PORT_0x47 0x47
|
||||
#define IOSF_PORT_SCORE 0x48 /* SCORE */
|
||||
#define IOSF_PORT_0x55 0x55
|
||||
#define IOSF_PORT_0x58 0x58
|
||||
#define IOSF_PORT_0x59 0x59
|
||||
#define IOSF_PORT_0x5a 0x5a
|
||||
#define IOSF_PORT_USHPHY 0x61 /* USB XHCI PHY */
|
||||
#define IOSF_PORT_SCC 0x63 /* Storage Control Cluster */
|
||||
#define IOSF_PORT_LPSS 0xa0 /* LPSS - Low Power Subsystem */
|
||||
#define IOSF_PORT_0xa2 0xa2
|
||||
#define IOSF_PORT_SATAPHY 0xa3 /* SATA PHY */
|
||||
#define IOSF_PORT_PCIEPHY 0xa3 /* PCIE PHY */
|
||||
#define IOSF_PORT_SSUS 0xa8 /* SUS */
|
||||
#define IOSF_PORT_CCU 0xa9 /* Clock control unit. */
|
||||
|
||||
/* 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_SEC 0x04
|
||||
#define IOSF_OP_WRITE_SEC (IOSF_OP_READ_SEC | 1)
|
||||
#define IOSF_OP_READ_0x45 0x06
|
||||
#define IOSF_OP_WRITE_0x45 (IOSF_OP_READ_0x45 | 1)
|
||||
#define IOSF_OP_READ_0x46 0x06
|
||||
#define IOSF_OP_WRITE_0x46 (IOSF_OP_READ_0x46 | 1)
|
||||
#define IOSF_OP_READ_0x47 0x06
|
||||
#define IOSF_OP_WRITE_0x47 (IOSF_OP_READ_0x47 | 1)
|
||||
#define IOSF_OP_READ_SCORE 0x06
|
||||
#define IOSF_OP_WRITE_SCORE (IOSF_OP_READ_SCORE | 1)
|
||||
#define IOSF_OP_READ_0x55 0x04
|
||||
#define IOSF_OP_WRITE_0x55 (IOSF_OP_READ_0x55 | 1)
|
||||
#define IOSF_OP_READ_0x58 0x06
|
||||
#define IOSF_OP_WRITE_0x58 (IOSF_OP_READ_0x58 | 1)
|
||||
#define IOSF_OP_READ_0x59 0x06
|
||||
#define IOSF_OP_WRITE_0x59 (IOSF_OP_READ_0x59 | 1)
|
||||
#define IOSF_OP_READ_0x5a 0x04
|
||||
#define IOSF_OP_WRITE_0x5a (IOSF_OP_READ_0x5a | 1)
|
||||
#define IOSF_OP_READ_USHPHY 0x06
|
||||
#define IOSF_OP_WRITE_USHPHY (IOSF_OP_READ_USHPHY | 1)
|
||||
#define IOSF_OP_READ_SCC 0x06
|
||||
#define IOSF_OP_WRITE_SCC (IOSF_OP_READ_SCC | 1)
|
||||
#define IOSF_OP_READ_LPSS 0x06
|
||||
#define IOSF_OP_WRITE_LPSS (IOSF_OP_READ_LPSS | 1)
|
||||
#define IOSF_OP_READ_0xa2 0x06
|
||||
#define IOSF_OP_WRITE_0xa2 (IOSF_OP_READ_0xa2 | 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)
|
||||
#define IOSF_OP_READ_SSUS 0x10
|
||||
#define IOSF_OP_WRITE_SSUS (IOSF_OP_READ_SSUS | 1)
|
||||
#define IOSF_OP_READ_CCU 0x06
|
||||
#define IOSF_OP_WRITE_CCU (IOSF_OP_READ_CCU | 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_SMRCP 0x2b
|
||||
#define BUNIT_SMRRAC 0x2c
|
||||
#define BUNIT_SMRWAC 0x2d
|
||||
#define BUNIT_SMRRL 0x2e
|
||||
#define BUNIT_SMRRH 0x2f
|
||||
# define BUNIT_SMRR_ENABLE (1 << 31)
|
||||
|
||||
/* SA ID bits. */
|
||||
#define SAI_IA_UNTRUSTED (1 << 0)
|
||||
#define SAI_IA_SMM (1 << 2)
|
||||
#define SAI_IA_BOOT (1 << 4)
|
||||
|
||||
/*
|
||||
* DUNIT Registers.
|
||||
*/
|
||||
|
||||
#define DRP 0x00
|
||||
# define DRP_DIMM0_RANK0_EN (0x01 << 0)
|
||||
# define DRP_DIMM0_RANK1_EN (0x01 << 1)
|
||||
# define DRP_DIMM1_RANK0_EN (0x01 << 2)
|
||||
# define DRP_DIMM1_RANK1_EN (0x01 << 3)
|
||||
# define DRP_RANK_MASK (DRP_DIMM0_RANK0_EN | DRP_DIMM0_RANK1_EN | \
|
||||
DRP_DIMM1_RANK0_EN | DRP_DIMM1_RANK1_EN)
|
||||
#define DTR0 0x01
|
||||
# define DTR0_SPEED_MASK 0x03
|
||||
# define DTR0_SPEED_800 0x00
|
||||
# define DTR0_SPEED_1066 0x01
|
||||
# define DTR0_SPEED_1333 0x02
|
||||
# define DTR0_SPEED_1600 0x03
|
||||
|
||||
/*
|
||||
* PUNIT Registers
|
||||
*/
|
||||
#define SB_BIOS_CONFIG 0x06
|
||||
# define SB_BIOS_CONFIG_ECC_EN (1 << 31)
|
||||
# define SB_BIOS_CONFIG_DUAL_CH_DIS (1 << 30)
|
||||
# define SB_BIOS_CONFIG_EFF_ECC (1 << 29)
|
||||
# define SB_BIOS_CONFIG_EFF_DUAL_CH_DIS (1 << 28)
|
||||
# define SB_BIOS_CONFIG_PERF_MODE (1 << 17)
|
||||
# define SB_BIOS_CONFIG_PDM_MODE (1 << 16)
|
||||
# define SB_BIOS_CONFIG_DDRIO_PWRGATE (1 << 8)
|
||||
# define SB_BIOS_CONFIG_GFX_TURBO_DIS (1 << 7)
|
||||
# define SB_BIOS_CONFIG_PS2_EN_VNN (1 << 3)
|
||||
# define SB_BIOS_CONFIG_PS2_EN_VCC (1 << 2)
|
||||
# define SB_BIOS_CONFIG_PCIE_PLLOFFOK (1 << 1)
|
||||
# define SB_BIOS_CONFIG_USB_CACHING_EN (1 << 0)
|
||||
#define BIOS_RESET_CPL 0x05
|
||||
# define BIOS_RESET_CPL_ALL_DONE (1 << 1)
|
||||
# define BIOS_RESET_CPL_RESET_DONE (1 << 0)
|
||||
#define PUNIT_PWRGT_CONTROL 0x60
|
||||
#define PUNIT_PWRGT_STATUS 0x61
|
||||
#define PUNIT_GPU_EC_VIRUS 0xd2
|
||||
|
||||
#define PUNIT_SOC_POWER_BUDGET 0x02
|
||||
#define PUNIT_SOC_ENERGY_CREDIT 0x03
|
||||
#define PUNIT_PTMC 0x80
|
||||
#define PUNIT_GFXT 0x88
|
||||
#define PUNIT_VEDT 0x89
|
||||
#define PUNIT_ISPT 0x8c
|
||||
#define PUNIT_PTPS 0xb2
|
||||
#define PUNIT_TE_AUX0 0xb5
|
||||
#define PUNIT_TE_AUX1 0xb6
|
||||
#define PUNIT_TE_AUX2 0xb7
|
||||
#define PUNIT_TE_AUX3 0xb8
|
||||
#define PUNIT_TTE_VRIccMax 0xb9
|
||||
#define PUNIT_TTE_VRHot 0xba
|
||||
#define PUNIT_TTE_XXPROCHOT 0xbb
|
||||
#define PUNIT_TTE_SLM0 0xbc
|
||||
#define PUNIT_TTE_SLM1 0xbd
|
||||
#define PUNIT_TTE_SWT 0xbf
|
||||
|
||||
/*
|
||||
* LPSS Registers
|
||||
*/
|
||||
#define LPSS_SIO_DMA1_CTL 0x280
|
||||
#define LPSS_I2C1_CTL 0x288
|
||||
#define LPSS_I2C2_CTL 0x290
|
||||
#define LPSS_I2C3_CTL 0x298
|
||||
#define LPSS_I2C4_CTL 0x2a0
|
||||
#define LPSS_I2C5_CTL 0x2a8
|
||||
#define LPSS_I2C6_CTL 0x2b0
|
||||
#define LPSS_I2C7_CTL 0x2b8
|
||||
#define LPSS_SIO_DMA2_CTL 0x240
|
||||
#define LPSS_PWM1_CTL 0x248
|
||||
#define LPSS_PWM2_CTL 0x250
|
||||
#define LPSS_HSUART1_CTL 0x258
|
||||
#define LPSS_HSUART2_CTL 0x260
|
||||
#define LPSS_SPI_CTL 0x268
|
||||
# define LPSS_CTL_ACPI_INT_EN (1 << 21)
|
||||
# define LPSS_CTL_PCI_CFG_DIS (1 << 20)
|
||||
# define LPSS_CTL_SNOOP (1 << 18)
|
||||
# define LPSS_CTL_NOSNOOP (1 << 19)
|
||||
# define LPSS_CTL_PM_CAP_PRSNT (1 << 1)
|
||||
|
||||
/*
|
||||
* SCC Registers
|
||||
*/
|
||||
#define SCC_SD_CTL 0x504
|
||||
#define SCC_SDIO_CTL 0x508
|
||||
#define SCC_MMC_CTL 0x50c
|
||||
# define SCC_CTL_PCI_CFG_DIS (1 << 0)
|
||||
# define SCC_CTL_ACPI_INT_EN (1 << 1)
|
||||
|
||||
/*
|
||||
* CCU Registers
|
||||
*/
|
||||
|
||||
#define PLT_CLK_CTRL_0 0x3c
|
||||
#define PLT_CLK_CTRL_1 0x40
|
||||
#define PLT_CLK_CTRL_2 0x44
|
||||
#define PLT_CLK_CTRL_3 0x48
|
||||
#define PLT_CLK_CTRL_4 0x4c
|
||||
#define PLT_CLK_CTRL_5 0x50
|
||||
# define PLT_CLK_CTRL_19P2MHZ_FREQ (0 << 1)
|
||||
# define PLT_CLK_CTRL_25MHZ_FREQ (1 << 1)
|
||||
# define PLT_CLK_CTRL_SELECT_FREQ (1 << 0)
|
||||
|
||||
/*
|
||||
* USBPHY Registers
|
||||
*/
|
||||
#define USBPHY_COMPBG 0x7f04
|
||||
#define USBPHY_PER_PORT_LANE0 0x4100
|
||||
#define USBPHY_PER_PORT_RCOMP_HS_PULLUP0 0x4122
|
||||
#define USBPHY_PER_PORT_LANE1 0x4200
|
||||
#define USBPHY_PER_PORT_RCOMP_HS_PULLUP1 0x4222
|
||||
#define USBPHY_PER_PORT_LANE2 0x4300
|
||||
#define USBPHY_PER_PORT_RCOMP_HS_PULLUP2 0x4322
|
||||
#define USBPHY_PER_PORT_LANE3 0x4400
|
||||
#define USBPHY_PER_PORT_RCOMP_HS_PULLUP3 0x4422
|
||||
|
||||
/*
|
||||
* USHPHY Registers
|
||||
*/
|
||||
#define USHPHY_CDN_PLL_CONTROL 0x03c0
|
||||
#define USHPHY_CDN_VCO_START_CAL_POINT 0x0054
|
||||
#define USHPHY_CCDRLF 0x8040
|
||||
#define USHPHY_PEAKING_AMP_CONFIG_DIAG 0x80a8
|
||||
#define USHPHY_OFFSET_COR_CONFIG_DIAG 0x80b0
|
||||
#define USHPHY_VGA_GAIN_CONFIG_DIAG 0x8080
|
||||
#define USHPHY_REE_DAC_CONTROL 0x80b8
|
||||
#define USHPHY_CDN_U1_POWER_STATE_DEF 0x0000
|
||||
|
||||
/*
|
||||
* LPE Registers
|
||||
*/
|
||||
#define LPE_PCICFGCTR1 0x0500
|
||||
# define LPE_PCICFGCTR1_PCI_CFG_DIS (1 << 0)
|
||||
# define LPE_PCICFGCTR1_ACPI_INT_EN (1 << 1)
|
||||
|
||||
#endif /* _BAYTRAIL_IOSF_H_ */
|
164
src/soc/intel/braswell/include/soc/irq.h
Normal file
164
src/soc/intel/braswell/include/soc/irq.h
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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_IRQ_H_
|
||||
#define _BAYTRAIL_IRQ_H_
|
||||
|
||||
#define PIRQA_APIC_IRQ 16
|
||||
#define PIRQB_APIC_IRQ 17
|
||||
#define PIRQC_APIC_IRQ 18
|
||||
#define PIRQD_APIC_IRQ 19
|
||||
#define PIRQE_APIC_IRQ 20
|
||||
#define PIRQF_APIC_IRQ 21
|
||||
#define PIRQG_APIC_IRQ 22
|
||||
#define PIRQH_APIC_IRQ 23
|
||||
/* The below IRQs are for when devices are in ACPI mode. Active low. */
|
||||
#define LPE_DMA0_IRQ 24
|
||||
#define LPE_DMA1_IRQ 25
|
||||
#define LPE_SSP0_IRQ 26
|
||||
#define LPE_SSP1_IRQ 27
|
||||
#define LPE_SSP2_IRQ 28
|
||||
#define LPE_IPC2HOST_IRQ 29
|
||||
#define LPSS_I2C1_IRQ 32
|
||||
#define LPSS_I2C2_IRQ 33
|
||||
#define LPSS_I2C3_IRQ 34
|
||||
#define LPSS_I2C4_IRQ 35
|
||||
#define LPSS_I2C5_IRQ 36
|
||||
#define LPSS_I2C6_IRQ 37
|
||||
#define LPSS_I2C7_IRQ 38
|
||||
#define LPSS_HSUART1_IRQ 39
|
||||
#define LPSS_HSUART2_IRQ 40
|
||||
#define LPSS_SPI_IRQ 41
|
||||
#define LPSS_DMA1_IRQ 42
|
||||
#define LPSS_DMA2_IRQ 43
|
||||
#define SCC_EMMC_IRQ 44
|
||||
#define SCC_SDIO_IRQ 46
|
||||
#define SCC_SD_IRQ 47
|
||||
#define GPIO_NC_IRQ 48
|
||||
#define GPIO_SC_IRQ 49
|
||||
#define GPIO_SUS_IRQ 50
|
||||
/* GPIO direct / dedicated IRQs. */
|
||||
#define GPIO_S0_DED_IRQ_0 51
|
||||
#define GPIO_S0_DED_IRQ_1 52
|
||||
#define GPIO_S0_DED_IRQ_2 53
|
||||
#define GPIO_S0_DED_IRQ_3 54
|
||||
#define GPIO_S0_DED_IRQ_4 55
|
||||
#define GPIO_S0_DED_IRQ_5 56
|
||||
#define GPIO_S0_DED_IRQ_6 57
|
||||
#define GPIO_S0_DED_IRQ_7 58
|
||||
#define GPIO_S0_DED_IRQ_8 59
|
||||
#define GPIO_S0_DED_IRQ_9 60
|
||||
#define GPIO_S0_DED_IRQ_10 61
|
||||
#define GPIO_S0_DED_IRQ_11 62
|
||||
#define GPIO_S0_DED_IRQ_12 63
|
||||
#define GPIO_S0_DED_IRQ_13 64
|
||||
#define GPIO_S0_DED_IRQ_14 65
|
||||
#define GPIO_S0_DED_IRQ_15 66
|
||||
#define GPIO_S5_DED_IRQ_0 67
|
||||
#define GPIO_S5_DED_IRQ_1 68
|
||||
#define GPIO_S5_DED_IRQ_2 69
|
||||
#define GPIO_S5_DED_IRQ_3 70
|
||||
#define GPIO_S5_DED_IRQ_4 71
|
||||
#define GPIO_S5_DED_IRQ_5 72
|
||||
#define GPIO_S5_DED_IRQ_6 73
|
||||
#define GPIO_S5_DED_IRQ_7 74
|
||||
#define GPIO_S5_DED_IRQ_8 75
|
||||
#define GPIO_S5_DED_IRQ_9 76
|
||||
#define GPIO_S5_DED_IRQ_10 77
|
||||
#define GPIO_S5_DED_IRQ_11 78
|
||||
#define GPIO_S5_DED_IRQ_12 79
|
||||
#define GPIO_S5_DED_IRQ_13 80
|
||||
#define GPIO_S5_DED_IRQ_14 81
|
||||
#define GPIO_S5_DED_IRQ_15 82
|
||||
/* DIRQs - Two levels of expansion to evaluate to numeric constants for ASL. */
|
||||
#define _GPIO_S0_DED_IRQ(slot) GPIO_S0_DED_IRQ_##slot
|
||||
#define _GPIO_S5_DED_IRQ(slot) GPIO_S5_DED_IRQ_##slot
|
||||
#define GPIO_S0_DED_IRQ(slot) _GPIO_S0_DED_IRQ(slot)
|
||||
#define GPIO_S5_DED_IRQ(slot) _GPIO_S5_DED_IRQ(slot)
|
||||
|
||||
/* PIC IRQ settings. */
|
||||
#define PIRQ_PIC_IRQDISABLE 0x0
|
||||
#define PIRQ_PIC_IRQ3 0x3
|
||||
#define PIRQ_PIC_IRQ4 0x4
|
||||
#define PIRQ_PIC_IRQ5 0x5
|
||||
#define PIRQ_PIC_IRQ6 0x6
|
||||
#define PIRQ_PIC_IRQ7 0x7
|
||||
#define PIRQ_PIC_IRQ9 0x9
|
||||
#define PIRQ_PIC_IRQ10 0xa
|
||||
#define PIRQ_PIC_IRQ11 0xb
|
||||
#define PIRQ_PIC_IRQ12 0xc
|
||||
#define PIRQ_PIC_IRQ14 0xe
|
||||
#define PIRQ_PIC_IRQ15 0xf
|
||||
|
||||
/* Overloaded term, but these values determine the per device route. */
|
||||
#define PIRQA 0
|
||||
#define PIRQB 1
|
||||
#define PIRQC 2
|
||||
#define PIRQD 3
|
||||
#define PIRQE 4
|
||||
#define PIRQF 5
|
||||
#define PIRQG 6
|
||||
#define PIRQH 7
|
||||
|
||||
/* These registers live behind the ILB_BASE_ADDRESS */
|
||||
#define ACTL 0x00
|
||||
# define SCIS_MASK 0x07
|
||||
# define SCIS_IRQ9 0x00
|
||||
# define SCIS_IRQ10 0x01
|
||||
# define SCIS_IRQ11 0x02
|
||||
# define SCIS_IRQ20 0x04
|
||||
# define SCIS_IRQ21 0x05
|
||||
# define SCIS_IRQ22 0x06
|
||||
# define SCIS_IRQ23 0x07
|
||||
|
||||
/* In each mainboard directory there should exist a header file irqroute.h that
|
||||
* defines the PCI_DEV_PIRQ_ROUTES and PIRQ_PIC_ROUTES macros which
|
||||
* consist of PCI_DEV_PIRQ_ROUTE and PIRQ_PIC entries. */
|
||||
|
||||
#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
|
||||
#include <stdint.h>
|
||||
|
||||
#define NUM_IR_DEVS 32
|
||||
#define NUM_PIRQS 8
|
||||
|
||||
struct baytrail_irq_route {
|
||||
/* Per device configuration. */
|
||||
uint16_t pcidev[NUM_IR_DEVS];
|
||||
/* Route path for each internal PIRQx in PIC mode. */
|
||||
uint8_t pic[NUM_PIRQS];
|
||||
};
|
||||
|
||||
extern const struct baytrail_irq_route global_baytrail_irq_route;
|
||||
|
||||
#define DEFINE_IRQ_ROUTES \
|
||||
const struct baytrail_irq_route global_baytrail_irq_route = { \
|
||||
.pcidev = { PCI_DEV_PIRQ_ROUTES, }, \
|
||||
.pic = { PIRQ_PIC_ROUTES, }, \
|
||||
}
|
||||
|
||||
#define PCI_DEV_PIRQ_ROUTE(dev_, a_, b_, c_, d_) \
|
||||
[dev_] = ((PIRQ ## d_) << 12) | ((PIRQ ## c_) << 8) | \
|
||||
((PIRQ ## b_) << 4) | ((PIRQ ## a_) << 0)
|
||||
|
||||
#define PIRQ_PIC(pirq_, pic_irq_) \
|
||||
[PIRQ ## pirq_] = PIRQ_PIC_IRQ ## pic_irq_
|
||||
|
||||
#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */
|
||||
|
||||
#endif /* _BAYTRAIL_IRQ_H_ */
|
54
src/soc/intel/braswell/include/soc/lpc.h
Normal file
54
src/soc/intel/braswell/include/soc/lpc.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 REVID 0x08
|
||||
#define ABASE 0x40
|
||||
#define PBASE 0x44
|
||||
#define GBASE 0x48
|
||||
#define IOBASE 0x4c
|
||||
#define IBASE 0x50
|
||||
#define SBASE 0x54
|
||||
#define MPBASE 0x58
|
||||
#define PUBASE 0x5c
|
||||
#define UART_CONT 0x80
|
||||
#define RCBA 0xf0
|
||||
|
||||
|
||||
#define RID_A_STEPPING_START 1
|
||||
#define RID_B_STEPPING_START 5
|
||||
#define RID_C_STEPPING_START 0xe
|
||||
enum baytrail_stepping {
|
||||
STEP_A0,
|
||||
STEP_A1,
|
||||
STEP_B0,
|
||||
STEP_B1,
|
||||
STEP_B2,
|
||||
STEP_B3,
|
||||
STEP_C0,
|
||||
};
|
||||
|
||||
/* Registers behind the RCBA_BASE_ADDRESS bar. */
|
||||
#define GCS 0x00
|
||||
# define BILD (1 << 0)
|
||||
|
||||
#endif /* _BAYTRAIL_LPC_H_ */
|
107
src/soc/intel/braswell/include/soc/mrc_wrapper.h
Normal file
107
src/soc/intel/braswell/include/soc/mrc_wrapper.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 5
|
||||
|
||||
#define NUM_CHANNELS 2
|
||||
|
||||
/* Provide generic x86 calling conventions. */
|
||||
#define ABI_X86 __attribute((regparm(0)))
|
||||
|
||||
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,
|
||||
INVALID_CPU_ODT_SETTING = -7,
|
||||
INVALID_DRAM_ODT_SETTING = -8,
|
||||
};
|
||||
|
||||
struct mrc_mainboard_params {
|
||||
int dram_type;
|
||||
int dram_info_location; /* DRAM_INFO_* */
|
||||
int dram_is_slotted; /* mobo has DRAM slots. */
|
||||
/*
|
||||
* The below ODT settings are only honored when !dram_is_slotted.
|
||||
* Additionally, weaker_odt_settings being non-zero causes
|
||||
* cpu_odt_value to not be honored as weaker_odt_settings have a
|
||||
* special training path.
|
||||
*/
|
||||
int weaker_odt_settings;
|
||||
/* Allowed settings: 60, 80, 100, 120, and 150. */
|
||||
int cpu_odt_value;
|
||||
/* Allowed settings: 60 and 120. */
|
||||
int dram_odt_value;
|
||||
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 ABI_X86 (*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. */
|
||||
int rmt_enabled; /* Enable RMT training + prints. */
|
||||
int io_hole_mb; /* Size of IO hole in MiB. */
|
||||
|
||||
/* Outputs */
|
||||
void *txe_base_address;
|
||||
int data_to_save_size;
|
||||
void *data_to_save;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Call into wrapper. */
|
||||
typedef int ABI_X86 (*mrc_wrapper_entry_t)(struct mrc_params *);
|
||||
|
||||
#endif /* _MRC_WRAPPER_H_ */
|
51
src/soc/intel/braswell/include/soc/msr.h
Normal file
51
src/soc/intel/braswell/include/soc/msr.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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_MSR_H_
|
||||
#define _BAYTRAIL_MSR_H_
|
||||
|
||||
#define MSR_IA32_PLATFORM_ID 0x17
|
||||
#define MSR_BSEL_CR_OVERCLOCK_CONTROL 0xcd
|
||||
#define MSR_PLATFORM_INFO 0xce
|
||||
#define MSR_PMG_CST_CONFIG_CONTROL 0xe2
|
||||
#define SINGLE_PCTL (1 << 11)
|
||||
#define MSR_POWER_MISC 0x120
|
||||
#define ENABLE_ULFM_AUTOCM_MASK (1 << 2)
|
||||
#define ENABLE_INDP_AUTOCM_MASK (1 << 3)
|
||||
#define MSR_IA32_PERF_CTL 0x199
|
||||
#define MSR_IA32_MISC_ENABLES 0x1a0
|
||||
#define MSR_POWER_CTL 0x1fc
|
||||
#define MSR_PKG_POWER_SKU_UNIT 0x606
|
||||
#define MSR_PKG_POWER_LIMIT 0x610
|
||||
#define MSR_PP1_POWER_LIMIT 0x638
|
||||
#define MSR_IACORE_RATIOS 0x66a
|
||||
#define MSR_IACORE_TURBO_RATIOS 0x66c
|
||||
#define MSR_IACORE_VIDS 0x66b
|
||||
#define MSR_IACORE_TURBO_VIDS 0x66d
|
||||
#define MSR_PKG_TURBO_CFG1 0x670
|
||||
#define MSR_CPU_TURBO_WKLD_CFG1 0x671
|
||||
#define MSR_CPU_TURBO_WKLD_CFG2 0x672
|
||||
#define MSR_CPU_THERM_CFG1 0x673
|
||||
#define MSR_CPU_THERM_CFG2 0x674
|
||||
#define MSR_CPU_THERM_SENS_CFG 0x675
|
||||
|
||||
/* Read BCLK from MSR */
|
||||
unsigned bus_freq_khz(void);
|
||||
|
||||
#endif /* _BAYTRAIL_MSR_H_ */
|
78
src/soc/intel/braswell/include/soc/nvs.h
Normal file
78
src/soc/intel/braswell/include/soc/nvs.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _BAYTRAIL_NVS_H_
|
||||
#define _BAYTRAIL_NVS_H_
|
||||
|
||||
#include <vendorcode/google/chromeos/gnvs.h>
|
||||
#include <soc/device_nvs.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) */
|
||||
u8 pcnt; /* 0x11 - Processor Count */
|
||||
u8 tpmp; /* 0x12 - TPM Present and Enabled */
|
||||
u8 tlvl; /* 0x13 - Throttle Level */
|
||||
u8 ppcm; /* 0x14 - Maximum P-state usable by OS */
|
||||
u32 pm1i; /* 0x15 - System Wake Source - PM1 Index */
|
||||
u8 rsvd1[7];
|
||||
|
||||
/* Device Config */
|
||||
u8 s5u0; /* 0x20 - Enable USB0 in S5 */
|
||||
u8 s5u1; /* 0x21 - Enable USB1 in S5 */
|
||||
u8 s3u0; /* 0x22 - Enable USB0 in S3 */
|
||||
u8 s3u1; /* 0x23 - Enable USB1 in S3 */
|
||||
u8 tact; /* 0x24 - Thermal Active trip point */
|
||||
u8 tpsv; /* 0x25 - Thermal Passive trip point */
|
||||
u8 tcrt; /* 0x26 - Thermal Critical trip point */
|
||||
u8 dpte; /* 0x27 - Enable DPTF */
|
||||
u8 rsvd2[8];
|
||||
|
||||
/* Base Addresses */
|
||||
u32 obsolete_cmem; /* 0x30 - CBMEM TOC */
|
||||
u32 tolm; /* 0x34 - Top of Low Memory */
|
||||
u32 cbmc; /* 0x38 - coreboot memconsole */
|
||||
u8 rsvd3[196];
|
||||
|
||||
/* ChromeOS specific (0x100-0xfff)*/
|
||||
chromeos_acpi_t chromeos;
|
||||
|
||||
/* Baytrail LPSS (0x1000) */
|
||||
device_nvs_t dev;
|
||||
} __attribute__((packed)) global_nvs_t;
|
||||
|
||||
#ifdef __SMM__
|
||||
/* Used in SMM to find the ACPI GNVS address */
|
||||
global_nvs_t *smm_get_gnvs(void);
|
||||
#endif
|
||||
|
||||
#endif /* _BAYTRAIL_NVS_H_ */
|
64
src/soc/intel/braswell/include/soc/pattrs.h
Normal file
64
src/soc/intel/braswell/include/soc/pattrs.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 _PATTRS_H_
|
||||
#define _PATTRS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
|
||||
enum {
|
||||
IACORE_MIN,
|
||||
IACORE_LFM,
|
||||
IACORE_MAX,
|
||||
IACORE_TURBO,
|
||||
IACORE_END
|
||||
};
|
||||
|
||||
/* The pattrs structure is a common place to stash pertinent information
|
||||
* about the processor or platform. Instead of going to the source (msrs, cpuid)
|
||||
* every time an attribute is needed use the pattrs structure.
|
||||
*/
|
||||
struct pattrs {
|
||||
msr_t platform_id;
|
||||
msr_t platform_info;
|
||||
int iacore_ratios[IACORE_END];
|
||||
int iacore_vids[IACORE_END];
|
||||
uint32_t cpuid;
|
||||
int revid;
|
||||
int stepping;
|
||||
const void *microcode_patch;
|
||||
int address_bits;
|
||||
int num_cpus;
|
||||
unsigned bclk_khz;
|
||||
};
|
||||
|
||||
/* This is just to hide the abstraction w/o relying on how the underlying
|
||||
* storage is allocated. */
|
||||
#define PATTRS_GLOB_NAME __global_pattrs
|
||||
#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME
|
||||
extern DEFINE_PATTRS;
|
||||
|
||||
static inline const struct pattrs *pattrs_get(void)
|
||||
{
|
||||
return &PATTRS_GLOB_NAME;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _PATTRS_H_ */
|
155
src/soc/intel/braswell/include/soc/pci_devs.h
Normal file
155
src/soc/intel/braswell/include/soc/pci_devs.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 0x0
|
||||
#define SOC_FUNC 0
|
||||
# define SOC_DEVID 0x0f00
|
||||
|
||||
/* Graphics and Display */
|
||||
#define GFX_DEV 0x2
|
||||
#define GFX_FUNC 0
|
||||
# define GFX_DEVID 0x0f31
|
||||
|
||||
/* SDIO Port */
|
||||
#define SDIO_DEV 0x11
|
||||
#define SDIO_FUNC 0
|
||||
# define SDIO_DEVID 0x0f15
|
||||
|
||||
/* SD Port */
|
||||
#define SD_DEV 0x12
|
||||
#define SD_FUNC 0
|
||||
# define SD_DEVID 0x0f16
|
||||
|
||||
/* SATA */
|
||||
#define SATA_DEV 0x13
|
||||
#define SATA_FUNC 0
|
||||
#define IDE1_DEVID 0x0f20
|
||||
#define IDE2_DEVID 0x0f21
|
||||
#define AHCI1_DEVID 0x0f22
|
||||
#define AHCI2_DEVID 0x0f23
|
||||
|
||||
/* xHCI */
|
||||
#define XHCI_DEV 0x14
|
||||
#define XHCI_FUNC 0
|
||||
# define XHCI_DEVID 0x0f35
|
||||
|
||||
/* LPE Audio */
|
||||
#define LPE_DEV 0x15
|
||||
#define LPE_FUNC 0
|
||||
# define LPE_DEVID 0x0f28
|
||||
|
||||
/* MMC Port */
|
||||
#define MMC_DEV 0x17
|
||||
#define MMC_FUNC 0
|
||||
# define MMC_DEVID 0x0f50
|
||||
|
||||
/* Serial IO 1 */
|
||||
#define SIO1_DEV 0x18
|
||||
# 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 0x1a
|
||||
#define TXE_FUNC 0
|
||||
# define TXE_DEVID 0x0f18
|
||||
|
||||
/* HD Audio */
|
||||
#define HDA_DEV 0x1b
|
||||
#define HDA_FUNC 0
|
||||
# define HDA_DEVID 0x0f04
|
||||
|
||||
/* PCIe Ports */
|
||||
#define PCIE_DEV 0x1c
|
||||
# define PCIE_PORT1_DEV PCIE_DEV
|
||||
# define PCIE_PORT1_FUNC 0
|
||||
# define PCIE_PORT1_DEVID 0x0f48
|
||||
# define PCIE_PORT2_DEV PCIE_DEV
|
||||
# define PCIE_PORT2_FUNC 1
|
||||
# define PCIE_PORT2_DEVID 0x0f4a
|
||||
# define PCIE_PORT3_DEV PCIE_DEV
|
||||
# define PCIE_PORT3_FUNC 2
|
||||
# define PCIE_PORT3_DEVID 0x0f4c
|
||||
# define PCIE_PORT4_DEV PCIE_DEV
|
||||
# define PCIE_PORT4_FUNC 3
|
||||
# define PCIE_PORT4_DEVID 0x0f4e
|
||||
|
||||
/* EHCI */
|
||||
#define EHCI_DEV 0x1d
|
||||
#define EHCI_FUNC 0
|
||||
# define EHCI_DEVID 0x0f34
|
||||
|
||||
/* Serial IO 2 */
|
||||
#define SIO2_DEV 0x1e
|
||||
# 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 0x1f
|
||||
# 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_ */
|
102
src/soc/intel/braswell/include/soc/pcie.h
Normal file
102
src/soc/intel/braswell/include/soc/pcie.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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_PCIE_H_
|
||||
#define _BAYTRAIL_PCIE_H_
|
||||
|
||||
/* PCIe root port config space registers. */
|
||||
#define XCAP 0x40
|
||||
# define SI (1 << 24)
|
||||
#define DCAP 0x44
|
||||
# define MPS_MASK 0x7
|
||||
#define DCTL_DSTS 0x48
|
||||
# define URE (1 << 3)
|
||||
# define FEE (1 << 2)
|
||||
# define NFE (1 << 1)
|
||||
# define CEE (1 << 0)
|
||||
#define LCAP 0x4c
|
||||
# define L1EXIT_SHIFT 15
|
||||
# define L1EXIT_MASK (0x7 << L1EXIT_SHIFT)
|
||||
#define LCTL 0x50
|
||||
# define CCC (1 << 6)
|
||||
# define RL (1 << 5)
|
||||
# define LD (1 << 4)
|
||||
#define LSTS 0x52
|
||||
#define SLCAP 0x54
|
||||
# define SLN_SHIFT 19
|
||||
# define SLS_SHIFT 15
|
||||
# define SLV_SHIFT 7
|
||||
# define HPC (1 << 6)
|
||||
# define HPS (1 << 5)
|
||||
#define SLCTL_SLSTS 0x58
|
||||
# define PDS (1 << 22)
|
||||
#define DCAP2 0x64
|
||||
# define OBFFS (0x3 << 18)
|
||||
# define LTRMS (1 << 11)
|
||||
#define DSTS2 0x68
|
||||
# define OBFFEN (3 << 13)
|
||||
# define LTRME (1 << 10)
|
||||
# define CTD (1 << 4)
|
||||
#define CHCFG 0xd0
|
||||
# define UPSD (1 << 24)
|
||||
# define UNRS (1 << 15)
|
||||
# define UPRS (1 << 14)
|
||||
#define MPC2 0xd4
|
||||
# define IPF (1 << 11)
|
||||
# define LSTP (1 << 6)
|
||||
# define EOIFD (1 << 1)
|
||||
#define MPC 0xd8
|
||||
# define CCEL_SHIFT 15
|
||||
# define CCEL_MASK (0x7 << CCEL_SHIFT)
|
||||
#define RPPGEN 0xe0
|
||||
# define RPSCGEN (1 << 15)
|
||||
# define LCLKREQEN (1 << 13)
|
||||
# define BBCLKREQEN (1 << 12)
|
||||
# define SRDLCGEN (1 << 11)
|
||||
# define SRDBCGEN (1 << 10)
|
||||
# define RPDLCGEN (1 << 9)
|
||||
# define RPDBCGEN (1 << 8)
|
||||
#define PWRCTL 0xe8
|
||||
# define RPL1SQPOL (1 << 1)
|
||||
# define RPDTSQPOL (1 << 0)
|
||||
#define PHYCTL2_IOSFBCTL 0xf4
|
||||
# define PLL_OFF_EN (1 << 8)
|
||||
# define TDFT (3 << 14)
|
||||
# define TXCFGCHWAIT (3 << 12)
|
||||
# define SIID (3 << 26)
|
||||
#define STRPFUSECFG 0xfc
|
||||
# define LANECFG_SHIFT 14
|
||||
# define LANECFG_MASK (0x3 << LANECFG_SHIFT)
|
||||
#define AERCH 0x100
|
||||
#define NFTS 0x314
|
||||
#define L0SC 0x318
|
||||
#define CFG2 0x320
|
||||
# define CSREN (1 << 22)
|
||||
# define LATGC_SHIFT 6
|
||||
# define LATGC_MASK (0x7 << LATGC_SHIFT)
|
||||
#define PCIEDBG 0x324
|
||||
# define SPCE (1 << 5)
|
||||
#define PCIESTS1 0x328
|
||||
#define PCIEALC 0x338
|
||||
#define RTP 0x33c
|
||||
#define PHYCTL4 0x408
|
||||
# define SQDIS (1 << 27)
|
||||
|
||||
#define PCIE_ROOT_PORT_COUNT 4
|
||||
#endif /* _BAYTRAIL_PCIE_H_ */
|
303
src/soc/intel/braswell/include/soc/pmc.h
Normal file
303
src/soc/intel/braswell/include/soc/pmc.h
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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 PRSTS 0x00
|
||||
# define PMC_WDT_STS (1 << 15)
|
||||
# define SEC_GBLRST_STS (1 << 7)
|
||||
# define SEC_WDT_STS (1 << 6)
|
||||
# define WOL_OVR_WK_STS (1 << 5)
|
||||
# define PMC_WAKE_STS (1 << 4)
|
||||
#define PMC_CFG 0x08
|
||||
# define SPS (1 << 5)
|
||||
# define NO_REBOOT (1 << 4)
|
||||
# define SX_ENT_TO_EN (1 << 3)
|
||||
# define TIMING_T581_SHIFT (0)
|
||||
# define TIMING_T581_MASK (3 << TIMING_T581_SHIFT)
|
||||
# define TIMING_T581_10uS (0 << TIMING_T581_SHIFT)
|
||||
# define TIMING_T581_100uS (1 << TIMING_T581_SHIFT)
|
||||
# define TIMING_T581_1mS (2 << TIMING_T581_SHIFT)
|
||||
# define TIMING_T581_10mS (3 << TIMING_T581_SHIFT)
|
||||
#define VLV_PM_STS 0x0c
|
||||
# define PMC_MSG_FULL_STS (1 << 24)
|
||||
# define PMC_MSG_4_FULL_STS (1 << 23)
|
||||
# define PMC_MSG_3_FULL_STS (1 << 22)
|
||||
# define PMC_MSG_2_FULL_STS (1 << 21)
|
||||
# define PMC_MSG_1_FULL_STS (1 << 20)
|
||||
# define CODE_REQ (1 << 8)
|
||||
# define HPR_ENT_TO (1 << 2)
|
||||
# define SX_ENT_TO (1 << 1)
|
||||
#define GEN_PMCON1 0x20
|
||||
# define UART_EN (1 << 24)
|
||||
# define DISB (1 << 23)
|
||||
# define MEM_SR (1 << 21)
|
||||
# define SRS (1 << 20)
|
||||
# define CTS (1 << 19)
|
||||
# define MS4V (1 << 18)
|
||||
# define PWR_FLR (1 << 16)
|
||||
# define PME_B0_S5_DIS (1 << 15)
|
||||
# define SUS_PWR_FLR (1 << 14)
|
||||
# define WOL_EN_OVRD (1 << 13)
|
||||
# define DIS_SLP_X_STRCH_SUS_UP (1 << 12)
|
||||
# define GEN_RST_STS (1 << 9)
|
||||
# define RPS (1 << 2)
|
||||
# define AFTERG3_EN (1 << 0)
|
||||
#define GEN_PMCON2 0x24
|
||||
# define SLPSX_STR_POL_LOCK (1 << 18)
|
||||
# define BIOS_PCI_EXP_EN (1 << 10)
|
||||
# define PWRBTN_LVL (1 << 9)
|
||||
# define SMI_LOCK (1 << 4)
|
||||
#define ETR 0x48
|
||||
# define CF9LOCK (1 << 31)
|
||||
# define LTR_DEF (1 << 22)
|
||||
# define IGNORE_HPET (1 << 21)
|
||||
# define CF9GR (1 << 20)
|
||||
# define CWORWRE (1 << 18)
|
||||
#define FUNC_DIS 0x34
|
||||
# define SIO_DMA2_DIS (1 << 0)
|
||||
# define PWM1_DIS (1 << 1)
|
||||
# define PWM2_DIS (1 << 2)
|
||||
# define HSUART1_DIS (1 << 3)
|
||||
# define HSUART2_DIS (1 << 4)
|
||||
# define SPI_DIS (1 << 5)
|
||||
# define SDIO_DIS (1 << 9)
|
||||
# define SD_DIS (1 << 10)
|
||||
# define MMC_DIS (1 << 11)
|
||||
# define HDA_DIS (1 << 12)
|
||||
# define LPE_DIS (1 << 13)
|
||||
# define OTG_DIS (1 << 14)
|
||||
# define XHCI_DIS (1 << 15)
|
||||
# define SATA_DIS (1 << 17)
|
||||
# define EHCI_DIS (1 << 18)
|
||||
# define TXE_DIS (1 << 19)
|
||||
# define PCIE_PORT1_DIS (1 << 20)
|
||||
# define PCIE_PORT2_DIS (1 << 21)
|
||||
# define PCIE_PORT3_DIS (1 << 22)
|
||||
# define PCIE_PORT4_DIS (1 << 23)
|
||||
# define SIO_DMA1_DIS (1 << 24)
|
||||
# define I2C1_DIS (1 << 25)
|
||||
# define I2C2_DIS (1 << 26)
|
||||
# define I2C3_DIS (1 << 27)
|
||||
# define I2C4_DIS (1 << 28)
|
||||
# define I2C5_DIS (1 << 29)
|
||||
# define I2C6_DIS (1 << 30)
|
||||
# define I2C7_DIS (1 << 31)
|
||||
#define FUNC_DIS2 0x38
|
||||
# define USH_SS_PHY_DIS (1 << 2)
|
||||
# define OTG_SS_PHY_DIS (1 << 1)
|
||||
# define SMBUS_DIS (1 << 0)
|
||||
#define GPIO_ROUT 0x58
|
||||
# define ROUTE_MASK 3
|
||||
# define ROUTE_NONE 0
|
||||
# define ROUTE_SMI 1
|
||||
# define ROUTE_SCI 2
|
||||
#define PLT_CLK_CTL_0 0x60
|
||||
#define PLT_CLK_CTL_1 0x64
|
||||
#define PLT_CLK_CTL_2 0x68
|
||||
#define PLT_CLK_CTL_3 0x6c
|
||||
#define PLT_CLK_CTL_4 0x70
|
||||
#define PLT_CLK_CTL_5 0x74
|
||||
# define CLK_FREQ_25MHZ (0x0 << 2)
|
||||
# define CLK_FREQ_19P2MHZ (0x1 << 2)
|
||||
# define CLK_CTL_D3_LPE (0x0 << 0)
|
||||
# define CLK_CTL_ON (0x1 << 0)
|
||||
# define CLK_CTL_OFF (0x2 << 0)
|
||||
#define PME_STS 0xc0
|
||||
#define GPE_LEVEL_EDGE 0xc4
|
||||
# define GPE_EDGE 0
|
||||
# define GPE_LEVEL 1
|
||||
#define GPE_POLARITY 0xc8
|
||||
# define GPE_ACTIVE_HIGH 1
|
||||
# define GPE_ACTIVE_LOW 0
|
||||
#define LOCK 0xcc
|
||||
|
||||
/* IO Mapped registers behind ACPI_BASE_ADDRESS */
|
||||
#define PM1_STS 0x00
|
||||
#define WAK_STS (1 << 15)
|
||||
#define PCIEXPWAK_STS (1 << 14)
|
||||
#define USB_STS (1 << 13)
|
||||
#define PRBTNOR_STS (1 << 11)
|
||||
#define RTC_STS (1 << 10)
|
||||
#define PWRBTN_STS (1 << 8)
|
||||
#define GBL_STS (1 << 5)
|
||||
#define TMROF_STS (1 << 0)
|
||||
#define PM1_EN 0x02
|
||||
#define PCIEXPWAK_DIS (1 << 14)
|
||||
#define USB_WAKE_EN (1 << 13)
|
||||
#define RTC_EN (1 << 10)
|
||||
#define PWRBTN_EN (1 << 8)
|
||||
#define GBL_EN (1 << 5)
|
||||
#define TMROF_EN (1 << 0)
|
||||
#define PM1_CNT 0x04
|
||||
#define SLP_EN (1 << 13)
|
||||
#define SLP_TYP_SHIFT 10
|
||||
#define SLP_TYP (7 << SLP_TYP_SHIFT)
|
||||
#define SLP_TYP_S0 0
|
||||
#define SLP_TYP_S1 1
|
||||
#define SLP_TYP_S3 5
|
||||
#define SLP_TYP_S4 6
|
||||
#define SLP_TYP_S5 7
|
||||
#define GBL_RLS (1 << 2)
|
||||
#define BM_RLD (1 << 1)
|
||||
#define SCI_EN (1 << 0)
|
||||
#define PM1_TMR 0x08
|
||||
#define GPE0_STS 0x20
|
||||
#define CORE_GPIO_STS7 (1 << 31)
|
||||
#define CORE_GPIO_STS6 (1 << 30)
|
||||
#define CORE_GPIO_STS5 (1 << 29)
|
||||
#define CORE_GPIO_STS4 (1 << 28)
|
||||
#define CORE_GPIO_STS3 (1 << 27)
|
||||
#define CORE_GPIO_STS2 (1 << 26)
|
||||
#define CORE_GPIO_STS1 (1 << 25)
|
||||
#define CORE_GPIO_STS0 (1 << 24)
|
||||
#define SUS_GPIO_STS7 (1 << 23)
|
||||
#define SUS_GPIO_STS6 (1 << 22)
|
||||
#define SUS_GPIO_STS5 (1 << 21)
|
||||
#define SUS_GPIO_STS4 (1 << 20)
|
||||
#define SUS_GPIO_STS3 (1 << 19)
|
||||
#define SUS_GPIO_STS2 (1 << 18)
|
||||
#define SUS_GPIO_STS1 (1 << 17)
|
||||
#define SUS_GPIO_STS0 (1 << 16)
|
||||
#define PME_B0_STS (1 << 13)
|
||||
#define BATLOW_STS (1 << 10)
|
||||
#define PCI_EXP_STS (1 << 9)
|
||||
#define PCIE_WAKE3_STS (1 << 8)
|
||||
#define PCIE_WAKE2_STS (1 << 7)
|
||||
#define PCIE_WAKE1_STS (1 << 6)
|
||||
#define GUNIT_SCI_STS (1 << 5)
|
||||
#define PUNIT_SCI_STS (1 << 4)
|
||||
#define PCIE_WAKE0_STS (1 << 3)
|
||||
#define SWGPE_STS (1 << 2)
|
||||
#define HOT_PLUG_STS (1 << 1)
|
||||
#define GPE0_EN 0x28
|
||||
#define CORE_GPIO_EN7 (1 << 31)
|
||||
#define CORE_GPIO_EN6 (1 << 30)
|
||||
#define CORE_GPIO_EN5 (1 << 29)
|
||||
#define CORE_GPIO_EN4 (1 << 28)
|
||||
#define CORE_GPIO_EN3 (1 << 27)
|
||||
#define CORE_GPIO_EN2 (1 << 26)
|
||||
#define CORE_GPIO_EN1 (1 << 25)
|
||||
#define CORE_GPIO_EN0 (1 << 24)
|
||||
#define SUS_GPIO_EN7_BIT 23
|
||||
#define SUS_GPIO_EN7 (1 << SUS_GPIO_EN7_BIT)
|
||||
#define SUS_GPIO_EN6_BIT 22
|
||||
#define SUS_GPIO_EN6 (1 << SUS_GPIO_EN6_BIT)
|
||||
#define SUS_GPIO_EN5_BIT 21
|
||||
#define SUS_GPIO_EN5 (1 << SUS_GPIO_EN5_BIT)
|
||||
#define SUS_GPIO_EN4_BIT 20
|
||||
#define SUS_GPIO_EN4 (1 << SUS_GPIO_EN4_BIT)
|
||||
#define SUS_GPIO_EN3_BIT 19
|
||||
#define SUS_GPIO_EN3 (1 << SUS_GPIO_EN3_BIT)
|
||||
#define SUS_GPIO_EN2_BIT 18
|
||||
#define SUS_GPIO_EN2 (1 << SUS_GPIO_EN2_BIT)
|
||||
#define SUS_GPIO_EN1_BIT 17
|
||||
#define SUS_GPIO_EN1 (1 << SUS_GPIO_EN1_BIT)
|
||||
#define SUS_GPIO_EN0_BIT 16
|
||||
#define SUS_GPIO_EN0 (1 << SUS_GPIO_EN0_BIT)
|
||||
#define PME_B0_EN (1 << 13)
|
||||
#define BATLOW_EN (1 << 10)
|
||||
#define PCI_EXP_EN (1 << 9)
|
||||
#define PCIE_WAKE3_EN (1 << 8)
|
||||
#define PCIE_WAKE2_EN (1 << 7)
|
||||
#define PCIE_WAKE1_EN (1 << 6)
|
||||
#define PCIE_WAKE0_EN (1 << 3)
|
||||
#define SWGPE_EN (1 << 2)
|
||||
#define HOT_PLUG_EN (1 << 1)
|
||||
#define _ACPI_ENABLE_WAKE_SUS_GPIO(x) SUS_GPIO_EN##x##_BIT
|
||||
#define ACPI_ENABLE_WAKE_SUS_GPIO(x) _ACPI_ENABLE_WAKE_SUS_GPIO(x)
|
||||
#define SMI_EN 0x30
|
||||
#define INTEL_USB2_EN (1 << 18) // Intel-Specific USB2 SMI logic
|
||||
#define USB_EN (1 << 17) // Legacy USB2 SMI logic
|
||||
#define PERIODIC_EN (1 << 14) // SMI on PERIODIC_STS in SMI_STS
|
||||
#define TCO_EN (1 << 13) // Enable TCO Logic (BIOSWE et al)
|
||||
#define BIOS_RLS (1 << 7) // asserts SCI on bit set
|
||||
#define SWSMI_TMR_EN (1 << 6) // start software smi timer on bit set
|
||||
#define APMC_EN (1 << 5) // Writes to APM_CNT cause SMI#
|
||||
#define SLP_SMI_EN (1 << 4) // Write to SLP_EN in PM1_CNT asserts SMI#
|
||||
#define BIOS_EN (1 << 2) // Assert SMI# on setting GBL_RLS bit
|
||||
#define EOS (1 << 1) // End of SMI (deassert SMI#)
|
||||
#define GBL_SMI_EN (1 << 0) // SMI# generation at all?
|
||||
#define SMI_STS 0x34
|
||||
#define ALT_GPIO_SMI 0x38
|
||||
#define UPRWC 0x3c
|
||||
# define UPRWC_WR_EN (1 << 1) // USB Per-Port Registers Write Enable
|
||||
#define GPE_CTRL 0x40
|
||||
#define PM2A_CNT_BLK 0x50
|
||||
#define TCO_RLD 0x60
|
||||
#define TCO_STS 0x64
|
||||
# define SECOND_TO_STS (1 << 17)
|
||||
# define TCO_TIMEOUT (1 << 3)
|
||||
#define TCO1_CNT 0x68
|
||||
# define TCO_LOCK (1 << 12)
|
||||
# define TCO_TMR_HALT (1 << 11)
|
||||
#define TCO_TMR 0x70
|
||||
|
||||
/* I/O ports */
|
||||
#define RST_CNT 0xcf9
|
||||
# define FULL_RST (1 << 3)
|
||||
# define RST_CPU (1 << 2)
|
||||
# define SYS_RST (1 << 1)
|
||||
|
||||
#if !defined(__ASSEMBLER__) && !defined(__ACPI__)
|
||||
|
||||
/* Track power state from reset to log events. */
|
||||
struct chipset_power_state {
|
||||
uint16_t pm1_sts;
|
||||
uint16_t pm1_en;
|
||||
uint32_t pm1_cnt;
|
||||
uint32_t gpe0_sts;
|
||||
uint32_t gpe0_en;
|
||||
uint32_t tco_sts;
|
||||
uint32_t prsts;
|
||||
uint32_t gen_pmcon1;
|
||||
uint32_t gen_pmcon2;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Power Management Utility Functions. */
|
||||
uint16_t get_pmbase(void);
|
||||
uint32_t clear_smi_status(void);
|
||||
uint16_t clear_pm1_status(void);
|
||||
uint32_t clear_tco_status(void);
|
||||
uint32_t clear_gpe_status(void);
|
||||
uint32_t clear_alt_status(void);
|
||||
void clear_pmc_status(void);
|
||||
void enable_smi(uint32_t mask);
|
||||
void disable_smi(uint32_t mask);
|
||||
void enable_pm1(uint16_t events);
|
||||
void enable_pm1_control(uint32_t mask);
|
||||
void disable_pm1_control(uint32_t mask);
|
||||
void enable_gpe(uint32_t mask);
|
||||
void disable_gpe(uint32_t mask);
|
||||
void disable_all_gpe(void);
|
||||
|
||||
#if CONFIG_ELOG
|
||||
void southcluster_log_state(void);
|
||||
#else
|
||||
static inline void southcluster_log_state(void) {}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__ASSEMBLER__) && !defined(__ACPI__) */
|
||||
|
||||
#endif /* _BAYTRAIL_PMC_H_ */
|
42
src/soc/intel/braswell/include/soc/ramstage.h
Normal file
42
src/soc/intel/braswell/include/soc/ramstage.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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_RAMSTAGE_H_
|
||||
#define _BAYTRAIL_RAMSTAGE_H_
|
||||
|
||||
#include <device/device.h>
|
||||
#include <soc/intel/baytrail/chip.h>
|
||||
|
||||
/* The baytrail_init_pre_device() function is called prior to device
|
||||
* initialization, but it's after console and cbmem has been reinitialized. */
|
||||
void baytrail_init_pre_device(struct soc_intel_baytrail_config *config);
|
||||
void baytrail_init_cpus(device_t dev);
|
||||
void set_max_freq(void);
|
||||
void southcluster_enable_dev(device_t dev);
|
||||
#if CONFIG_HAVE_REFCODE_BLOB
|
||||
void baytrail_run_reference_code(void);
|
||||
#else
|
||||
static inline void baytrail_run_reference_code(void) {}
|
||||
#endif
|
||||
void baytrail_init_scc(void);
|
||||
void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index);
|
||||
|
||||
extern struct pci_operations soc_pci_ops;
|
||||
|
||||
#endif /* _BAYTRAIL_RAMSTAGE_H_ */
|
36
src/soc/intel/braswell/include/soc/reset.h
Normal file
36
src/soc/intel/braswell/include/soc/reset.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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_RESET_H_
|
||||
#define _BAYTRAIL_RESET_H_
|
||||
#include <reset.h>
|
||||
|
||||
/* Bay Trail has the following types of resets:
|
||||
* - Soft reset (INIT# to cpu) - write 0x1 to I/O 0x92
|
||||
* - Soft reset (INIT# to cpu)- write 0x4 to I/0 0xcf9
|
||||
* - Cold reset (S0->S5->S0) - write 0xe to I/0 0xcf9
|
||||
* - Warm reset (PMC_PLTRST# assertion) - write 0x6 to I/O 0xcf9
|
||||
* - Global reset (S0->S5->S0 with TXE reset) - write 0x6 or 0xe to 0xcf9 but
|
||||
* with ETR[20] set.
|
||||
*/
|
||||
|
||||
void cold_reset(void);
|
||||
void warm_reset(void);
|
||||
|
||||
#endif /* _BAYTRAIL_RESET_H_ */
|
54
src/soc/intel/braswell/include/soc/romstage.h
Normal file
54
src/soc/intel/braswell/include/soc/romstage.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 <stdint.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <soc/mrc_wrapper.h>
|
||||
|
||||
struct romstage_params {
|
||||
unsigned long bist;
|
||||
struct mrc_params *mrc_params;
|
||||
};
|
||||
|
||||
void mainboard_romstage_entry(struct romstage_params *params);
|
||||
void romstage_common(struct romstage_params *params);
|
||||
void * asmlinkage romstage_main(unsigned long bist, uint32_t tsc_lo,
|
||||
uint32_t tsc_high);
|
||||
void asmlinkage romstage_after_car(void);
|
||||
void raminit(struct mrc_params *mp, int prev_sleep_state);
|
||||
void gfx_init(void);
|
||||
void tco_disable(void);
|
||||
void punit_init(void);
|
||||
void set_max_freq(void);
|
||||
int early_spi_read_wpsr(u8 *sr);
|
||||
|
||||
#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_ */
|
26
src/soc/intel/braswell/include/soc/sata.h
Normal file
26
src/soc/intel/braswell/include/soc/sata.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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_SATA_H
|
||||
#define BAYTRAIL_SATA_H
|
||||
|
||||
#define SATA_SIRI 0xa0
|
||||
#define SATA_SIRD 0xa4
|
||||
|
||||
#endif
|
49
src/soc/intel/braswell/include/soc/smm.h
Normal file
49
src/soc/intel/braswell/include/soc/smm.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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_SMM_H_
|
||||
#define _BAYTRAIL_SMM_H_
|
||||
|
||||
/* There is a bug in the order of Kconfig includes in that arch/x86/Kconfig
|
||||
* is included after chipset code. This causes the chipset's Kconfig to be
|
||||
* clobbered by the arch/x86/Kconfig if they have the same name. */
|
||||
static inline int smm_region_size(void)
|
||||
{
|
||||
/* Make it 8MiB by default. */
|
||||
if (CONFIG_SMM_TSEG_SIZE == 0)
|
||||
return (8 << 20);
|
||||
return CONFIG_SMM_TSEG_SIZE;
|
||||
}
|
||||
|
||||
uintptr_t smm_region_start(void);
|
||||
|
||||
#if !defined(__PRE_RAM__) && !defined(__SMM___)
|
||||
#include <stdint.h>
|
||||
void southcluster_smm_clear_state(void);
|
||||
void southcluster_smm_enable_smi(void);
|
||||
void southcluster_smm_save_param(int param, uint32_t data);
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SMM_SAVE_PARAM_GPIO_ROUTE = 0,
|
||||
SMM_SAVE_PARAM_PCIE_WAKE_ENABLE,
|
||||
SMM_SAVE_PARAM_COUNT
|
||||
};
|
||||
|
||||
#endif /* _BAYTRAIL_SMM_H_ */
|
74
src/soc/intel/braswell/include/soc/spi.h
Normal file
74
src/soc/intel/braswell/include/soc/spi.h
Normal file
@ -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
|
||||
*/
|
||||
|
||||
#ifndef _BAYTRAIL_SPI_H_
|
||||
#define _BAYTRAIL_SPI_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* These registers live behind SPI_BASE_ADDRESS. */
|
||||
#define HSFSTS 0x04
|
||||
#define FDATA0 0x10
|
||||
# define FLOCKDN (0x1 << 15)
|
||||
#define SSFS 0x90
|
||||
# define CYCLE_DONE_STATUS (0x1 << 2)
|
||||
# define FLASH_CYCLE_ERROR (0x1 << 3)
|
||||
#define SSFC 0x91
|
||||
# define SPI_CYCLE_GO (0x1 << 1)
|
||||
# define DATA_CYCLE (0x1 << 14)
|
||||
#define PREOP 0x94
|
||||
#define OPTYPE 0x96
|
||||
#define OPMENU0 0x98
|
||||
#define OPMENU1 0x9c
|
||||
#define LVSCC 0xc4
|
||||
# define VCL (0x1 << 23)
|
||||
# define EO(x) (((x) & 0xff) << 8)
|
||||
# define WG_1_BYTE (0x0 << 2)
|
||||
# define WG_64_BYTE (0x1 << 2)
|
||||
# define BES_256_BYTE (0x0 << 0)
|
||||
# define BES_4_KB (0x1 << 0)
|
||||
# define BES_8_KB (0x2 << 0)
|
||||
# define BES_64_KB (0x3 << 0)
|
||||
#define UVSCC 0xc8
|
||||
#define SCS 0xf8
|
||||
# define SMIWPEN (0x1 << 7)
|
||||
#define BCR 0xfc
|
||||
# define EISS (0x1 << 5)
|
||||
# define SRC_MASK (0x3 << 2)
|
||||
# define SRC_CACHE_NO_PREFETCH (0x0 << 2)
|
||||
# define SRC_NO_CACHE_NO_PREFETCH (0x1 << 2)
|
||||
# define SRC_CACHE_PREFETCH (0x2 << 2)
|
||||
# define BCR_LE (0x1 << 1)
|
||||
# define BCR_WPD (0x1 << 0)
|
||||
|
||||
/*
|
||||
* SPI lockdown configuration.
|
||||
*/
|
||||
struct spi_config {
|
||||
uint16_t preop;
|
||||
uint16_t optype;
|
||||
uint32_t opmenu[2];
|
||||
uint32_t lvscc;
|
||||
uint32_t uvscc;
|
||||
};
|
||||
|
||||
/* Return 0 on success < 0 on failure. */
|
||||
int mainboard_get_spi_config(struct spi_config *cfg);
|
||||
|
||||
#endif /* _BAYTRAIL_SPI_H_ */
|
56
src/soc/intel/braswell/include/soc/xhci.h
Normal file
56
src/soc/intel/braswell/include/soc/xhci.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_XHCI_H
|
||||
#define BAYTRAIL_XHCI_H
|
||||
|
||||
/* XHCI PCI Registers */
|
||||
#define XHCI_PWR_CTL_STS 0x74
|
||||
#define XHCI_USB2PR 0xd0
|
||||
#define XHCI_USB2PRM 0xd4
|
||||
#define XHCI_USB3PR 0xd8
|
||||
#define XHCI_USB3PRM 0xdc
|
||||
#define XHCI_USB2PDO 0xe4
|
||||
#define XHCI_USB3PDO 0xe8
|
||||
|
||||
/* XHCI Memory Registers */
|
||||
#define XHCI_USB3_PORTSC(port) (0x4e0 + (port * 0x10))
|
||||
# define XHCI_USB3_PORTSC_CHST (0x7f << 17)
|
||||
# define XHCI_USB3_PORTSC_WCE (1 << 25) /* Wake on Connect */
|
||||
# define XHCI_USB3_PORTSC_WDE (1 << 26) /* Wake on Disconnect */
|
||||
# define XHCI_USB3_PORTSC_WOE (1 << 27) /* Wake on Overcurrent */
|
||||
# define XHCI_USB3_PORTSC_WRC (1 << 19) /* Warm Reset Complete */
|
||||
# define XHCI_USB3_PORTSC_LWS (1 << 16) /* Link Write Strobe */
|
||||
# define XHCI_USB3_PORTSC_PED (1 << 1) /* Port Enabled/Disabled */
|
||||
# define XHCI_USB3_PORTSC_WPR (1 << 31) /* Warm Port Reset */
|
||||
# define XHCI_USB3_PORTSC_PLS (0xf << 5) /* Port Link State */
|
||||
# define XHCI_PLSR_DISABLED (4 << 5) /* Port is disabled */
|
||||
# define XHCI_PLSR_RXDETECT (5 << 5) /* Port is disconnected */
|
||||
# define XHCI_PLSR_POLLING (7 << 5) /* Port is polling */
|
||||
# define XHCI_PLSW_ENABLE (5 << 5) /* Enable port */
|
||||
|
||||
/* The Fuse register is incorrect for Baytrail-M so use hardcoded values */
|
||||
#define BYTM_USB2_PORT_COUNT 4
|
||||
#define BYTM_USB2_PORT_MAP 0xf
|
||||
#define BYTM_USB3_PORT_COUNT 1
|
||||
#define BYTM_USB3_PORT_MAP 0x1
|
||||
|
||||
#define XHCI_RESET_TIMEOUT 100000 /* 100ms */
|
||||
|
||||
#endif /* BAYTRAIL_XHCI_H */
|
287
src/soc/intel/braswell/iosf.c
Normal file
287
src/soc/intel/braswell/iosf.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* 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 <soc/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((u32 *)(IOSF_PCI_BASE + reg), value);
|
||||
}
|
||||
static inline uint32_t read_iosf_reg(int reg)
|
||||
{
|
||||
return read32((u32 *)(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
|
||||
|
||||
/* Common sequences for all the port accesses. */
|
||||
static uint32_t iosf_read_port(uint32_t cr, int reg)
|
||||
{
|
||||
cr |= IOSF_REG(reg) | IOSF_BYTE_EN;
|
||||
write_iosf_reg(MCRX_REG, IOSF_REG_UPPER(reg));
|
||||
write_iosf_reg(MCR_REG, cr);
|
||||
return read_iosf_reg(MDR_REG);
|
||||
}
|
||||
|
||||
static void iosf_write_port(uint32_t cr, int reg, uint32_t val)
|
||||
{
|
||||
cr |= IOSF_REG(reg) | IOSF_BYTE_EN;
|
||||
write_iosf_reg(MDR_REG, val);
|
||||
write_iosf_reg(MCRX_REG, IOSF_REG_UPPER(reg));
|
||||
write_iosf_reg(MCR_REG, cr);
|
||||
}
|
||||
|
||||
#define IOSF_READ(port) \
|
||||
IOSF_OPCODE(IOSF_OP_READ_##port) | IOSF_PORT(IOSF_PORT_##port)
|
||||
#define IOSF_WRITE(port) \
|
||||
IOSF_OPCODE(IOSF_OP_WRITE_##port) | IOSF_PORT(IOSF_PORT_##port)
|
||||
|
||||
uint32_t iosf_bunit_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(BUNIT), reg);
|
||||
}
|
||||
|
||||
void iosf_bunit_write(int reg, uint32_t val)
|
||||
{
|
||||
iosf_write_port(IOSF_WRITE(BUNIT), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_dunit_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(SYSMEMC), reg);
|
||||
}
|
||||
|
||||
uint32_t iosf_dunit_ch0_read(int reg)
|
||||
{
|
||||
return iosf_dunit_read(reg);
|
||||
}
|
||||
|
||||
uint32_t iosf_dunit_ch1_read(int reg)
|
||||
{
|
||||
uint32_t cr = IOSF_OPCODE(IOSF_OP_READ_SYSMEMC) |
|
||||
IOSF_PORT(IOSF_PORT_DUNIT_CH1);
|
||||
return iosf_read_port(cr, reg);
|
||||
}
|
||||
|
||||
void iosf_dunit_write(int reg, uint32_t val)
|
||||
{
|
||||
iosf_write_port(IOSF_WRITE(SYSMEMC), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_punit_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(PMC), reg);
|
||||
}
|
||||
|
||||
void iosf_punit_write(int reg, uint32_t val)
|
||||
{
|
||||
iosf_write_port(IOSF_WRITE(PMC), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_usbphy_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(USBPHY), reg);
|
||||
}
|
||||
|
||||
void iosf_usbphy_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(USBPHY), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_ushphy_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(USHPHY), reg);
|
||||
}
|
||||
|
||||
void iosf_ushphy_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(USHPHY), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_lpss_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(LPSS), reg);
|
||||
}
|
||||
|
||||
void iosf_lpss_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(LPSS), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_ccu_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(CCU), reg);
|
||||
}
|
||||
|
||||
void iosf_ccu_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(CCU), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_score_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(SCORE), reg);
|
||||
}
|
||||
|
||||
void iosf_score_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(SCORE), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_scc_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(SCC), reg);
|
||||
}
|
||||
|
||||
void iosf_scc_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(SCC), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_aunit_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(AUNIT), reg);
|
||||
}
|
||||
|
||||
void iosf_aunit_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(AUNIT), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_cpu_bus_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(CPU_BUS), reg);
|
||||
}
|
||||
|
||||
void iosf_cpu_bus_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(CPU_BUS), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_sec_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(SEC), reg);
|
||||
}
|
||||
|
||||
void iosf_sec_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(SEC), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port45_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x45), reg);
|
||||
}
|
||||
|
||||
void iosf_port45_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x45), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port46_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x46), reg);
|
||||
}
|
||||
|
||||
void iosf_port46_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x46), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port47_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x47), reg);
|
||||
}
|
||||
|
||||
void iosf_port47_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x47), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port55_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x55), reg);
|
||||
}
|
||||
|
||||
void iosf_port55_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x55), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port58_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x58), reg);
|
||||
}
|
||||
|
||||
void iosf_port58_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x58), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port59_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x59), reg);
|
||||
}
|
||||
|
||||
void iosf_port59_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x59), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_port5a_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0x5a), reg);
|
||||
}
|
||||
|
||||
void iosf_port5a_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0x5a), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_porta2_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(0xa2), reg);
|
||||
}
|
||||
|
||||
void iosf_porta2_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(0xa2), reg, val);
|
||||
}
|
||||
|
||||
uint32_t iosf_ssus_read(int reg)
|
||||
{
|
||||
return iosf_read_port(IOSF_READ(SSUS), reg);
|
||||
}
|
||||
|
||||
void iosf_ssus_write(int reg, uint32_t val)
|
||||
{
|
||||
return iosf_write_port(IOSF_WRITE(SSUS), reg, val);
|
||||
}
|
189
src/soc/intel/braswell/lpe.c
Normal file
189
src/soc/intel/braswell/lpe.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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 <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pattrs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include "chip.h"
|
||||
|
||||
|
||||
/* The LPE audio devices needs 1MiB of memory reserved aligned to a 512MiB
|
||||
* address. Just take 1MiB @ 512MiB. */
|
||||
#define FIRMWARE_PHYS_BASE (512 << 20)
|
||||
#define FIRMWARE_PHYS_LENGTH (1 << 20)
|
||||
#define FIRMWARE_PCI_REG_BASE 0xa8
|
||||
#define FIRMWARE_PCI_REG_LENGTH 0xac
|
||||
#define FIRMWARE_REG_BASE_C0 0x144000
|
||||
#define FIRMWARE_REG_LENGTH_C0 (FIRMWARE_REG_BASE_C0 + 4)
|
||||
|
||||
static void assign_device_nvs(device_t dev, u32 *field, unsigned index)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
res = find_resource(dev, index);
|
||||
if (res)
|
||||
*field = res->base;
|
||||
}
|
||||
|
||||
static void lpe_enable_acpi_mode(device_t dev)
|
||||
{
|
||||
static const struct reg_script ops[] = {
|
||||
/* Disable PCI interrupt, enable Memory and Bus Master */
|
||||
REG_PCI_OR32(PCI_COMMAND,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
|
||||
/* Enable ACPI mode */
|
||||
REG_IOSF_OR(IOSF_PORT_0x58, LPE_PCICFGCTR1,
|
||||
LPE_PCICFGCTR1_PCI_CFG_DIS |
|
||||
LPE_PCICFGCTR1_ACPI_INT_EN),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
global_nvs_t *gnvs;
|
||||
|
||||
/* Find ACPI NVS to update BARs */
|
||||
gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
if (!gnvs) {
|
||||
printk(BIOS_ERR, "Unable to locate Global NVS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save BAR0, BAR1, and firmware base to ACPI NVS */
|
||||
assign_device_nvs(dev, &gnvs->dev.lpe_bar0, PCI_BASE_ADDRESS_0);
|
||||
assign_device_nvs(dev, &gnvs->dev.lpe_bar1, PCI_BASE_ADDRESS_1);
|
||||
assign_device_nvs(dev, &gnvs->dev.lpe_fw, FIRMWARE_PCI_REG_BASE);
|
||||
|
||||
/* Device is enabled in ACPI mode */
|
||||
gnvs->dev.lpe_en = 1;
|
||||
|
||||
/* Put device in ACPI mode */
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
}
|
||||
|
||||
static void setup_codec_clock(device_t dev)
|
||||
{
|
||||
uint32_t reg;
|
||||
u32 *clk_reg;
|
||||
struct soc_intel_baytrail_config *config;
|
||||
const char *freq_str;
|
||||
|
||||
config = dev->chip_info;
|
||||
switch (config->lpe_codec_clk_freq) {
|
||||
case 19:
|
||||
freq_str = "19.2";
|
||||
reg = CLK_FREQ_19P2MHZ;
|
||||
break;
|
||||
case 25:
|
||||
freq_str = "25";
|
||||
reg = CLK_FREQ_25MHZ;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_DEBUG, "LPE codec clock not required.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Default to always running. */
|
||||
reg |= CLK_CTL_ON;
|
||||
|
||||
if (config->lpe_codec_clk_num < 0 || config->lpe_codec_clk_num > 5) {
|
||||
printk(BIOS_DEBUG, "Invalid LPE codec clock number.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "LPE Audio codec clock set to %sMHz.\n", freq_str);
|
||||
|
||||
clk_reg = (u32 *)(PMC_BASE_ADDRESS + PLT_CLK_CTL_0);
|
||||
clk_reg += config->lpe_codec_clk_num;
|
||||
|
||||
write32(clk_reg, (read32(clk_reg) & ~0x7) | reg);
|
||||
}
|
||||
|
||||
static void lpe_stash_firmware_info(device_t dev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct resource *mmio;
|
||||
const struct pattrs *pattrs = pattrs_get();
|
||||
|
||||
res = find_resource(dev, FIRMWARE_PCI_REG_BASE);
|
||||
if (res == NULL) {
|
||||
printk(BIOS_DEBUG, "LPE Firmware memory not found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Continue using old way of informing firmware address / size. */
|
||||
pci_write_config32(dev, FIRMWARE_PCI_REG_BASE, res->base);
|
||||
pci_write_config32(dev, FIRMWARE_PCI_REG_LENGTH, res->size);
|
||||
|
||||
/* C0 and later steppings use an offset in the MMIO space. */
|
||||
if (pattrs->stepping >= STEP_C0) {
|
||||
mmio = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
write32((u32 *)(uintptr_t)(mmio->base + FIRMWARE_REG_BASE_C0),
|
||||
res->base);
|
||||
write32((u32 *)(uintptr_t)(mmio->base + FIRMWARE_REG_LENGTH_C0),
|
||||
res->size);
|
||||
}
|
||||
}
|
||||
|
||||
static void lpe_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
|
||||
lpe_stash_firmware_info(dev);
|
||||
|
||||
setup_codec_clock(dev);
|
||||
|
||||
if (config->lpe_acpi_mode)
|
||||
lpe_enable_acpi_mode(dev);
|
||||
}
|
||||
|
||||
static void lpe_read_resources(device_t dev)
|
||||
{
|
||||
pci_dev_read_resources(dev);
|
||||
|
||||
reserved_ram_resource(dev, FIRMWARE_PCI_REG_BASE,
|
||||
FIRMWARE_PHYS_BASE >> 10,
|
||||
FIRMWARE_PHYS_LENGTH >> 10);
|
||||
}
|
||||
|
||||
static const struct device_operations device_ops = {
|
||||
.read_resources = lpe_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = lpe_init,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = LPE_DEVID,
|
||||
};
|
206
src/soc/intel/braswell/lpss.c
Normal file
206
src/soc/intel/braswell/lpss.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 <arch/io.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
static void dev_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
|
||||
{
|
||||
struct reg_script ops[] = {
|
||||
/* Disable PCI interrupt, enable Memory and Bus Master */
|
||||
REG_PCI_OR32(PCI_COMMAND,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
|
||||
/* Enable ACPI mode */
|
||||
REG_IOSF_OR(IOSF_PORT_LPSS, iosf_reg,
|
||||
LPSS_CTL_PCI_CFG_DIS | LPSS_CTL_ACPI_INT_EN),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
struct resource *bar;
|
||||
global_nvs_t *gnvs;
|
||||
|
||||
/* Find ACPI NVS to update BARs */
|
||||
gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
if (!gnvs) {
|
||||
printk(BIOS_ERR, "Unable to locate Global NVS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save BAR0 and BAR1 to ACPI NVS */
|
||||
bar = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
if (bar)
|
||||
gnvs->dev.lpss_bar0[nvs_index] = (u32)bar->base;
|
||||
|
||||
bar = find_resource(dev, PCI_BASE_ADDRESS_1);
|
||||
if (bar)
|
||||
gnvs->dev.lpss_bar1[nvs_index] = (u32)bar->base;
|
||||
|
||||
/* Device is enabled in ACPI mode */
|
||||
gnvs->dev.lpss_en[nvs_index] = 1;
|
||||
|
||||
/* Put device in ACPI mode */
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
}
|
||||
|
||||
static void dev_enable_snoop_and_pm(device_t dev, int iosf_reg)
|
||||
{
|
||||
struct reg_script ops[] = {
|
||||
REG_IOSF_RMW(IOSF_PORT_LPSS, iosf_reg,
|
||||
~(LPSS_CTL_SNOOP | LPSS_CTL_NOSNOOP),
|
||||
LPSS_CTL_SNOOP | LPSS_CTL_PM_CAP_PRSNT),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
}
|
||||
|
||||
static void dev_ctl_reg(device_t dev, int *iosf_reg, int *nvs_index)
|
||||
{
|
||||
*iosf_reg = -1;
|
||||
*nvs_index = -1;
|
||||
#define SET_IOSF_REG(name_) \
|
||||
case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC): \
|
||||
*iosf_reg = LPSS_ ## name_ ## _CTL; \
|
||||
*nvs_index = LPSS_NVS_ ## name_
|
||||
|
||||
switch (dev->path.pci.devfn) {
|
||||
SET_IOSF_REG(SIO_DMA1);
|
||||
break;
|
||||
SET_IOSF_REG(I2C1);
|
||||
break;
|
||||
SET_IOSF_REG(I2C2);
|
||||
break;
|
||||
SET_IOSF_REG(I2C3);
|
||||
break;
|
||||
SET_IOSF_REG(I2C4);
|
||||
break;
|
||||
SET_IOSF_REG(I2C5);
|
||||
break;
|
||||
SET_IOSF_REG(I2C6);
|
||||
break;
|
||||
SET_IOSF_REG(I2C7);
|
||||
break;
|
||||
SET_IOSF_REG(SIO_DMA2);
|
||||
break;
|
||||
SET_IOSF_REG(PWM1);
|
||||
break;
|
||||
SET_IOSF_REG(PWM2);
|
||||
break;
|
||||
SET_IOSF_REG(HSUART1);
|
||||
break;
|
||||
SET_IOSF_REG(HSUART2);
|
||||
break;
|
||||
SET_IOSF_REG(SPI);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void i2c_disable_resets(device_t dev)
|
||||
{
|
||||
/* Release the I2C devices from reset. */
|
||||
static const struct reg_script ops[] = {
|
||||
REG_RES_WRITE32(PCI_BASE_ADDRESS_0, 0x804, 0x3),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
#define CASE_I2C(name_) \
|
||||
case PCI_DEVFN(name_ ## _DEV, name_ ## _FUNC)
|
||||
|
||||
switch (dev->path.pci.devfn) {
|
||||
CASE_I2C(I2C1):
|
||||
CASE_I2C(I2C2):
|
||||
CASE_I2C(I2C3):
|
||||
CASE_I2C(I2C4):
|
||||
CASE_I2C(I2C5):
|
||||
CASE_I2C(I2C6):
|
||||
CASE_I2C(I2C7):
|
||||
printk(BIOS_DEBUG, "Releasing I2C device from reset.\n");
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void lpss_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
int iosf_reg, nvs_index;
|
||||
|
||||
dev_ctl_reg(dev, &iosf_reg, &nvs_index);
|
||||
|
||||
if (iosf_reg < 0) {
|
||||
int slot = PCI_SLOT(dev->path.pci.devfn);
|
||||
int func = PCI_FUNC(dev->path.pci.devfn);
|
||||
printk(BIOS_DEBUG, "Could not find iosf_reg for %02x.%01x\n",
|
||||
slot, func);
|
||||
return;
|
||||
}
|
||||
dev_enable_snoop_and_pm(dev, iosf_reg);
|
||||
i2c_disable_resets(dev);
|
||||
|
||||
if (config->lpss_acpi_mode)
|
||||
dev_enable_acpi_mode(dev, iosf_reg, nvs_index);
|
||||
}
|
||||
|
||||
static struct device_operations device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = lpss_init,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const unsigned short pci_device_ids[] = {
|
||||
SIO_DMA1_DEVID,
|
||||
I2C1_DEVID,
|
||||
I2C2_DEVID,
|
||||
I2C3_DEVID,
|
||||
I2C4_DEVID,
|
||||
I2C5_DEVID,
|
||||
I2C6_DEVID,
|
||||
I2C7_DEVID,
|
||||
SIO_DMA2_DEVID,
|
||||
PWM1_DEVID,
|
||||
PWM2_DEVID,
|
||||
HSUART1_DEVID,
|
||||
HSUART2_DEVID,
|
||||
SPI_DEVID,
|
||||
0,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.devices = pci_device_ids,
|
||||
};
|
33
src/soc/intel/braswell/memmap.c
Normal file
33
src/soc/intel/braswell/memmap.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 <cbmem.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
uintptr_t smm_region_start(void)
|
||||
{
|
||||
return (iosf_bunit_read(BUNIT_SMRRL) << 20);
|
||||
}
|
||||
|
||||
void *cbmem_top(void)
|
||||
{
|
||||
return (void *) smm_region_start();
|
||||
}
|
1
src/soc/intel/braswell/microcode/Makefile.inc
Normal file
1
src/soc/intel/braswell/microcode/Makefile.inc
Normal file
@ -0,0 +1 @@
|
||||
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
|
3
src/soc/intel/braswell/microcode/microcode_blob.c
Normal file
3
src/soc/intel/braswell/microcode/microcode_blob.c
Normal file
@ -0,0 +1,3 @@
|
||||
unsigned microcode[] = {
|
||||
#include "../../../../../3rdparty/soc/intel/baytrail/microcode_blob.h"
|
||||
};
|
148
src/soc/intel/braswell/northcluster.c
Normal file
148
src/soc/intel/braswell/northcluster.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 <cpu/x86/smm.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
|
||||
/* Host Memory Map:
|
||||
*
|
||||
* +--------------------------+ BMBOUND_HI
|
||||
* | Usable DRAM |
|
||||
* +--------------------------+ 4GiB
|
||||
* | PCI Address Space |
|
||||
* +--------------------------+ BMBOUND
|
||||
* | TPM |
|
||||
* +--------------------------+ IMR2
|
||||
* | TXE |
|
||||
* +--------------------------+ IMR1
|
||||
* | iGD |
|
||||
* +--------------------------+
|
||||
* | GTT |
|
||||
* +--------------------------+ SMMRRH, IRM0
|
||||
* | TSEG |
|
||||
* +--------------------------+ SMMRRL
|
||||
* | Usable DRAM |
|
||||
* +--------------------------+ 0
|
||||
*
|
||||
* Note that there are really only a few regions that need to enumerated w.r.t.
|
||||
* coreboot's resource model:
|
||||
*
|
||||
* +--------------------------+ BMBOUND_HI
|
||||
* | Cacheable/Usable |
|
||||
* +--------------------------+ 4GiB
|
||||
*
|
||||
* +--------------------------+ BMBOUND
|
||||
* | Uncacheable/Reserved |
|
||||
* +--------------------------+ SMMRRH
|
||||
* | Cacheable/Reserved |
|
||||
* +--------------------------+ SMMRRL
|
||||
* | Cacheable/Usable |
|
||||
* +--------------------------+ 0
|
||||
*/
|
||||
#define RES_IN_KiB(r) ((r) >> 10)
|
||||
|
||||
uint32_t nc_read_top_of_low_memory(void)
|
||||
{
|
||||
return iosf_bunit_read(BUNIT_BMBOUND) & ~((1 << 27) - 1);
|
||||
}
|
||||
|
||||
static void nc_read_resources(device_t dev)
|
||||
{
|
||||
unsigned long mmconf;
|
||||
unsigned long bmbound;
|
||||
unsigned long bmbound_hi;
|
||||
unsigned long smmrrh;
|
||||
unsigned long smmrrl;
|
||||
unsigned long base_k, size_k;
|
||||
const unsigned long four_gig_kib = (4 << (30 - 10));
|
||||
int index = 0;
|
||||
|
||||
/* Read standard PCI resources. */
|
||||
pci_dev_read_resources(dev);
|
||||
|
||||
/* PCIe memory-mapped config space access - 256 MiB. */
|
||||
mmconf = iosf_bunit_read(BUNIT_MMCONF_REG) & ~((1 << 28) - 1);
|
||||
mmio_resource(dev, BUNIT_MMCONF_REG, RES_IN_KiB(mmconf), 256 * 1024);
|
||||
|
||||
/* 0 -> 0xa0000 */
|
||||
base_k = RES_IN_KiB(0);
|
||||
size_k = RES_IN_KiB(0xa0000) - base_k;
|
||||
ram_resource(dev, index++, base_k, size_k);
|
||||
|
||||
/* The SMMRR registers are 1MiB granularity with smmrrh being
|
||||
* inclusive of the SMM region. */
|
||||
smmrrl = (iosf_bunit_read(BUNIT_SMRRL) & 0xffff) << 10;
|
||||
smmrrh = ((iosf_bunit_read(BUNIT_SMRRH) & 0xffff) + 1) << 10;
|
||||
|
||||
/* 0xc0000 -> smrrl - cacheable and usable */
|
||||
base_k = RES_IN_KiB(0xc0000);
|
||||
size_k = smmrrl - base_k;
|
||||
ram_resource(dev, index++, base_k, size_k);
|
||||
|
||||
if (smmrrh > smmrrl)
|
||||
reserved_ram_resource(dev, index++, smmrrl, smmrrh - smmrrl);
|
||||
|
||||
/* All address space between bmbound and smmrrh is unusable. */
|
||||
bmbound = RES_IN_KiB(nc_read_top_of_low_memory());
|
||||
mmio_resource(dev, index++, smmrrh, bmbound - smmrrh);
|
||||
|
||||
/* The BMBOUND_HI register matches register bits of 31:24 with address
|
||||
* bits of 35:28. Therefore, shift register to align properly. */
|
||||
bmbound_hi = iosf_bunit_read(BUNIT_BMBOUND_HI) & ~((1 << 24) - 1);
|
||||
bmbound_hi = RES_IN_KiB(bmbound_hi) << 4;
|
||||
if (bmbound_hi > four_gig_kib)
|
||||
ram_resource(dev, index++, four_gig_kib,
|
||||
bmbound_hi - four_gig_kib);
|
||||
|
||||
/* Reserve everything between A segment and 1MB:
|
||||
*
|
||||
* 0xa0000 - 0xbffff: legacy VGA
|
||||
* 0xc0000 - 0xfffff: RAM
|
||||
*/
|
||||
mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10);
|
||||
reserved_ram_resource(dev, index++, (0xc0000 >> 10),
|
||||
(0x100000 - 0xc0000) >> 10);
|
||||
|
||||
chromeos_reserve_ram_oops(dev, index++);
|
||||
}
|
||||
|
||||
static struct device_operations nc_ops = {
|
||||
.read_resources = nc_read_resources,
|
||||
.set_resources = NULL,
|
||||
.enable_resources = NULL,
|
||||
.init = NULL,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver nc_driver __pci_driver = {
|
||||
.ops = &nc_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = SOC_DEVID,
|
||||
};
|
278
src/soc/intel/braswell/pcie.c
Normal file
278
src/soc/intel/braswell/pcie.c
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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 <device/pciexp.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pcie.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
static int pll_en_off;
|
||||
static uint32_t strpfusecfg;
|
||||
|
||||
static inline int root_port_offset(device_t dev)
|
||||
{
|
||||
return PCI_FUNC(dev->path.pci.devfn);
|
||||
}
|
||||
|
||||
static inline int is_first_port(device_t dev)
|
||||
{
|
||||
return root_port_offset(dev) == PCIE_PORT1_FUNC;
|
||||
}
|
||||
|
||||
static const struct reg_script init_static_before_exit_latency[] = {
|
||||
/* Disable optimized buffer flush fill and latency tolerant reporting */
|
||||
REG_PCI_RMW32(DCAP2, ~(OBFFS | LTRMS), 0),
|
||||
REG_PCI_RMW32(DSTS2, ~(OBFFEN| LTRME), 0),
|
||||
/* Set maximum payload size. */
|
||||
REG_PCI_RMW32(DCAP, ~MPS_MASK, 0),
|
||||
/* Disable transmit datapath flush timer, clear transmit config change
|
||||
* wait time, clear sideband interface idle counter. */
|
||||
REG_PCI_RMW32(PHYCTL2_IOSFBCTL, ~(TDFT | TXCFGCHWAIT | SIID), 0),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static const struct reg_script init_static_after_exit_latency[] = {
|
||||
/* Set common clock configuration. */
|
||||
REG_PCI_OR16(LCTL, CCC),
|
||||
/* Set NFTS to 0x743a361b */
|
||||
REG_PCI_WRITE32(NFTS, 0x743a361b),
|
||||
/* Set common clock latency to 0x3 */
|
||||
REG_PCI_RMW32(MPC, ~CCEL_MASK, (0x3 << CCEL_SHIFT)),
|
||||
/* Set relay timer policy. */
|
||||
REG_PCI_RMW32(RTP, 0xff000000, 0x854c74),
|
||||
/* Set IOSF packet fast transmit mode and link speed training policy. */
|
||||
REG_PCI_OR16(MPC2, IPF | LSTP),
|
||||
/* Channel configuration - enable upstream posted split, set non-posted
|
||||
* and posted request size */
|
||||
REG_PCI_RMW32(CHCFG, ~UPSD, UNRS | UPRS),
|
||||
/* Completion status replay enable and set TLP grant count */
|
||||
REG_PCI_RMW32(CFG2, ~(LATGC_MASK), CSREN | (3 << LATGC_SHIFT)),
|
||||
/* Assume no IOAPIC behind root port -- disable EOI forwarding. */
|
||||
REG_PCI_OR16(MPC2, EOIFD),
|
||||
/* Expose AER */
|
||||
REG_PCI_RMW32(AERCH, ~0, (1 << 16) | (1 << 0)),
|
||||
/* set completion timeout to 160ms to 170ms */
|
||||
REG_PCI_RMW16(DSTS2, ~CTD, 0x6),
|
||||
/* Enable AER */
|
||||
REG_PCI_OR16(DCTL_DSTS, URE | FEE | NFE | CEE),
|
||||
/* Read and write back capability registers. */
|
||||
REG_PCI_OR32(0x34, 0),
|
||||
REG_PCI_OR32(0x80, 0),
|
||||
/* Retrain the link. */
|
||||
REG_PCI_OR16(LCTL, RL),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static void byt_pcie_init(device_t dev)
|
||||
{
|
||||
struct reg_script init_script[] = {
|
||||
REG_SCRIPT_NEXT(init_static_before_exit_latency),
|
||||
/* Exit latency configuration based on
|
||||
* PHYCTL2_IOSFBCTL[PLL_OFF_EN] set in root port 1*/
|
||||
REG_PCI_RMW32(LCAP, ~L1EXIT_MASK,
|
||||
2 << (L1EXIT_SHIFT + pll_en_off)),
|
||||
REG_SCRIPT_NEXT(init_static_after_exit_latency),
|
||||
/* Disable hot plug, set power to 10W, set slot number. */
|
||||
REG_PCI_RMW32(SLCAP, ~(HPC | HPS),
|
||||
(1 << SLS_SHIFT) | (100 << SLV_SHIFT) |
|
||||
(root_port_offset(dev) << SLN_SHIFT)),
|
||||
/* Dynamic clock gating. */
|
||||
REG_PCI_OR32(RPPGEN, RPDLCGEN | RPDBCGEN | RPSCGEN),
|
||||
REG_PCI_OR32(PWRCTL, RPL1SQPOL | RPDTSQPOL),
|
||||
REG_PCI_OR32(PCIEDBG, SPCE),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
reg_script_run_on_dev(dev, init_script);
|
||||
|
||||
if (is_first_port(dev)) {
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
uint32_t reg = pci_read_config32(dev, RPPGEN);
|
||||
reg |= SRDLCGEN | SRDBCGEN;
|
||||
|
||||
if (config && config->clkreq_enable)
|
||||
reg |= LCLKREQEN | BBCLKREQEN;
|
||||
|
||||
pci_write_config32(dev, RPPGEN, reg);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct reg_script no_dev_behind_port[] = {
|
||||
REG_PCI_OR32(PCIEALC, (1 << 26)),
|
||||
REG_PCI_POLL32(PCIESTS1, 0x1f000000, (1 << 24), 50000),
|
||||
REG_PCI_OR32(PHYCTL4, SQDIS),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static void check_port_enabled(device_t dev)
|
||||
{
|
||||
int rp_config = (strpfusecfg & LANECFG_MASK) >> LANECFG_SHIFT;
|
||||
|
||||
switch (root_port_offset(dev)) {
|
||||
case PCIE_PORT1_FUNC:
|
||||
/* Port 1 cannot be disabled from strapping config. */
|
||||
break;
|
||||
case PCIE_PORT2_FUNC:
|
||||
/* Port 2 disabled in all configs but 4x1. */
|
||||
if (rp_config != 0x0)
|
||||
dev->enabled = 0;
|
||||
break;
|
||||
case PCIE_PORT3_FUNC:
|
||||
/* Port 3 disabled only in 1x4 config. */
|
||||
if (rp_config == 0x3)
|
||||
dev->enabled = 0;
|
||||
break;
|
||||
case PCIE_PORT4_FUNC:
|
||||
/* Port 4 disabled in 1x4 and 2x2 config. */
|
||||
if (rp_config >= 0x2)
|
||||
dev->enabled = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 all_ports_no_dev_present(device_t dev)
|
||||
{
|
||||
u8 func;
|
||||
u8 temp = dev->path.pci.devfn;
|
||||
u8 device_not_present = 1;
|
||||
u8 data;
|
||||
|
||||
for (func = 1; func < PCIE_ROOT_PORT_COUNT; func++) {
|
||||
dev->path.pci.devfn &= ~0x7;
|
||||
dev->path.pci.devfn |= func;
|
||||
|
||||
/* is pcie device there */
|
||||
if (pci_read_config32(dev, 0) == 0xFFFFFFFF)
|
||||
continue;
|
||||
|
||||
data = pci_read_config8(dev, XCAP + 3) | (SI >> 24);
|
||||
pci_write_config8(dev, XCAP + 3, data);
|
||||
|
||||
/* is any device present */
|
||||
if ((pci_read_config32(dev, SLCTL_SLSTS) & PDS)) {
|
||||
device_not_present = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->path.pci.devfn = temp;
|
||||
return device_not_present;
|
||||
}
|
||||
|
||||
static void check_device_present(device_t dev)
|
||||
{
|
||||
/* Set slot implemented. */
|
||||
pci_write_config32(dev, XCAP, pci_read_config32(dev, XCAP) | SI);
|
||||
|
||||
/* No device present. */
|
||||
if (!(pci_read_config32(dev, SLCTL_SLSTS) & PDS)) {
|
||||
printk(BIOS_DEBUG, "No PCIe device present.\n");
|
||||
if (is_first_port(dev)) {
|
||||
if (all_ports_no_dev_present(dev)) {
|
||||
reg_script_run_on_dev(dev, no_dev_behind_port);
|
||||
dev->enabled = 0;
|
||||
}
|
||||
} else {
|
||||
reg_script_run_on_dev(dev, no_dev_behind_port);
|
||||
dev->enabled = 0;
|
||||
}
|
||||
} else if(!dev->enabled) {
|
||||
/* Port is disabled, but device present. Disable link. */
|
||||
pci_write_config32(dev, LCTL,
|
||||
pci_read_config32(dev, LCTL) | LD);
|
||||
}
|
||||
}
|
||||
|
||||
static void byt_pcie_enable(device_t dev)
|
||||
{
|
||||
if (is_first_port(dev)) {
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
uint32_t reg = pci_read_config32(dev, PHYCTL2_IOSFBCTL);
|
||||
pll_en_off = !!(reg & PLL_OFF_EN);
|
||||
|
||||
strpfusecfg = pci_read_config32(dev, STRPFUSECFG);
|
||||
|
||||
if (config && config->pcie_wake_enable)
|
||||
southcluster_smm_save_param(
|
||||
SMM_SAVE_PARAM_PCIE_WAKE_ENABLE, 1);
|
||||
}
|
||||
|
||||
/* Check if device is enabled in strapping. */
|
||||
check_port_enabled(dev);
|
||||
/* Determine if device is behind port. */
|
||||
check_device_present(dev);
|
||||
|
||||
southcluster_enable_dev(dev);
|
||||
}
|
||||
|
||||
static unsigned int byt_pciexp_scan_bridge(device_t dev, unsigned int max)
|
||||
{
|
||||
static const struct reg_script wait_for_link_active[] = {
|
||||
REG_PCI_POLL32(LCTL, (1 << 29) , (1 << 29), 50000),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
/* wait for Link Active with 50ms timeout */
|
||||
reg_script_run_on_dev(dev, wait_for_link_active);
|
||||
|
||||
return do_pci_scan_bridge(dev, max, pciexp_scan_bus);
|
||||
}
|
||||
|
||||
static void pcie_root_set_subsystem(device_t dev, unsigned vid, unsigned did)
|
||||
{
|
||||
uint32_t didvid = ((did & 0xffff) << 16) | (vid & 0xffff);
|
||||
|
||||
if (!didvid)
|
||||
didvid = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
pci_write_config32(dev, 0x94, didvid);
|
||||
}
|
||||
|
||||
static struct pci_operations pcie_root_ops = {
|
||||
.set_subsystem = &pcie_root_set_subsystem,
|
||||
};
|
||||
|
||||
static struct device_operations device_ops = {
|
||||
.read_resources = pci_bus_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_bus_enable_resources,
|
||||
.init = byt_pcie_init,
|
||||
.scan_bus = byt_pciexp_scan_bridge,
|
||||
.enable = byt_pcie_enable,
|
||||
.ops_pci = &pcie_root_ops,
|
||||
};
|
||||
|
||||
static const unsigned short pci_device_ids[] = {
|
||||
PCIE_PORT1_DEVID, PCIE_PORT2_DEVID, PCIE_PORT3_DEVID, PCIE_PORT4_DEVID,
|
||||
0
|
||||
};
|
||||
|
||||
static const struct pci_driver pcie_root_ports __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.devices = pci_device_ids,
|
||||
};
|
292
src/soc/intel/braswell/perf_power.c
Normal file
292
src/soc/intel/braswell/perf_power.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* 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 <arch/io.h>
|
||||
#include <bootstate.h>
|
||||
#include <console/console.h>
|
||||
#include <reg_script.h>
|
||||
#include <soc/iosf.h>
|
||||
|
||||
#define MAKE_MASK_INCLUSIVE(msb) \
|
||||
((1ULL << (1 + (msb))) - 1)
|
||||
#define MAKE_MASK(msb) \
|
||||
((1ULL << (msb)) - 1)
|
||||
#define MASK_VAL(msb, lsb, val) \
|
||||
~(MAKE_MASK_INCLUSIVE(msb) & ~MAKE_MASK(lsb)), (val) << (lsb)
|
||||
|
||||
#define E(arg1, arg2, args) \
|
||||
REG_IOSF_RMW(IOSF_PORT_##arg1, arg2, args)
|
||||
|
||||
static const struct reg_script perf_power_settings[] = {
|
||||
E(AUNIT, 0x18, MASK_VAL(22, 22, 0x1)), // ACKGATE.AMESSAGE_MSGIF
|
||||
E(AUNIT, 0x18, MASK_VAL(21, 21, 0x1)), // ACKGATE.AREQDOWN_SCL0_ARB
|
||||
E(AUNIT, 0x18, MASK_VAL(20, 20, 0x1)), // ACKGATE.AREQUP_MIRROR
|
||||
E(AUNIT, 0x18, MASK_VAL(19, 19, 0x1)), // ACKGATE.AREQTAHACK
|
||||
E(AUNIT, 0x18, MASK_VAL(18, 18, 0x1)), // ACKGATE.AREQDOWN_TAREQQ
|
||||
E(AUNIT, 0x18, MASK_VAL(17, 17, 0x1)), // ACKGATE.AREQDOWN_CREDIT
|
||||
E(AUNIT, 0x18, MASK_VAL(16, 16, 0x1)), // ACKGATE.ASCLUP_FAIR_ARBITER
|
||||
E(AUNIT, 0x18, MASK_VAL(15, 15, 0x1)), // ACKGATE.AIOSFDOWN_DATA
|
||||
E(AUNIT, 0x18, MASK_VAL(14, 14, 0x1)), // ACKGATE.ASCLUP_IOSF_ADAPTER
|
||||
E(AUNIT, 0x18, MASK_VAL(12, 12, 0x1)), // ACKGATE.ASCLUP_CMD_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(11, 11, 0x1)), // ACKGATE.ASCLUP_DATA_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(10, 10, 0x1)), // ACKGATE.AREQUP_CMD_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(9, 9, 0x1)), // ACKGATE.AREQUP_DATA_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(8, 8, 0x1)), // ACKGATE.AREQDOWN_RSP_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(7, 7, 0x1)), // ACKGATE.AREQDOWN_DATA_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(6, 6, 0x1)), // ACKGATE.AIOSFDOWN_CMD_DRVR
|
||||
E(AUNIT, 0x18, MASK_VAL(5, 5, 0x1)), // ACKGATE.AIOSFDOWN_CMD_DATA_BUFF
|
||||
E(AUNIT, 0x18, MASK_VAL(4, 4, 0x1)), // ACKGATE.AT_REQ_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(3, 3, 0x1)), // ACKGATE.AT_DATA_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(2, 2, 0x1)), // ACKGATE.TA_REQ_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(1, 1, 0x1)), // ACKGATE.TA_DATA_QUEUE
|
||||
E(AUNIT, 0x18, MASK_VAL(0, 0, 0x1)), // ACKGATE.CONFIG_REGS
|
||||
E(AUNIT, 0x20, MASK_VAL(26, 24, 0x2)), // AISOCHCTL.CHANNEL_AB_DEADLINE_EN
|
||||
E(AUNIT, 0x20, MASK_VAL(8, 0, 0x1)), // AISOCHCTL.VC1_ISOC_CH_DEFAULT_DDLINE_DLY
|
||||
E(AUNIT, 0x21, MASK_VAL(31, 31, 0x1)), // AVCCTL.EFFICIENT_PERF_UP_EN
|
||||
E(AUNIT, 0x21, MASK_VAL(8, 8, 0x0)), // AVCCTL.VC_EN_PRIORITY_DNARB
|
||||
E(AUNIT, 0x0C0, MASK_VAL(11, 8, 0x4)), // AARBCTL0.IOSF0VC2_WGT
|
||||
E(AUNIT, 0x0C0, MASK_VAL(7, 4, 0x4)), // AARBCTL0.IOSF0VC1_WGT
|
||||
E(AUNIT, 0x0C0, MASK_VAL(3, 0, 0x4)), // AARBCTL0.IOSF0VC0_WGT
|
||||
E(BUNIT, 0x3, MASK_VAL(29, 24, 0x4)), // BARBCTRL0.AGENT3_WEIGHT
|
||||
E(BUNIT, 0x3, MASK_VAL(21, 16, 0x4)), // BARBCTRL0.AGENT2_WEIGHT
|
||||
E(BUNIT, 0x3, MASK_VAL(13, 8, 0x4)), // BARBCTRL0.AGENT1_WEIGHT
|
||||
E(BUNIT, 0x3, MASK_VAL(5, 0, 0x4)), // BARBCTRL0.AGENT0_WEIGHT
|
||||
E(BUNIT, 0x4, MASK_VAL(29, 24, 0x4)), // BARBCTRL1.AGENT7_WEIGHT
|
||||
E(BUNIT, 0x4, MASK_VAL(21, 16, 0x4)), // BARBCTRL1.AGENT6_WEIGHT
|
||||
E(BUNIT, 0x4, MASK_VAL(13, 8, 0x4)), // BARBCTRL1.AGENT5_WEIGHT
|
||||
E(BUNIT, 0x4, MASK_VAL(5, 0, 0x4)), // BARBCTRL1.AGENT4_WEIGHT
|
||||
E(BUNIT, 0x5, MASK_VAL(21, 16, 0x4)), // BARBCTRL2.AGENT10_WEIGHT
|
||||
E(BUNIT, 0x5, MASK_VAL(13, 8, 0x4)), // BARBCTRL2.AGENT9_WEIGHT
|
||||
E(BUNIT, 0x5, MASK_VAL(5, 0, 0x8)), // BARBCTRL2.AGENT8_WEIGHT
|
||||
E(BUNIT, 0x7, MASK_VAL(31, 24, 0x20)), // BWFLUSH.FLUSH_THRSHOLD
|
||||
E(BUNIT, 0x7, MASK_VAL(15, 8, 0x0A)), // BWFLUSH.DIRTY_LWM
|
||||
E(BUNIT, 0x7, MASK_VAL(7, 0, 0x10)), // BWFLUSH.DIRTY_HWM
|
||||
E(BUNIT, 0x8, MASK_VAL(23, 0, 0x0)), // BBANKMASK.BANK_MASK
|
||||
E(BUNIT, 0x9, MASK_VAL(23, 0, 0x3FFFFC)), // BROWMASK.ROW_MASK
|
||||
E(BUNIT, 0x0A, MASK_VAL(9, 0, 0x080)), // BRANKMASK.RANK_MASK
|
||||
E(BUNIT, 0x0B, MASK_VAL(29, 24, 0x1F)), // BALIMIT0.AGENT3_LIMIT
|
||||
E(BUNIT, 0x0B, MASK_VAL(21, 16, 0x2F)), // BALIMIT0.AGENT2_LIMIT
|
||||
E(BUNIT, 0x0B, MASK_VAL(13, 8, 0x2F)), // BALIMIT0.AGENT1_LIMIT
|
||||
E(BUNIT, 0x0B, MASK_VAL(5, 0, 0x2F)), // BALIMIT0.AGENT0_LIMIT
|
||||
E(BUNIT, 0x0C, MASK_VAL(29, 24, 0x2F)), // BALIMIT1.AGENT7_LIMIT
|
||||
E(BUNIT, 0x0C, MASK_VAL(21, 16, 0x2F)), // BALIMIT1.AGENT6_LIMIT
|
||||
E(BUNIT, 0x0C, MASK_VAL(13, 8, 0x2F)), // BALIMIT1.AGENT5_LIMIT
|
||||
E(BUNIT, 0x0C, MASK_VAL(5, 0, 0x2B)), // BALIMIT1.AGENT4_LIMIT
|
||||
E(BUNIT, 0x0D, MASK_VAL(21, 16, 0x2F)), // BALIMIT2.AGENT10_LIMIT
|
||||
E(BUNIT, 0x0D, MASK_VAL(13, 8, 0x2F)), // BALIMIT2.AGENT9_LIMIT
|
||||
E(BUNIT, 0x0D, MASK_VAL(5, 0, 0x2F)), // BALIMIT2.AGENT8_LIMIT
|
||||
E(BUNIT, 0x0F, MASK_VAL(29, 28, 0x0)), // BARES0.AGENT7_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(25, 24, 0x0)), // BARES0.AGENT6_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(21, 20, 0x0)), // BARES0.AGENT5_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(17, 16, 0x0)), // BARES0.AGENT4_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(13, 12, 0x0)), // BARES0.AGENT3_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(9, 8, 0x0)), // BARES0.AGENT2_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(5, 4, 0x0)), // BARES0.AGENT1_RSVD
|
||||
E(BUNIT, 0x0F, MASK_VAL(1, 0, 0x0)), // BARES0.AGENT0_RSVD
|
||||
E(BUNIT, 0x10, MASK_VAL(9, 8, 0x0)), // BARES1.AGENT10_RSVD
|
||||
E(BUNIT, 0x10, MASK_VAL(5, 4, 0x0)), // BARES1.AGENT9_RSVD
|
||||
E(BUNIT, 0x10, MASK_VAL(1, 0, 0x0)), // BARES1.AGENT8_RSVD
|
||||
E(BUNIT, 0x11, MASK_VAL(31, 22, 0x20)), // BISOC.ENTER_SELF_REFRESH_THRSH
|
||||
E(BUNIT, 0x11, MASK_VAL(18, 18, 0x1)), // BISOC.SR_EXIT_SYNC_EN
|
||||
E(BUNIT, 0x11, MASK_VAL(17, 12, 0x4)), // BISOC.ENTER_SELF_REFRESH_DLY
|
||||
E(BUNIT, 0x11, MASK_VAL(11, 8, 0x8)), // BISOC.SCHEDULER_LATENCY
|
||||
E(BUNIT, 0x12, MASK_VAL(31, 30, 0x0)), // BCOSCAT.COS_CAT_AGENT15 and BCOSCAT.BUS_LOCK_THROTTLE_ENABLE
|
||||
E(BUNIT, 0x12, MASK_VAL(29, 28, 0x0)), // BCOSCAT.COS_CAT_AGENT14
|
||||
E(BUNIT, 0x12, MASK_VAL(27, 26, 0x0)), // BCOSCAT.COS_CAT_AGENT13
|
||||
E(BUNIT, 0x12, MASK_VAL(25, 24, 0x0)), // BCOSCAT.COS_CAT_AGENT12
|
||||
E(BUNIT, 0x12, MASK_VAL(23, 22, 0x0)), // BCOSCAT.COS_CAT_AGENT11
|
||||
E(BUNIT, 0x12, MASK_VAL(21, 20, 0x0)), // BCOSCAT.COS_CAT_AGENT10
|
||||
E(BUNIT, 0x12, MASK_VAL(19, 18, 0x0)), // BCOSCAT.COS_CAT_AGENT9
|
||||
E(BUNIT, 0x12, MASK_VAL(17, 16, 0x1)), // BCOSCAT.COS_CAT_AGENT8
|
||||
E(BUNIT, 0x12, MASK_VAL(15, 14, 0x0)), // BCOSCAT.COS_CAT_AGENT7
|
||||
E(BUNIT, 0x12, MASK_VAL(13, 12, 0x0)), // BCOSCAT.COS_CAT_AGENT6
|
||||
E(BUNIT, 0x12, MASK_VAL(11, 10, 0x1)), // BCOSCAT.COS_CAT_AGENT5
|
||||
E(BUNIT, 0x12, MASK_VAL(9, 8, 0x1)), // BCOSCAT.COS_CAT_AGENT4
|
||||
E(BUNIT, 0x12, MASK_VAL(7, 6, 0x0)), // BCOSCAT.COS_CAT_AGENT3
|
||||
E(BUNIT, 0x12, MASK_VAL(5, 4, 0x0)), // BCOSCAT.COS_CAT_AGENT2
|
||||
E(BUNIT, 0x12, MASK_VAL(3, 2, 0x0)), // BCOSCAT.COS_CAT_AGENT1
|
||||
E(BUNIT, 0x12, MASK_VAL(1, 0, 0x0)), // BCOSCAT.COS_CAT_AGENT0
|
||||
E(BUNIT, 0x14, MASK_VAL(31, 31, 0x0)), // BFLWT.DISABLE_FLUSH_WEIGHTS
|
||||
E(BUNIT, 0x14, MASK_VAL(30, 30, 0x0)), // BFLWT.ENABLE_READ_INVALIDATE_TIMER
|
||||
E(BUNIT, 0x14, MASK_VAL(13, 8, 0x8)), // BFLWT.WRITE_WEIGHTS
|
||||
E(BUNIT, 0x14, MASK_VAL(5, 0, 0x10)), // BFLWT.READ_WEIGHTS
|
||||
E(BUNIT, 0x16, MASK_VAL(31, 31, 0x0)), // BISOCWT.ENABLE_ISOC_WEIGHTS
|
||||
E(BUNIT, 0x16, MASK_VAL(13, 8, 0x3F)), // BISOCWT.ISOC_REQUEST_WEIGHTS
|
||||
E(BUNIT, 0x16, MASK_VAL(5, 0, 0x8)), // BISOCWT.NON_ISOC_REQUEST_WEIGHTS
|
||||
E(BUNIT, 0x18, MASK_VAL(31, 24, 0x20)), // BSCHCTRL0.BEST_EFFORT_MAX_LATENCY
|
||||
E(BUNIT, 0x18, MASK_VAL(23, 21, 0x6)), // BSCHCTRL0.PAGE_HIT_DELAY
|
||||
E(BUNIT, 0x18, MASK_VAL(13, 7, 0x0)), // BSCHCTRL0.ISOC_BANK_PREFETCH
|
||||
E(BUNIT, 0x18, MASK_VAL(6, 0, 0x20)), // BSCHCTRL0.BEST_EFFORT_BANK_PREFETCH
|
||||
E(BUNIT, 0x3B, MASK_VAL(23, 16, 0x4)), // BDEBUG0.CASUAL_TIMER
|
||||
E(BUNIT, 0x3B, MASK_VAL(9, 9, 0x0)), // BDEBUG0.DISABLE_BADMIT_URGENT_ISOC
|
||||
E(BUNIT, 0x3B, MASK_VAL(7, 0, 0x0A)), // BDEBUG0.CASUAL_WATER_MARK
|
||||
E(BUNIT, 0x3C, MASK_VAL(31, 16, 0x0FFFF)), // BDEBUG1.AGENT_WEIGHT_ENABLE
|
||||
E(BUNIT, 0x3C, MASK_VAL(2, 2, 0x0)), // BDEBUG1.EXIT_SR_FOR_CASUAL_FLUSH
|
||||
E(BUNIT, 0x3C, MASK_VAL(1, 1, 0x0)), // BDEBUG1.ENABLE_DRAM_SELF_RFRSH
|
||||
E(BUNIT, 0x3D, MASK_VAL(14, 14, 0x1)), // BCTRL.BANK_STATUS_ENABLE
|
||||
E(BUNIT, 0x3D, MASK_VAL(13, 13, 0x0)), // BCTRL.DISABLE_OWNED
|
||||
E(BUNIT, 0x3D, MASK_VAL(12, 12, 0x0)), // BCTRL.INORDER_READ_ENABLE
|
||||
E(BUNIT, 0x3D, MASK_VAL(11, 11, 0x0)), // BCTRL.INORDER_FLUSH_ENABLE
|
||||
E(BUNIT, 0x3D, MASK_VAL(8, 8, 0x0)), // BCTRL.MISS_VALID_ENTRIES
|
||||
E(BUNIT, 0x3D, MASK_VAL(7, 7, 0x0)), // BCTRL.DIRTY_STALL
|
||||
E(BUNIT, 0x3D, MASK_VAL(6, 6, 0x0)), // BCTRL.SINGLE_TAG_ACCESS
|
||||
E(BUNIT, 0x3D, MASK_VAL(5, 5, 0x0)), // BCTRL.SINGLE_CHUNK_ACCESS
|
||||
E(BUNIT, 0x3D, MASK_VAL(2, 2, 0x1)), // BCTRL.BECLK_GATE_EN
|
||||
E(BUNIT, 0x3D, MASK_VAL(1, 1, 0x1)), // BCTRL.MASTERCLK_GATE_EN
|
||||
E(BUNIT, 0x3D, MASK_VAL(0, 0, 0x1)), // BCTRL.REQUESTCLK_GATE_EN
|
||||
E(BUNIT, 0x3E, MASK_VAL(31, 16, 0x0)), // BTHCTRL.AGENT_THROTTLING_ENABLE
|
||||
E(BUNIT, 0x3E, MASK_VAL(7, 0, 0x0)), // BTHCTRL.RANK_SELECTION_MASK
|
||||
E(BUNIT, 0x3F, MASK_VAL(31, 24, 0x0FF)), // BTHMASK.ORWRITE_MASK
|
||||
E(BUNIT, 0x3F, MASK_VAL(23, 16, 0x0FF)), // BTHMASK.ORREAD_MASK
|
||||
E(BUNIT, 0x3F, MASK_VAL(15, 8, 0x0FF)), // BTHMASK.ERWRITE_MASK
|
||||
E(BUNIT, 0x3F, MASK_VAL(7, 0, 0x0FF)), // BTHMASK.ERREAD_MASK
|
||||
//0x02, 0x0, 2, 0, 0x1, //T_INTR_REDIR_CTL.REDIR_MODE_SEL
|
||||
E(CPU_BUS, 0x3, MASK_VAL(20, 20, 0x1)), // T_CTL.SPLIT_GOIWP_MODE
|
||||
E(CPU_BUS, 0x3, MASK_VAL(19, 19, 0x0)), // T_CTL.DISABLE_TRDY_RDGO
|
||||
E(CPU_BUS, 0x3, MASK_VAL(18, 18, 0x0)), // T_CTL.DISABLE_ISOC_HIGHPRI_RDDATA_RETURN
|
||||
E(CPU_BUS, 0x3, MASK_VAL(17, 17, 0x0)), // T_CTL.ENABLE_NPC_COLLECTOR
|
||||
E(CPU_BUS, 0x3, MASK_VAL(16, 16, 0x1)), // T_CTL.ENABLE_IN_ORDER_APIC
|
||||
E(CPU_BUS, 0x3, MASK_VAL(15, 15, 0x0)), // T_CTL.TG_HIGHPRI_WRITE_PULLS
|
||||
//0x02, 0x3, 12, 12, 0x1, // T_CTL.TG_NDRAMSNP
|
||||
E(CPU_BUS, 0x3, MASK_VAL(10, 10, 0x1)), // T_CTL.TG_DW_POST_PUSH_LOG
|
||||
E(CPU_BUS, 0x3, MASK_VAL(3, 3, 0x0)), // T_CTL.ALWAYS_SNP_IDI
|
||||
E(CPU_BUS, 0x3, MASK_VAL(2, 2, 0x0)), // T_CTL.DIS_LIVE_BRAM_BYP_IDI
|
||||
E(CPU_BUS, 0x4, MASK_VAL(18, 18, 0x1)), // T_MISC_CTL.DISABLE_IOSF_OUTBOUND_THROTTLE
|
||||
E(CPU_BUS, 0x4, MASK_VAL(4, 1, 0x8)), // T_MISC_CTL.DPTE_CNT
|
||||
E(CPU_BUS, 0x4, MASK_VAL(0, 0, 0x0)), // T_MISC_CTL.DPTE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(27, 27, 0x1)), // T_CLKGATE_CTL.XUNIT_4_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(26, 26, 0x1)), // T_CLKGATE_CTL.XUNIT_3_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(25, 25, 0x1)), // T_CLKGATE_CTL.XUNIT_2_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(24, 24, 0x1)), // T_CLKGATE_CTL.XUNIT_1_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(23, 23, 0x1)), // T_CLKGATE_CTL.MON_LOG_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(22, 22, 0x1)), // T_CLKGATE_CTL.A2T_Q_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(21, 21, 0x1)), // T_CLKGATE_CTL.T2A_Q_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(20, 20, 0x1)), // T_CLKGATE_CTL.A2TAPIC_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(19, 19, 0x1)), // T_CLKGATE_CTL.B2X_DATSEL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(18, 18, 0x1)), // T_CLKGATE_CTL.X2B_DATSEL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(17, 17, 0x1)), // T_CLKGATE_CTL.S2C_RESP_SEL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(16, 16, 0x1)), // T_CLKGATE_CTL.T2A_REQ_SEL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(15, 15, 0x1)), // T_CLKGATE_CTL.C2APIC_FIFO_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(14, 14, 0x1)), // T_CLKGATE_CTL.S2C_REQ_FIFO_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(13, 13, 0x1)), // T_CLKGATE_CTL.S2C_REQ_SEL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(12, 12, 0x1)), // T_CLKGATE_CTL.TRKR_SB_LLST_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(11, 11, 0x1)), // T_CLKGATE_CTL.TRKR_SB_OLDST_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(10, 10, 0x1)), // T_CLKGATE_CTL.TRKR_SB_S2C_RESP_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(9, 9, 0x1)), // T_CLKGATE_CTL.TRKR_SB_T2A_REQSTAT_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(8, 8, 0x1)), // T_CLKGATE_CTL.TRKR_SB_B2X_DATSTAT_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(7, 7, 0x1)), // T_CLKGATE_CTL.TRKR_SB_WRSTAT_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(6, 6, 0x1)), // T_CLKGATE_CTL.TRKR_SB_SNP_STAT_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(5, 5, 0x1)), // T_CLKGATE_CTL.TRKR_SB_REQ_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(4, 4, 0x1)), // T_CLKGATE_CTL.TRKR_SB_VIOL_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(3, 3, 0x1)), // T_CLKGATE_CTL.TRKR_SB_VALID_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(2, 2, 0x1)), // T_CLKGATE_CTL.TRKR_SB_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(1, 1, 0x1)), // T_CLKGATE_CTL.IOSF_SB_CFG_REG_CLK_GATE_EN
|
||||
E(CPU_BUS, 0x5, MASK_VAL(0, 0, 0x1)), // T_CLKGATE_CTL.IOSF_SB_MSG_CLK_GATE_EN
|
||||
E(0x58, 0x40, MASK_VAL(4, 4, 0x0)), // SSCR2.ACG_EN
|
||||
E(0x58, 0x40, MASK_VAL(4, 4, 0x0)), // SSCR2.ACG_EN
|
||||
E(0x58, 0x40, MASK_VAL(4, 4, 0x0)), // SSCR2.ACG_EN
|
||||
E(0x55, 0x54, MASK_VAL(1, 0, 0x0)), // SMB_Config_PMCSR.PS
|
||||
E(0x55, 0x0FC, MASK_VAL(17, 17, 0x0)), // SMB_Config_CGC.FUNC_CLK_CGD
|
||||
E(0x55, 0x0FC, MASK_VAL(9, 9, 0x0)), // SMB_Config_CGC.SB_LOCAL_CGD
|
||||
E(0xa2, 0x0C000, MASK_VAL(0, 0, 0x0)), // power_options.clkgate_disable
|
||||
E(0x47, 0x0C000, MASK_VAL(0, 0, 0x0)), // power_options.clkgate_disable
|
||||
E(0x45, 0x0C000, MASK_VAL(0, 0, 0x0)), // power_options.clkgate_disable
|
||||
E(0x46, 0x0C000, MASK_VAL(0, 0, 0x0)), // power_options.clkgate_disable
|
||||
E(PMC, 0x0, MASK_VAL(11, 11, 0x1)), // PUNIT_CONTROL.MODE_DEMOTE_EN
|
||||
E(PMC, 0x0, MASK_VAL(10, 10, 0x1)), // PUNIT_CONTROL.CORE_DEMOTE_EN
|
||||
|
||||
//
|
||||
//s0ix_PnP_Settings
|
||||
//
|
||||
E(0x58, 0x1e0, MASK_VAL(4, 4, 0x1)), //vlv.audio.lpe.bridge.pmctl.iosfprim_trunk_gate_en
|
||||
E(0x58, 0x1e0, MASK_VAL(0, 0, 0x0)), //vlv.audio.lpe.bridge.pmctl.iosfprimclk_gate_en
|
||||
E(0x58, 0x1e0, MASK_VAL(5, 5, 0x1)), //vlv.audio.lpe.bridge.pmctl.iosfsb_trunk_gate_en
|
||||
E(0x58, 0x1e0, MASK_VAL(3, 3, 0x1)), //vlv.audio.lpe.bridge.pmctl.pmctl.iosfsbclk_gate_en
|
||||
E(0x58, 0x1e0, MASK_VAL(1, 1, 0x1)), //vlv.audio.lpe.bridge.pmctl.ocpclk_gate_en
|
||||
E(0x58, 0x1e0, MASK_VAL(2, 2, 0x1)), //vlv.audio.lpe.bridge.pmctl.ocpclk_trunk_gate_en
|
||||
E(CCU, 0x28, MASK_VAL(31, 0, 0x0)), //vlv.ccu.ccu_trunk_clkgate
|
||||
E(CCU, 0x38, MASK_VAL(31, 0, 0x0)), //vlv.ccu.ccu_trunk_clkgate_2
|
||||
E(CCU, 0x1c, MASK_VAL(29, 28, 0x0)), //vlv.ccu.clkgate_en_1.cr_lpe_pri_clkgate_en
|
||||
E(CCU, 0x1c, MASK_VAL(25, 24, 0x0)), //vlv.ccu.clkgate_en_1.cr_lpe_sb_clkgate_en
|
||||
E(CCU, 0x1c, MASK_VAL( 1, 0, 0x0)), //vlv.ccu.clkgate_en_1.lps_free_clkgate_en
|
||||
E(CCU, 0x54, MASK_VAL(17, 16, 0x0)), //vlv.ccu.clkgate_en_3.cr_lpe_func_ip_clkgate_en
|
||||
E(CCU, 0x54, MASK_VAL(13, 12, 0x0)), //vlv.ccu.clkgate_en_3.cr_lpe_osc_ip_clk_en
|
||||
E(CCU, 0x54, MASK_VAL(15, 14, 0x0)), //vlv.ccu.clkgate_en_3.cr_lpe_xtal_ip_clkgate_en
|
||||
E(CCU, 0x54, MASK_VAL(26, 24, 0x0)), //vlv.ccu.clkgate_en_3.psf_pri_clkgate_en
|
||||
E(CCU, 0x24, MASK_VAL(24, 20, 0x0)), //vlv.ccu.iclk_clkgate_ctrl.iopcibuffen_force_on
|
||||
E(0x59, 0x1e0, MASK_VAL(4, 4, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.iosfprim_trunk_gate_en
|
||||
E(0x59, 0x1e0, MASK_VAL(0, 0, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.iosfprimclk_gate_en
|
||||
E(0x59, 0x1e0, MASK_VAL(5, 5, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.iosfsb_trunk_gate_en
|
||||
E(0x59, 0x1e0, MASK_VAL(3, 3, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.iosfsbclk_gate_en
|
||||
E(0x59, 0x1e0, MASK_VAL(1, 1, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.ocpclk_gate_en
|
||||
E(0x59, 0x1e0, MASK_VAL(2, 2, 0x1)), //vlv.usb.xdci_otg.controller.pmctl.ocpclk_trunk_gate_en
|
||||
E(0x5a, 0xd0, MASK_VAL(8, 0, 0x3f)), //vlv.usb.xhci.controller.usb2pr.usb2hcsel
|
||||
E(0x5a, 0x40, MASK_VAL(21, 19, 0x6)), //vlv.usb.xhci.controller.xhcc1.iil1e
|
||||
E(0x5a, 0x40, MASK_VAL(10, 8, 0x1)), //vlv.usb.xhci.controller.xhcc1.l23hrawc
|
||||
E(0x5a, 0x40, MASK_VAL(18, 18, 0x1)), //vlv.usb.xhci.controller.xhcc1.xhcil1e
|
||||
E(0x5a, 0x50, MASK_VAL(3, 3, 0x1)), //vlv.usb.xhci.controller.xhclkgten.hsltcge
|
||||
E(0x5a, 0x50, MASK_VAL(0, 0, 0x1)), //vlv.usb.xhci.controller.xhclkgten.iosfblcge
|
||||
E(0x5a, 0x50, MASK_VAL(1, 1, 0x1)), //vlv.usb.xhci.controller.xhclkgten.iosfbtcge
|
||||
E(0x5a, 0x50, MASK_VAL(2, 2, 0x1)), //vlv.usb.xhci.controller.xhclkgten.ssltcge
|
||||
E(0x5a, 0x50, MASK_VAL(7, 5, 0x2)), //vlv.usb.xhci.controller.xhclkgten.sspllsue
|
||||
E(0x5a, 0x50, MASK_VAL(13, 13, 0x1)), //vlv.usb.xhci.controller.xhclkgten.xhcbbtcgipiso
|
||||
E(0x5a, 0x50, MASK_VAL(4, 4, 0x1)), //vlv.usb.xhci.controller.xhclkgten.xhcblcge
|
||||
E(0x5a, 0x50, MASK_VAL(14, 14, 0x1)), //vlv.usb.xhci.controller.xhclkgten.xhcftclkse
|
||||
E(0x5a, 0x50, MASK_VAL(12, 12, 0x0)), //vlv.usb.xhci.controller.xhclkgten.xhchstcgu2nrwe
|
||||
E(0x5a, 0x50, MASK_VAL(11, 10, 0x3)), //vlv.usb.xhci.controller.xhclkgten.xhcusb2pllsdle
|
||||
E(SCORE, 0x4900, MASK_VAL(16, 16, 0x1)), //vlv.gpio.gpscore.cfio_regs_com_cfg_score_pb_config.sb_clkgaten
|
||||
E(SSUS, 0x4900, MASK_VAL(16, 16, 0x1)), //vlv.gpio.gpssus.cfio_regs_com_cfg_ssus_pb_config.sb_clkgaten
|
||||
E(LPSS, 0x180, MASK_VAL(1, 1, 0x1)), //vlv.lpss.iosf2ahb.pmctl.ahb_clk_gate_en
|
||||
E(LPSS, 0x180, MASK_VAL(4, 4, 0x1)), //vlv.lpss.iosf2ahb.pmctl.ahb_trunk_gate_enable
|
||||
E(LPSS, 0x180, MASK_VAL(0, 0, 0x1)), //vlv.lpss.iosf2ahb.pmctl.iosf_clk_gate_enable
|
||||
E(LPSS, 0x180, MASK_VAL(3, 3, 0x1)), //vlv.lpss.iosf2ahb.pmctl.iosfprim_trunk_gate_enable
|
||||
E(LPSS, 0x180, MASK_VAL(5, 5, 0x1)), //vlv.lpss.iosf2ahb.pmctl.iosfsb_trunk_gate_enable
|
||||
E(LPSS, 0x180, MASK_VAL(2, 2, 0x1)), //vlv.lpss.iosf2ahb.pmctl.side_clk_gate_enable
|
||||
//0x54, 0xfc, 31, 0, 0x0, //vlv.pcu.iosfahbep.clock_gating_control
|
||||
//0x55, 0xfc, 1, 1, 0x0, //vlv.pcu.smbus.smb_config_cgc.pri_local_cgd
|
||||
//0x55, 0xfc, 0, 0, 0x0, //vlv.pcu.smbus.smb_config_cgc.pri_trunk_cgd
|
||||
//0x55, 0xfc, 8, 8, 0x0, //vlv.pcu.smbus.smb_config_cgc.sb_trunk_cgd
|
||||
E(SCC, 0x600, MASK_VAL(31, 15, 0x5)), //vlv.scc.iosf2ocp.gen_regrw1.gen_reg_rw1
|
||||
E(SCC, 0x1e0, MASK_VAL(4, 4, 0x1)), //vlv.scc.iosf2ocp.pmctl.iosfprim_trunk_gate_en
|
||||
E(SCC, 0x1e0, MASK_VAL(0, 0, 0x1)), //vlv.scc.iosf2ocp.pmctl.iosfprimclk_gate_en
|
||||
E(SCC, 0x1e0, MASK_VAL(5, 5, 0x1)), //vlv.scc.iosf2ocp.pmctl.iosfsb_trunk_gate_en
|
||||
E(SCC, 0x1e0, MASK_VAL(3, 3, 0x1)), //vlv.scc.iosf2ocp.pmctl.iosfsbclk_gate_en
|
||||
E(SCC, 0x1e0, MASK_VAL(1, 1, 0x1)), //vlv.scc.iosf2ocp.pmctl.ocpclk_gate_en
|
||||
E(SCC, 0x1e0, MASK_VAL(2, 2, 0x1)), //vlv.scc.iosf2ocp.pmctl.ocpclk_trunk_gate_en
|
||||
E(SEC, 0x88, MASK_VAL(7, 7, 0x0)), //vlv.sec.clk_gate_dis.nfc_cg_dis
|
||||
E(SEC, 0x88, MASK_VAL(1, 1, 0x0)), //vlv.sec.clk_gate_dis.prim_cg_dis
|
||||
E(SEC, 0x88, MASK_VAL(2, 2, 0x0)), //vlv.sec.clk_gate_dis.prim_clkreq_dis
|
||||
E(SEC, 0x88, MASK_VAL(3, 3, 0x0)), //vlv.sec.clk_gate_dis.prim_xsm_clkreq_dis
|
||||
E(SEC, 0x88, MASK_VAL(4, 4, 0x0)), //vlv.sec.clk_gate_dis.sap_cg_dis
|
||||
E(SEC, 0x88, MASK_VAL(6, 6, 0x0)), //vlv.sec.clk_gate_dis.sap_clkidle_dis
|
||||
E(SEC, 0x88, MASK_VAL(5, 5, 0x0)), //vlv.sec.clk_gate_dis.sap_ip_cg_dis
|
||||
E(SEC, 0x88, MASK_VAL(0, 0, 0x0)), //vlv.sec.clk_gate_dis.sb_cg_dis
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
|
||||
static void perf_power(void *unused)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Applying perf/power settings.\n");
|
||||
reg_script_run(perf_power_settings);
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, perf_power, NULL);
|
||||
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, perf_power, NULL);
|
11
src/soc/intel/braswell/placeholders.c
Normal file
11
src/soc/intel/braswell/placeholders.c
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
#include <arch/acpi.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <device/pci_rom.h>
|
||||
#include <soc/acpi.h>
|
||||
|
||||
|
||||
void smm_init(void) {}
|
||||
|
||||
/* Rmodules don't like weak symbols. */
|
||||
u32 map_oprom_vendev(u32 vendev) { return vendev; }
|
364
src/soc/intel/braswell/pmutil.c
Normal file
364
src/soc/intel/braswell/pmutil.c
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
* 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 <arch/io.h>
|
||||
#include <console/console.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
|
||||
#if defined(__SMM__)
|
||||
|
||||
static const device_t pcu_dev = PCI_DEV(0, PCU_DEV, 0);
|
||||
|
||||
static inline device_t get_pcu_dev(void)
|
||||
{
|
||||
return pcu_dev;
|
||||
}
|
||||
|
||||
#else /* !__SMM__ */
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
|
||||
static device_t pcu_dev;
|
||||
static device_t get_pcu_dev(void)
|
||||
{
|
||||
if (pcu_dev == NULL)
|
||||
pcu_dev = dev_find_slot(0, PCI_DEVFN(PCU_DEV, 0));
|
||||
return pcu_dev;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t get_pmbase(void)
|
||||
{
|
||||
return pci_read_config16(get_pcu_dev(), ABASE) & 0xfff8;
|
||||
}
|
||||
|
||||
static void print_num_status_bits(int num_bits, uint32_t status,
|
||||
const char *bit_names[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
for (i = num_bits - 1; i >= 0; i--) {
|
||||
if (status & (1 << i)) {
|
||||
if (bit_names[i])
|
||||
printk(BIOS_DEBUG, "%s ", bit_names[i]);
|
||||
else
|
||||
printk(BIOS_DEBUG, "BIT%d ", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void print_status_bits(uint32_t status, const char *bit_names[])
|
||||
{
|
||||
print_num_status_bits(32, status, bit_names);
|
||||
}
|
||||
|
||||
static uint32_t print_smi_status(uint32_t smi_sts)
|
||||
{
|
||||
static const char *smi_sts_bits[] = {
|
||||
[2] = "BIOS",
|
||||
[4] = "SLP_SMI",
|
||||
[5] = "APM",
|
||||
[6] = "SWSMI_TMR",
|
||||
[8] = "PM1",
|
||||
[9] = "GPE0",
|
||||
[12] = "DEVMON",
|
||||
[13] = "TCO",
|
||||
[14] = "PERIODIC",
|
||||
[15] = "ILB",
|
||||
[16] = "SMBUS_SMI",
|
||||
[17] = "LEGACY_USB2",
|
||||
[18] = "INTEL_USB2",
|
||||
[20] = "PCI_EXP_SMI",
|
||||
[26] = "SPI",
|
||||
[28] = "PUNIT",
|
||||
[29] = "GUNIT",
|
||||
};
|
||||
|
||||
if (!smi_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "SMI_STS: ");
|
||||
print_status_bits(smi_sts, smi_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return smi_sts;
|
||||
}
|
||||
|
||||
static uint32_t reset_smi_status(void)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t smi_sts = inl(pmbase + SMI_STS);
|
||||
outl(smi_sts, pmbase + SMI_STS);
|
||||
return smi_sts;
|
||||
}
|
||||
|
||||
uint32_t clear_smi_status(void)
|
||||
{
|
||||
return print_smi_status(reset_smi_status());
|
||||
}
|
||||
|
||||
void enable_smi(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t smi_en = inl(pmbase + SMI_EN);
|
||||
smi_en |= mask;
|
||||
outl(smi_en, pmbase + SMI_EN);
|
||||
}
|
||||
|
||||
void disable_smi(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t smi_en = inl(pmbase + SMI_EN);
|
||||
smi_en &= ~mask;
|
||||
outl(smi_en, pmbase + SMI_EN);
|
||||
}
|
||||
|
||||
void enable_pm1_control(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t pm1_cnt = inl(pmbase + PM1_CNT);
|
||||
pm1_cnt |= mask;
|
||||
outl(pm1_cnt, pmbase + PM1_CNT);
|
||||
}
|
||||
|
||||
void disable_pm1_control(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t pm1_cnt = inl(pmbase + PM1_CNT);
|
||||
pm1_cnt &= ~mask;
|
||||
outl(pm1_cnt, pmbase + PM1_CNT);
|
||||
}
|
||||
|
||||
static uint16_t reset_pm1_status(void)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint16_t pm1_sts = inw(pmbase + PM1_STS);
|
||||
outw(pm1_sts, pmbase + PM1_STS);
|
||||
return pm1_sts;
|
||||
}
|
||||
|
||||
static uint16_t print_pm1_status(uint16_t pm1_sts)
|
||||
{
|
||||
static const char *pm1_sts_bits[] = {
|
||||
[0] = "TMROF",
|
||||
[5] = "GBL",
|
||||
[8] = "PWRBTN",
|
||||
[10] = "RTC",
|
||||
[11] = "PRBTNOR",
|
||||
[13] = "USB",
|
||||
[14] = "PCIEXPWAK",
|
||||
[15] = "WAK",
|
||||
};
|
||||
|
||||
if (!pm1_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_SPEW, "PM1_STS: ");
|
||||
print_status_bits(pm1_sts, pm1_sts_bits);
|
||||
printk(BIOS_SPEW, "\n");
|
||||
|
||||
return pm1_sts;
|
||||
}
|
||||
|
||||
uint16_t clear_pm1_status(void)
|
||||
{
|
||||
return print_pm1_status(reset_pm1_status());
|
||||
}
|
||||
|
||||
void enable_pm1(uint16_t events)
|
||||
{
|
||||
outw(events, get_pmbase() + PM1_EN);
|
||||
}
|
||||
|
||||
static uint32_t print_tco_status(uint32_t tco_sts)
|
||||
{
|
||||
static const char *tco_sts_bits[] = {
|
||||
[3] = "TIMEOUT",
|
||||
[17] = "SECOND_TO",
|
||||
};
|
||||
|
||||
if (!tco_sts)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_DEBUG, "TCO_STS: ");
|
||||
print_status_bits(tco_sts, tco_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return tco_sts;
|
||||
}
|
||||
|
||||
static uint32_t reset_tco_status(void)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t tco_sts = inl(pmbase + TCO_STS);
|
||||
uint32_t tco_en = inl(pmbase + TCO1_CNT);
|
||||
|
||||
outl(tco_sts, pmbase + TCO_STS);
|
||||
return tco_sts & tco_en;
|
||||
}
|
||||
|
||||
uint32_t clear_tco_status(void)
|
||||
{
|
||||
return print_tco_status(reset_tco_status());
|
||||
}
|
||||
|
||||
void enable_gpe(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t gpe0_en = inl(pmbase + GPE0_EN);
|
||||
gpe0_en |= mask;
|
||||
outl(gpe0_en, pmbase + GPE0_EN);
|
||||
}
|
||||
|
||||
void disable_gpe(uint32_t mask)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t gpe0_en = inl(pmbase + GPE0_EN);
|
||||
gpe0_en &= ~mask;
|
||||
outl(gpe0_en, pmbase + GPE0_EN);
|
||||
}
|
||||
|
||||
void disable_all_gpe(void)
|
||||
{
|
||||
disable_gpe(~0);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t reset_gpe_status(void)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t gpe_sts = inl(pmbase + GPE0_STS);
|
||||
outl(gpe_sts, pmbase + GPE0_STS);
|
||||
return gpe_sts;
|
||||
}
|
||||
|
||||
static uint32_t print_gpe_sts(uint32_t gpe_sts)
|
||||
{
|
||||
static const char *gpe_sts_bits[] = {
|
||||
[1] = "HOTPLUG",
|
||||
[2] = "SWGPE",
|
||||
[3] = "PCIE_WAKE0",
|
||||
[4] = "PUNIT",
|
||||
[5] = "GUNIT",
|
||||
[6] = "PCIE_WAKE1",
|
||||
[7] = "PCIE_WAKE2",
|
||||
[8] = "PCIE_WAKE3",
|
||||
[9] = "PCI_EXP",
|
||||
[10] = "BATLOW",
|
||||
[13] = "PME_B0",
|
||||
[16] = "SUS_GPIO_0",
|
||||
[17] = "SUS_GPIO_1",
|
||||
[18] = "SUS_GPIO_2",
|
||||
[19] = "SUS_GPIO_3",
|
||||
[20] = "SUS_GPIO_4",
|
||||
[21] = "SUS_GPIO_5",
|
||||
[22] = "SUS_GPIO_6",
|
||||
[23] = "SUS_GPIO_7",
|
||||
[24] = "CORE_GPIO_0",
|
||||
[25] = "CORE_GPIO_1",
|
||||
[26] = "CORE_GPIO_2",
|
||||
[27] = "CORE_GPIO_3",
|
||||
[28] = "CORE_GPIO_4",
|
||||
[29] = "CORE_GPIO_5",
|
||||
[30] = "CORE_GPIO_6",
|
||||
[31] = "CORE_GPIO_7",
|
||||
};
|
||||
|
||||
if (!gpe_sts)
|
||||
return gpe_sts;
|
||||
|
||||
printk(BIOS_DEBUG, "GPE0a_STS: ");
|
||||
print_status_bits(gpe_sts, gpe_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return gpe_sts;
|
||||
}
|
||||
|
||||
uint32_t clear_gpe_status(void)
|
||||
{
|
||||
return print_gpe_sts(reset_gpe_status());
|
||||
}
|
||||
|
||||
static uint32_t reset_alt_status(void)
|
||||
{
|
||||
uint16_t pmbase = get_pmbase();
|
||||
uint32_t alt_gpio_smi = inl(pmbase + ALT_GPIO_SMI);
|
||||
outl(alt_gpio_smi, pmbase + ALT_GPIO_SMI);
|
||||
return alt_gpio_smi;
|
||||
}
|
||||
|
||||
static uint32_t print_alt_sts(uint32_t alt_gpio_smi)
|
||||
{
|
||||
uint32_t alt_gpio_sts;
|
||||
static const char *alt_gpio_smi_sts_bits[] = {
|
||||
[0] = "SUS_GPIO_0",
|
||||
[1] = "SUS_GPIO_1",
|
||||
[2] = "SUS_GPIO_2",
|
||||
[3] = "SUS_GPIO_3",
|
||||
[4] = "SUS_GPIO_4",
|
||||
[5] = "SUS_GPIO_5",
|
||||
[6] = "SUS_GPIO_6",
|
||||
[7] = "SUS_GPIO_7",
|
||||
[8] = "CORE_GPIO_0",
|
||||
[9] = "CORE_GPIO_1",
|
||||
[10] = "CORE_GPIO_2",
|
||||
[11] = "CORE_GPIO_3",
|
||||
[12] = "CORE_GPIO_4",
|
||||
[13] = "CORE_GPIO_5",
|
||||
[14] = "CORE_GPIO_6",
|
||||
[15] = "CORE_GPIO_7",
|
||||
};
|
||||
|
||||
/* Status bits are in the upper 16 bits. */
|
||||
alt_gpio_sts = alt_gpio_smi >> 16;
|
||||
if (!alt_gpio_sts)
|
||||
return alt_gpio_smi;
|
||||
|
||||
printk(BIOS_DEBUG, "ALT_GPIO_SMI: ");
|
||||
print_num_status_bits(16, alt_gpio_sts, alt_gpio_smi_sts_bits);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
|
||||
return alt_gpio_smi;
|
||||
}
|
||||
|
||||
uint32_t clear_alt_status(void)
|
||||
{
|
||||
return print_alt_sts(reset_alt_status());
|
||||
}
|
||||
|
||||
void clear_pmc_status(void)
|
||||
{
|
||||
uint32_t prsts;
|
||||
uint32_t gen_pmcon1;
|
||||
|
||||
prsts = read32((u32 *)(PMC_BASE_ADDRESS + PRSTS));
|
||||
gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1));
|
||||
|
||||
/* Clear the status bits. The RPS field is cleared on a 0 write. */
|
||||
write32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1), gen_pmcon1 & ~RPS);
|
||||
write32((u32 *)(PMC_BASE_ADDRESS + PRSTS), prsts);
|
||||
}
|
206
src/soc/intel/braswell/ramstage.c
Normal file
206
src/soc/intel/braswell/ramstage.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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/cpu.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/intel/microcode.h>
|
||||
#include <cpu/x86/cr.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/msr.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pattrs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/iosf.h>
|
||||
|
||||
/* Global PATTRS */
|
||||
DEFINE_PATTRS;
|
||||
|
||||
#define SHOW_PATTRS 1
|
||||
|
||||
static void detect_num_cpus(struct pattrs *attrs)
|
||||
{
|
||||
int ecx = 0;
|
||||
|
||||
while (1) {
|
||||
struct cpuid_result leaf_b;
|
||||
|
||||
leaf_b = cpuid_ext(0xb, ecx);
|
||||
|
||||
/* Bay Trail doesn't have hyperthreading so just determine the
|
||||
* number of cores by from level type (ecx[15:8] == * 2). */
|
||||
if ((leaf_b.ecx & 0xff00) == 0x0200) {
|
||||
attrs->num_cpus = leaf_b.ebx & 0xffff;
|
||||
break;
|
||||
}
|
||||
ecx++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fill_in_msr(msr_t *msr, int idx)
|
||||
{
|
||||
*msr = rdmsr(idx);
|
||||
if (SHOW_PATTRS) {
|
||||
printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
|
||||
idx, msr->hi, msr->lo);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *stepping_str[] = {
|
||||
"A0", "A1", "B0", "B1", "B2", "B3", "C0"
|
||||
};
|
||||
|
||||
static void fill_in_pattrs(void)
|
||||
{
|
||||
device_t dev;
|
||||
msr_t msr;
|
||||
struct pattrs *attrs = (struct pattrs *)pattrs_get();
|
||||
|
||||
attrs->cpuid = cpuid_eax(1);
|
||||
dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
|
||||
attrs->revid = pci_read_config8(dev, REVID);
|
||||
/* The revision to stepping IDs have two values per metal stepping. */
|
||||
if (attrs->revid >= RID_C_STEPPING_START) {
|
||||
attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
|
||||
attrs->stepping += STEP_C0;
|
||||
} else if (attrs->revid >= RID_B_STEPPING_START) {
|
||||
attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
|
||||
attrs->stepping += STEP_B0;
|
||||
} else {
|
||||
attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
|
||||
attrs->stepping += STEP_A0;
|
||||
}
|
||||
|
||||
attrs->microcode_patch = intel_microcode_find();
|
||||
attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
|
||||
detect_num_cpus(attrs);
|
||||
|
||||
if (SHOW_PATTRS) {
|
||||
printk(BIOS_DEBUG, "BYT: cpuid %08x cpus %d rid %02x step %s\n",
|
||||
attrs->cpuid, attrs->num_cpus, attrs->revid,
|
||||
(attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
|
||||
stepping_str[attrs->stepping]);
|
||||
}
|
||||
|
||||
fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID);
|
||||
fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
|
||||
|
||||
/* Set IA core speed ratio and voltages */
|
||||
msr = rdmsr(MSR_IACORE_RATIOS);
|
||||
attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f;
|
||||
attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
|
||||
attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
|
||||
msr = rdmsr(MSR_IACORE_TURBO_RATIOS);
|
||||
attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
|
||||
|
||||
msr = rdmsr(MSR_IACORE_VIDS);
|
||||
attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f;
|
||||
attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
|
||||
attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
|
||||
msr = rdmsr(MSR_IACORE_TURBO_VIDS);
|
||||
attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
|
||||
|
||||
/* Set bus clock speed */
|
||||
attrs->bclk_khz = bus_freq_khz();
|
||||
}
|
||||
|
||||
/* Save bit index for first enabled event in PM1_STS for \_SB._SWS */
|
||||
static void s3_save_acpi_wake_source(global_nvs_t *gnvs)
|
||||
{
|
||||
struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
|
||||
uint16_t pm1;
|
||||
|
||||
if (!ps)
|
||||
return;
|
||||
|
||||
pm1 = ps->pm1_sts & ps->pm1_en;
|
||||
|
||||
/* Scan for first set bit in PM1 */
|
||||
for (gnvs->pm1i = 0; gnvs->pm1i < 16; gnvs->pm1i++) {
|
||||
if (pm1 & 1)
|
||||
break;
|
||||
pm1 >>= 1;
|
||||
}
|
||||
|
||||
/* If unable to determine then return -1 */
|
||||
if (gnvs->pm1i >= 16)
|
||||
gnvs->pm1i = -1;
|
||||
|
||||
printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n",
|
||||
gnvs->pm1i);
|
||||
}
|
||||
|
||||
static void s3_resume_prepare(void)
|
||||
{
|
||||
global_nvs_t *gnvs;
|
||||
|
||||
gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
|
||||
if (gnvs == NULL)
|
||||
return;
|
||||
|
||||
if (!acpi_is_wakeup_s3())
|
||||
memset(gnvs, 0, sizeof(global_nvs_t));
|
||||
else
|
||||
s3_save_acpi_wake_source(gnvs);
|
||||
}
|
||||
|
||||
static void baytrail_enable_2x_refresh_rate(void)
|
||||
{
|
||||
u32 reg;
|
||||
reg = iosf_dunit_read(0x8);
|
||||
reg = reg & ~0x7000;
|
||||
reg = reg | 0x2000;
|
||||
iosf_dunit_write(0x8, reg);
|
||||
}
|
||||
|
||||
void baytrail_init_pre_device(struct soc_intel_baytrail_config *config)
|
||||
{
|
||||
struct soc_gpio_config *gpio_config;
|
||||
|
||||
fill_in_pattrs();
|
||||
|
||||
if (!config->disable_ddr_2x_refresh_rate)
|
||||
baytrail_enable_2x_refresh_rate();
|
||||
|
||||
/* Allow for SSE instructions to be executed. */
|
||||
write_cr4(read_cr4() | CR4_OSFXSR | CR4_OSXMMEXCPT);
|
||||
|
||||
/* Indicate S3 resume to rest of ramstage. */
|
||||
s3_resume_prepare();
|
||||
|
||||
/* Run reference code. */
|
||||
baytrail_run_reference_code();
|
||||
|
||||
/* Get GPIO initial states from mainboard */
|
||||
gpio_config = mainboard_get_gpios();
|
||||
setup_soc_gpios(gpio_config, config->enable_xdp_tap);
|
||||
|
||||
baytrail_init_scc();
|
||||
}
|
148
src/soc/intel/braswell/refcode.c
Normal file
148
src/soc/intel/braswell/refcode.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 <arch/acpi.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <console/streams.h>
|
||||
#include <cpu/x86/tsc.h>
|
||||
#include <program_loading.h>
|
||||
#include <rmodule.h>
|
||||
#include <stage_cache.h>
|
||||
#if IS_ENABLED(CONFIG_CHROMEOS)
|
||||
#include <vendorcode/google/chromeos/vboot_handoff.h>
|
||||
#endif
|
||||
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/efi_wrapper.h>
|
||||
|
||||
static void ABI_X86 send_to_console(unsigned char b)
|
||||
{
|
||||
console_tx_byte(b);
|
||||
}
|
||||
|
||||
static efi_wrapper_entry_t load_refcode_from_cache(void)
|
||||
{
|
||||
struct prog refcode;
|
||||
|
||||
printk(BIOS_DEBUG, "refcode loading from cache.\n");
|
||||
|
||||
stage_cache_load_stage(STAGE_REFCODE, &refcode);
|
||||
|
||||
return (efi_wrapper_entry_t)prog_entry(&refcode);
|
||||
}
|
||||
|
||||
static void cache_refcode(const struct rmod_stage_load *rsl)
|
||||
{
|
||||
stage_cache_add(STAGE_REFCODE, rsl->prog);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CHROMEOS)
|
||||
static int load_refcode_from_vboot(struct rmod_stage_load *refcode)
|
||||
{
|
||||
struct vboot_handoff *vboot_handoff;
|
||||
const struct firmware_component *fwc;
|
||||
struct cbfs_stage *stage;
|
||||
|
||||
vboot_handoff = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);
|
||||
fwc = &vboot_handoff->components[CONFIG_VBOOT_REFCODE_INDEX];
|
||||
|
||||
if (vboot_handoff == NULL ||
|
||||
vboot_handoff->selected_firmware == VB_SELECT_FIRMWARE_READONLY ||
|
||||
CONFIG_VBOOT_REFCODE_INDEX >= MAX_PARSED_FW_COMPONENTS ||
|
||||
fwc->size == 0 || fwc->address == 0)
|
||||
return -1;
|
||||
|
||||
printk(BIOS_DEBUG, "refcode loading from vboot rw area.\n");
|
||||
stage = (void *)(uintptr_t)fwc->address;
|
||||
|
||||
if (rmodule_stage_load(refcode, stage)) {
|
||||
printk(BIOS_DEBUG, "Error loading reference code.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int load_refcode_from_vboot(struct rmod_stage_load *refcode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int load_refcode_from_cbfs(struct rmod_stage_load *refcode)
|
||||
{
|
||||
printk(BIOS_DEBUG, "refcode loading from cbfs.\n");
|
||||
|
||||
if (rmodule_stage_load_from_cbfs(refcode)) {
|
||||
printk(BIOS_DEBUG, "Error loading reference code.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static efi_wrapper_entry_t load_reference_code(void)
|
||||
{
|
||||
struct prog prog = {
|
||||
.name = CONFIG_CBFS_PREFIX "/refcode",
|
||||
};
|
||||
struct rmod_stage_load refcode = {
|
||||
.cbmem_id = CBMEM_ID_REFCODE,
|
||||
.prog = &prog,
|
||||
};
|
||||
|
||||
if (acpi_is_wakeup_s3()) {
|
||||
return load_refcode_from_cache();
|
||||
}
|
||||
|
||||
if (load_refcode_from_vboot(&refcode) ||
|
||||
load_refcode_from_cbfs(&refcode))
|
||||
return NULL;
|
||||
|
||||
/* Cache loaded reference code. */
|
||||
cache_refcode(&refcode);
|
||||
|
||||
return prog_entry(&prog);
|
||||
}
|
||||
|
||||
void baytrail_run_reference_code(void)
|
||||
{
|
||||
int ret;
|
||||
efi_wrapper_entry_t entry;
|
||||
struct efi_wrapper_params wrp = {
|
||||
.version = EFI_WRAPPER_VER,
|
||||
.console_out = send_to_console,
|
||||
};
|
||||
|
||||
entry = load_reference_code();
|
||||
|
||||
if (entry == NULL)
|
||||
return;
|
||||
|
||||
wrp.tsc_ticks_per_microsecond = tsc_freq_mhz();
|
||||
|
||||
/* Call into reference code. */
|
||||
ret = entry(&wrp);
|
||||
|
||||
if (ret != 0) {
|
||||
printk(BIOS_DEBUG, "Reference code returned %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
47
src/soc/intel/braswell/reset.c
Normal file
47
src/soc/intel/braswell/reset.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 <soc/pmc.h>
|
||||
#include <soc/reset.h>
|
||||
|
||||
void cold_reset(void)
|
||||
{
|
||||
/* S0->S5->S0 trip. */
|
||||
outb(RST_CPU | SYS_RST | FULL_RST, RST_CNT);
|
||||
}
|
||||
|
||||
void warm_reset(void)
|
||||
{
|
||||
/* PMC_PLTRST# asserted. */
|
||||
outb(RST_CPU | SYS_RST, RST_CNT);
|
||||
}
|
||||
|
||||
void soft_reset(void)
|
||||
{
|
||||
/* Sends INIT# to CPU */
|
||||
outb(RST_CPU, RST_CNT);
|
||||
}
|
||||
|
||||
void hard_reset(void)
|
||||
{
|
||||
/* Don't power cycle on hard_reset(). It's not really clear what the
|
||||
* semantics should be for the meaning of hard_reset(). */
|
||||
warm_reset();
|
||||
}
|
7
src/soc/intel/braswell/romstage/Makefile.inc
Normal file
7
src/soc/intel/braswell/romstage/Makefile.inc
Normal file
@ -0,0 +1,7 @@
|
||||
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
|
||||
romstage-y += gfx.c
|
||||
romstage-y += pmc.c
|
||||
romstage-y += early_spi.c
|
285
src/soc/intel/braswell/romstage/cache_as_ram.inc
Normal file
285
src/soc/intel/braswell/romstage/cache_as_ram.inc
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* 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/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
|
||||
|
||||
/* Cache all of CBFS just below 4GiB as Write-Protect type. */
|
||||
#define CODE_CACHE_SIZE (CONFIG_CBFS_SIZE)
|
||||
#define CODE_CACHE_BASE (-CODE_CACHE_SIZE)
|
||||
#define CODE_CACHE_MASK (~(CODE_CACHE_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 code caching up for romstage. */
|
||||
movl $(MTRRphysBase_MSR(1)), %ecx
|
||||
movl $(CODE_CACHE_BASE | MTRR_TYPE_WRPROT), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
movl $(MTRRphysMask_MSR(1)), %ecx
|
||||
movl $(CODE_CACHE_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
|
||||
|
||||
/* Push the initial TSC value from boot block. The low 32 bits are
|
||||
* in mm0, and the high 32 bits are in mm1. */
|
||||
movd %mm1, %eax
|
||||
pushl %eax
|
||||
movd %mm0, %eax
|
||||
pushl %eax
|
||||
/* 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:
|
||||
|
65
src/soc/intel/braswell/romstage/early_spi.c
Normal file
65
src/soc/intel/braswell/romstage/early_spi.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 <delay.h>
|
||||
#include <console/console.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <soc/spi.h>
|
||||
|
||||
#define SPI_CYCLE_DELAY 10 /* 10us */
|
||||
#define SPI_CYCLE_TIMEOUT 400000 / SPI_CYCLE_DELAY /* 400ms */
|
||||
|
||||
#define SPI8(x) *((volatile u8 *)(SPI_BASE_ADDRESS + x))
|
||||
#define SPI16(x) *((volatile u16 *)(SPI_BASE_ADDRESS + x))
|
||||
#define SPI32(x) *((volatile u32 *)(SPI_BASE_ADDRESS + x))
|
||||
|
||||
/* Minimal set of commands to read wpsr from SPI. Don't use this code outside
|
||||
* romstage -- it trashes the opmenu table.
|
||||
* Returns 0 on success, < 0 on failure. */
|
||||
int early_spi_read_wpsr(u8 *sr)
|
||||
{
|
||||
int timeout = SPI_CYCLE_TIMEOUT;
|
||||
|
||||
/* No address associated with rdsr */
|
||||
SPI8(OPTYPE) = 0x0;
|
||||
/* Setup opcode[0] = read wpsr */
|
||||
SPI8(OPMENU0) = 0x5;
|
||||
|
||||
/* Start transaction */
|
||||
SPI16(SSFC) = DATA_CYCLE | SPI_CYCLE_GO;
|
||||
|
||||
/* Wait for error / complete status */
|
||||
while(timeout--) {
|
||||
u16 status = SPI16(SSFS);
|
||||
if (status & FLASH_CYCLE_ERROR) {
|
||||
printk(BIOS_ERR, "SPI rdsr failed\n");
|
||||
return -1;
|
||||
} else if (status & CYCLE_DONE_STATUS)
|
||||
break;
|
||||
|
||||
udelay(SPI_CYCLE_DELAY);
|
||||
}
|
||||
|
||||
*sr = SPI32(FDATA0) & 0xff;
|
||||
return 0;
|
||||
}
|
50
src/soc/intel/braswell/romstage/gfx.c
Normal file
50
src/soc/intel/braswell/romstage/gfx.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 <soc/gfx.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/romstage.h>
|
||||
|
||||
void gfx_init(void)
|
||||
{
|
||||
uint32_t ggc;
|
||||
uint8_t msac;
|
||||
const unsigned int gfx_dev = PCI_DEV(0, GFX_DEV, GFX_FUNC);
|
||||
|
||||
/* The GFX device needs to set the aperture, gtt stolen size, and
|
||||
* graphics stolen memory stolen size before running MRC. For now
|
||||
* just hard code the defaults. Options can be added to the device
|
||||
* tree if needed. */
|
||||
|
||||
ggc = pci_read_config32(gfx_dev, GGC);
|
||||
msac = pci_read_config8(gfx_dev, MSAC);
|
||||
|
||||
ggc &= ~(GGC_GTT_SIZE_MASK | GGC_GSM_SIZE_MASK);
|
||||
/* 32MB GSM is not supported with <C0 stepping. */
|
||||
ggc |= GGC_GTT_SIZE_2MB | GGC_GSM_SIZE_64MB;
|
||||
/* Enable VGA decoding as well. */
|
||||
ggc &= ~(GGC_VGA_DISABLE);
|
||||
|
||||
msac &= ~(APERTURE_SIZE_MASK);
|
||||
msac |= APERTURE_SIZE_256MB;
|
||||
|
||||
pci_write_config32(gfx_dev, GGC, ggc);
|
||||
pci_write_config8(gfx_dev, MSAC, msac);
|
||||
}
|
81
src/soc/intel/braswell/romstage/pmc.c
Normal file
81
src/soc/intel/braswell/romstage/pmc.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/romstage.h>
|
||||
#include "../chip.h"
|
||||
|
||||
void tco_disable(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = inl(ACPI_BASE_ADDRESS + TCO1_CNT);
|
||||
reg |= TCO_TMR_HALT;
|
||||
outl(reg, ACPI_BASE_ADDRESS + TCO1_CNT);
|
||||
}
|
||||
|
||||
/* This sequence signals the PUNIT to start running. */
|
||||
void punit_init(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint8_t rid;
|
||||
const struct device *dev;
|
||||
const struct soc_intel_baytrail_config *cfg = NULL;
|
||||
|
||||
rid = pci_read_config8(IOSF_PCI_DEV, REVID);
|
||||
dev = dev_find_slot(0, PCI_DEVFN(SOC_DEV, SOC_FUNC));
|
||||
|
||||
if (dev)
|
||||
cfg = dev->chip_info;
|
||||
|
||||
reg = iosf_punit_read(SB_BIOS_CONFIG);
|
||||
/* Write bits 17:16 of SB_BIOS_CONFIG in the PUNIT. */
|
||||
reg |= SB_BIOS_CONFIG_PERF_MODE | SB_BIOS_CONFIG_PDM_MODE;
|
||||
/* Configure VR low power mode for C0 and above. */
|
||||
if (rid >= RID_C_STEPPING_START && cfg != NULL &&
|
||||
(cfg->vnn_ps2_enable || cfg->vcc_ps2_enable)) {
|
||||
printk(BIOS_DEBUG, "Enabling VR PS2 mode: ");
|
||||
if (cfg->vnn_ps2_enable) {
|
||||
reg |= SB_BIOS_CONFIG_PS2_EN_VNN;
|
||||
printk(BIOS_DEBUG, "VNN ");
|
||||
}
|
||||
if (cfg->vcc_ps2_enable) {
|
||||
reg |= SB_BIOS_CONFIG_PS2_EN_VCC;
|
||||
printk(BIOS_DEBUG, "VCC ");
|
||||
}
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
}
|
||||
iosf_punit_write(SB_BIOS_CONFIG, reg);
|
||||
|
||||
/* Write bits 1:0 of BIOS_RESET_CPL in the PUNIT. */
|
||||
reg = BIOS_RESET_CPL_ALL_DONE | BIOS_RESET_CPL_RESET_DONE;
|
||||
pci_write_config32(IOSF_PCI_DEV, MDR_REG, reg);
|
||||
reg = IOSF_OPCODE(IOSF_OP_WRITE_PMC) | IOSF_PORT(IOSF_PORT_PMC) |
|
||||
IOSF_REG(BIOS_RESET_CPL) | IOSF_BYTE_EN_0;
|
||||
pci_write_config32(IOSF_PCI_DEV, MCR_REG, reg);
|
||||
}
|
191
src/soc/intel/braswell/romstage/raminit.c
Normal file
191
src/soc/intel/braswell/romstage/raminit.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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 <bootmode.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <halt.h>
|
||||
#include <stage_cache.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/intel/common/mrc_cache.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/reset.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#include <ec/google/chromeec/ec_commands.h>
|
||||
|
||||
static void reset_system(void)
|
||||
{
|
||||
warm_reset();
|
||||
halt();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void ABI_X86 send_to_console(unsigned char b)
|
||||
{
|
||||
do_putchar(b);
|
||||
}
|
||||
|
||||
static void print_dram_info(void)
|
||||
{
|
||||
const int mrc_ver_reg = 0xf0;
|
||||
const uint32_t soc_dev = PCI_DEV(0, SOC_DEV, SOC_FUNC);
|
||||
uint32_t reg;
|
||||
int num_channels;
|
||||
int speed;
|
||||
uint32_t ch0;
|
||||
uint32_t ch1;
|
||||
|
||||
reg = pci_read_config32(soc_dev, mrc_ver_reg);
|
||||
|
||||
printk(BIOS_INFO, "MRC v%d.%02d\n", (reg >> 8) & 0xff, reg & 0xff);
|
||||
|
||||
/* Number of channels enabled and DDR3 type. Determine number of
|
||||
* channels by keying of the rank enable bits [3:0]. * */
|
||||
ch0 = iosf_dunit_ch0_read(DRP);
|
||||
ch1 = iosf_dunit_ch1_read(DRP);
|
||||
num_channels = 0;
|
||||
if (ch0 & DRP_RANK_MASK)
|
||||
num_channels++;
|
||||
if (ch1 & DRP_RANK_MASK)
|
||||
num_channels++;
|
||||
|
||||
printk(BIOS_INFO, "%d channels of %sDDR3 @ ", num_channels,
|
||||
(reg & (1 << 22)) ? "LP" : "");
|
||||
|
||||
/* DRAM frequency -- all channels run at same frequency. */
|
||||
reg = iosf_dunit_read(DTR0);
|
||||
switch (reg & 0x3) {
|
||||
case 0:
|
||||
speed = 800; break;
|
||||
case 1:
|
||||
speed = 1066; break;
|
||||
case 2:
|
||||
speed = 1333; break;
|
||||
case 3:
|
||||
speed = 1600; break;
|
||||
}
|
||||
printk(BIOS_INFO, "%dMHz\n", speed);
|
||||
}
|
||||
|
||||
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 = &send_to_console;
|
||||
mp->prev_sleep_state = prev_sleep_state;
|
||||
mp->rmt_enabled = IS_ENABLED(CONFIG_MRC_RMT);
|
||||
|
||||
/* Default to 2GiB IO hole. */
|
||||
if (!mp->io_hole_mb)
|
||||
mp->io_hole_mb = 2048;
|
||||
|
||||
if (recovery_mode_enabled()) {
|
||||
printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n");
|
||||
} else if (!mrc_cache_get_current(&cache)) {
|
||||
mp->saved_data_size = cache->size;
|
||||
mp->saved_data = &cache->data[0];
|
||||
} else if (prev_sleep_state == 3) {
|
||||
/* If waking from S3 and no cache then. */
|
||||
printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n");
|
||||
post_code(POST_RESUME_FAILURE);
|
||||
reset_system();
|
||||
} else {
|
||||
printk(BIOS_DEBUG, "No MRC cache found.\n");
|
||||
#if CONFIG_EC_GOOGLE_CHROMEEC
|
||||
if (prev_sleep_state == 0) {
|
||||
/* Ensure EC is running RO firmware. */
|
||||
google_chromeec_check_ec_image(EC_IMAGE_RO);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Determine if mrc.bin is in the cbfs. */
|
||||
if (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "mrc.bin", CBFS_TYPE_MRC,
|
||||
NULL) == NULL) {
|
||||
printk(BIOS_DEBUG, "Couldn't find mrc.bin\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The entry point is currently the first instruction. Handle the
|
||||
* case of an ELF file being put in the cbfs by setting the entry
|
||||
* to the CONFIG_MRC_BIN_ADDRESS.
|
||||
*/
|
||||
mrc_entry = (void *)(uintptr_t)CONFIG_MRC_BIN_ADDRESS;
|
||||
|
||||
if (mp->mainboard.dram_info_location == DRAM_INFO_SPD_SMBUS)
|
||||
enable_smbus();
|
||||
|
||||
ret = mrc_entry(mp);
|
||||
|
||||
print_dram_info();
|
||||
|
||||
if (prev_sleep_state != 3) {
|
||||
cbmem_initialize_empty();
|
||||
stage_cache_create_empty();
|
||||
} else {
|
||||
stage_cache_recover();
|
||||
if (cbmem_initialize()) {
|
||||
#if CONFIG_HAVE_ACPI_RESUME
|
||||
printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
|
||||
/* Failed S3 resume, reset to come up cleanly */
|
||||
reset_system();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "MRC 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);
|
||||
}
|
377
src/soc/intel/braswell/romstage/romstage.c
Normal file
377
src/soc/intel/braswell/romstage/romstage.c
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
* 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/stages.h>
|
||||
#include <arch/early_variables.h>
|
||||
#include <console/console.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#if CONFIG_EC_GOOGLE_CHROMEEC
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#endif
|
||||
#include <elog.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <stage_cache.h>
|
||||
#include <timestamp.h>
|
||||
#include <vendorcode/google/chromeos/chromeos.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/reset.h>
|
||||
#include <soc/romstage.h>
|
||||
#include <soc/smm.h>
|
||||
#include <soc/spi.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 = PUNIT_BASE_ADDRESS | 2;
|
||||
pci_write_config32(lpc_dev, PUBASE, 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);
|
||||
}
|
||||
|
||||
static void spi_init(void)
|
||||
{
|
||||
u32 *scs = (u32 *)(SPI_BASE_ADDRESS + SCS);
|
||||
u32 *bcr = (u32 *)(SPI_BASE_ADDRESS + BCR);
|
||||
uint32_t reg;
|
||||
|
||||
/* Disable generating SMI when setting WPD bit. */
|
||||
write32(scs, read32(scs) & ~SMIWPEN);
|
||||
/*
|
||||
* Enable caching and prefetching in the SPI controller. Disable
|
||||
* the SMM-only BIOS write and set WPD bit.
|
||||
*/
|
||||
reg = (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH | BCR_WPD;
|
||||
reg &= ~EISS;
|
||||
write32(bcr, reg);
|
||||
}
|
||||
|
||||
/* Entry from cache-as-ram.inc. */
|
||||
void * asmlinkage romstage_main(unsigned long bist,
|
||||
uint32_t tsc_low, uint32_t tsc_hi)
|
||||
{
|
||||
struct romstage_params rp = {
|
||||
.bist = bist,
|
||||
.mrc_params = NULL,
|
||||
};
|
||||
|
||||
/* Save initial timestamp from bootblock. */
|
||||
timestamp_init((((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low);
|
||||
|
||||
/* Save romstage begin */
|
||||
timestamp_add_now(TS_START_ROMSTAGE);
|
||||
|
||||
program_base_addresses();
|
||||
|
||||
tco_disable();
|
||||
|
||||
byt_config_com1_and_enable();
|
||||
|
||||
console_init();
|
||||
|
||||
spi_init();
|
||||
|
||||
set_max_freq();
|
||||
|
||||
punit_init();
|
||||
|
||||
gfx_init();
|
||||
|
||||
#if CONFIG_EC_GOOGLE_CHROMEEC
|
||||
/* Ensure the EC is in the right mode for recovery */
|
||||
google_chromeec_early_init();
|
||||
#endif
|
||||
|
||||
/* Call into mainboard. */
|
||||
mainboard_romstage_entry(&rp);
|
||||
|
||||
return setup_stack_and_mttrs();
|
||||
}
|
||||
|
||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
||||
|
||||
static void migrate_power_state(void)
|
||||
{
|
||||
struct chipset_power_state *ps_cbmem;
|
||||
struct chipset_power_state *ps_car;
|
||||
|
||||
ps_car = car_get_var_ptr(&power_state);
|
||||
ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem));
|
||||
|
||||
if (ps_cbmem == NULL) {
|
||||
printk(BIOS_DEBUG, "Not adding power state to cbmem!\n");
|
||||
return;
|
||||
}
|
||||
memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
|
||||
}
|
||||
CAR_MIGRATE(migrate_power_state);
|
||||
|
||||
static struct chipset_power_state *fill_power_state(void)
|
||||
{
|
||||
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
||||
|
||||
ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
|
||||
ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN);
|
||||
ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
|
||||
ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS);
|
||||
ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN);
|
||||
ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS);
|
||||
ps->prsts = read32((u32 *)(PMC_BASE_ADDRESS + PRSTS));
|
||||
ps->gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1));
|
||||
ps->gen_pmcon2 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON2));
|
||||
|
||||
printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n",
|
||||
ps->pm1_sts, ps->pm1_en, ps->pm1_cnt);
|
||||
printk(BIOS_DEBUG, "gpe0_sts: %08x gpe0_en: %08x tco_sts: %08x\n",
|
||||
ps->gpe0_sts, ps->gpe0_en, ps->tco_sts);
|
||||
printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n",
|
||||
ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2);
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
/* Return 0, 3, or 5 to indicate the previous sleep state. */
|
||||
static int chipset_prev_sleep_state(struct chipset_power_state *ps)
|
||||
{
|
||||
/* Default to S0. */
|
||||
int prev_sleep_state = 0;
|
||||
|
||||
if (ps->pm1_sts & WAK_STS) {
|
||||
switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
|
||||
#if CONFIG_HAVE_ACPI_RESUME
|
||||
case SLP_TYP_S3:
|
||||
prev_sleep_state = 3;
|
||||
break;
|
||||
#endif
|
||||
case SLP_TYP_S5:
|
||||
prev_sleep_state = 5;
|
||||
break;
|
||||
}
|
||||
/* Clear SLP_TYP. */
|
||||
outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
|
||||
}
|
||||
|
||||
if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
|
||||
prev_sleep_state = 5;
|
||||
}
|
||||
|
||||
return prev_sleep_state;
|
||||
}
|
||||
|
||||
static inline void chromeos_init(int prev_sleep_state)
|
||||
{
|
||||
#if CONFIG_CHROMEOS
|
||||
/* Normalize the sleep state to what init_chromeos() wants for S3: 2. */
|
||||
init_chromeos(prev_sleep_state == 3 ? 2 : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Entry from the mainboard. */
|
||||
void romstage_common(struct romstage_params *params)
|
||||
{
|
||||
struct romstage_handoff *handoff;
|
||||
struct chipset_power_state *ps;
|
||||
int prev_sleep_state;
|
||||
|
||||
timestamp_add_now(TS_BEFORE_INITRAM);
|
||||
|
||||
ps = fill_power_state();
|
||||
prev_sleep_state = chipset_prev_sleep_state(ps);
|
||||
|
||||
printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
|
||||
|
||||
#if CONFIG_ELOG_BOOT_COUNT
|
||||
if (prev_sleep_state != 3)
|
||||
boot_count_increment();
|
||||
#endif
|
||||
|
||||
|
||||
/* Initialize RAM */
|
||||
raminit(params->mrc_params, prev_sleep_state);
|
||||
|
||||
timestamp_add_now(TS_AFTER_INITRAM);
|
||||
|
||||
handoff = romstage_handoff_find_or_add();
|
||||
if (handoff != NULL)
|
||||
handoff->s3_resume = (prev_sleep_state == 3);
|
||||
else
|
||||
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
|
||||
|
||||
chromeos_init(prev_sleep_state);
|
||||
}
|
||||
|
||||
void asmlinkage romstage_after_car(void)
|
||||
{
|
||||
timestamp_add_now(TS_END_ROMSTAGE);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void ramstage_cache_invalid(void)
|
||||
{
|
||||
#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE
|
||||
/* Perform cold reset on invalid ramstage cache. */
|
||||
cold_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_CHROMEOS
|
||||
int vboot_get_sw_write_protect(void)
|
||||
{
|
||||
u8 status;
|
||||
/* Return unprotected status if status read fails. */
|
||||
return (early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80));
|
||||
}
|
||||
#endif
|
38
src/soc/intel/braswell/romstage/uart.c
Normal file
38
src/soc/intel/braswell/romstage/uart.c
Normal file
@ -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
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/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 */
|
||||
score_select_func(UART_RXD_PAD, 1);
|
||||
score_select_func(UART_TXD_PAD, 1);
|
||||
}
|
240
src/soc/intel/braswell/sata.c
Normal file
240
src/soc/intel/braswell/sata.c
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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 <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/sata.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
typedef struct soc_intel_baytrail_config config_t;
|
||||
|
||||
static inline void sir_write(struct device *dev, int idx, u32 value)
|
||||
{
|
||||
pci_write_config32(dev, SATA_SIRI, idx);
|
||||
pci_write_config32(dev, SATA_SIRD, value);
|
||||
}
|
||||
|
||||
static void sata_init(struct device *dev)
|
||||
{
|
||||
config_t *config = dev->chip_info;
|
||||
u32 reg32;
|
||||
u16 reg16;
|
||||
u8 reg8;
|
||||
|
||||
printk(BIOS_DEBUG, "SATA: Initializing...\n");
|
||||
|
||||
if (config == NULL) {
|
||||
printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config->sata_ahci) {
|
||||
/* Set legacy or native decoding mode */
|
||||
if (config->ide_legacy_combined) {
|
||||
reg8 = pci_read_config8(dev, 0x09);
|
||||
reg8 &= ~0x5;
|
||||
pci_write_config8(dev, 0x09, reg8);
|
||||
} else {
|
||||
reg8 = pci_read_config8(dev, 0x09);
|
||||
reg8 |= 0x5;
|
||||
pci_write_config8(dev, 0x09, reg8);
|
||||
}
|
||||
|
||||
/* Set capabilities pointer */
|
||||
pci_write_config8(dev, 0x34, 0x70);
|
||||
reg16 = pci_read_config16(dev, 0x70);
|
||||
reg16 &= ~0xFF00;
|
||||
pci_write_config16(dev, 0x70, reg16);
|
||||
}
|
||||
|
||||
/* Primary timing - decode enable */
|
||||
reg16 = pci_read_config16(dev, 0x40);
|
||||
reg16 |= 1 << 15;
|
||||
pci_write_config16(dev, 0x40, reg16);
|
||||
|
||||
/* Secondary timing - decode enable */
|
||||
reg16 = pci_read_config16(dev, 0x42);
|
||||
reg16 |= 1 << 15;
|
||||
pci_write_config16(dev, 0x42, reg16);
|
||||
|
||||
/* Port mapping enables */
|
||||
reg16 = pci_read_config16(dev, 0x90);
|
||||
reg16 |= (config->sata_port_map ^ 0x3) << 8;
|
||||
pci_write_config16(dev, 0x90, reg16);
|
||||
|
||||
/* Port control enables */
|
||||
reg16 = pci_read_config16(dev, 0x92);
|
||||
reg16 &= ~0x003f;
|
||||
reg16 |= config->sata_port_map;
|
||||
pci_write_config16(dev, 0x92, reg16);
|
||||
|
||||
if (config->sata_ahci) {
|
||||
u8 *abar = (u8 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5);
|
||||
|
||||
/* Enable CR memory space decoding */
|
||||
reg16 = pci_read_config16(dev, 0x04);
|
||||
reg16 |= 0x2;
|
||||
pci_write_config16(dev, 0x04, reg16);
|
||||
|
||||
/* Set capability register */
|
||||
reg32 = read32(abar + 0x00);
|
||||
reg32 |= 0x0c046000; // set PSC+SSC+SALP+SSS+SAM
|
||||
reg32 &= ~0x00f20060; // clear SXS+EMS+PMS+gen bits
|
||||
reg32 |= (0x3 << 20); // Gen3 SATA
|
||||
write32(abar + 0x00, reg32);
|
||||
|
||||
/* Ports enabled */
|
||||
reg32 = read32(abar + 0x0c);
|
||||
reg32 &= (u32)(~0x3f);
|
||||
reg32 |= config->sata_port_map;
|
||||
write32(abar + 0xc, reg32);
|
||||
/* Two extra reads to latch */
|
||||
read32(abar + 0x0c);
|
||||
read32(abar + 0x0c);
|
||||
|
||||
/* Set cap2 - Support devslp */
|
||||
reg32 = (1 << 5) | (1 << 4) | (1 << 3);
|
||||
write32(abar + 0x24, reg32);
|
||||
|
||||
/* Set PxCMD registers */
|
||||
reg32 = read32(abar + 0x118);
|
||||
reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) |
|
||||
(1 << 19) | (1 << 18) | (1 << 1));
|
||||
reg32 |= 2;
|
||||
write32(abar + 0x118, reg32);
|
||||
|
||||
reg32 = read32(abar + 0x198);
|
||||
reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) |
|
||||
(1 << 19) | (1 << 18) | (1 << 1));
|
||||
reg32 |= 2;
|
||||
write32(abar + 0x198, reg32);
|
||||
|
||||
/* Clear reset features */
|
||||
write32(abar + 0xc8, 0);
|
||||
|
||||
/* Enable interrupts */
|
||||
reg8 = read8(abar + 0x04);
|
||||
reg8 |= 0x02;
|
||||
write8(abar + 0x04, reg8);
|
||||
|
||||
} else {
|
||||
/* TODO(shawnn): Configure IDE SATA speed regs */
|
||||
}
|
||||
|
||||
/* 1.4 us delay after configuring port / enable bits */
|
||||
udelay(2);
|
||||
|
||||
/* Enable clock for ports */
|
||||
reg32 = pci_read_config32(dev, 0x94);
|
||||
reg32 |= 0x3f << 24;
|
||||
pci_write_config32(dev, 0x94, reg32);
|
||||
reg32 &= (config->sata_port_map ^ 0x3) << 24;
|
||||
pci_write_config32(dev, 0x94, reg32);
|
||||
|
||||
/* Lock SataGc register */
|
||||
reg32 = (0x1 << 31) | (0x7 << 12);
|
||||
pci_write_config32(dev, 0x98, reg32);
|
||||
}
|
||||
|
||||
static void sata_enable(device_t dev)
|
||||
{
|
||||
config_t *config = dev->chip_info;
|
||||
u8 reg8;
|
||||
u16 reg16;
|
||||
u32 reg32;
|
||||
|
||||
southcluster_enable_dev(dev);
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
/* Port mapping -- mask off SPD + SMS + SC bits, then re-set */
|
||||
reg16 = pci_read_config16(dev, 0x90);
|
||||
reg16 &= ~0x03e0;
|
||||
reg16 |= (config->sata_port_map ^ 0x3) << 8;
|
||||
if(config->sata_ahci)
|
||||
reg16 |= 0x60;
|
||||
pci_write_config16(dev, 0x90, reg16);
|
||||
|
||||
/* Set reg 0x94 before starting configuration */
|
||||
reg32 = pci_read_config32(dev, 0x94);
|
||||
reg32 &= (u32)(~0x1ff);
|
||||
reg32 |= 0x183;
|
||||
pci_write_config32(dev, 0x94, reg32);
|
||||
|
||||
/* Set ORM bit */
|
||||
reg16 = pci_read_config16(dev, 0x92);
|
||||
reg16 |= (1 << 15);
|
||||
pci_write_config16(dev, 0x92, reg16);
|
||||
|
||||
/* R_PCH_SATA_TM2 - Undocumented in EDS, set according to ref. code */
|
||||
reg32 = pci_read_config32(dev, 0x98);
|
||||
reg32 &= (u32)~(0x1f80 | (1 << 6) | (1 << 5));
|
||||
reg32 |= (1 << 29) | (1 << 25) | (1 << 23) | (1 << 22) |
|
||||
(1 << 20) | (1 << 19) | (1 << 18) | (1 << 9) | (1 << 5);
|
||||
pci_write_config32(dev, 0x98, reg32);
|
||||
|
||||
/* CMD reg - set bus master enable (BME) */
|
||||
reg8 = pci_read_config8(dev, 0x04);
|
||||
reg8 |= (1 << 2);
|
||||
pci_write_config8(dev, 0x04, reg8);
|
||||
|
||||
/* "Test mode registers" */
|
||||
sir_write(dev, 0x70, 0x00288301);
|
||||
sir_write(dev, 0x54, 0x00000300);
|
||||
sir_write(dev, 0x58, 0x50000000);
|
||||
/* "OOB Detection Margin */
|
||||
sir_write(dev, 0x6c, 0x130C0603);
|
||||
/* "Gasket Control" */
|
||||
sir_write(dev, 0xf4, 0);
|
||||
|
||||
/* PCS - Enable requested SATA ports */
|
||||
reg8 = pci_read_config8(dev, 0x92);
|
||||
reg8 &= ~0x03;
|
||||
reg8 |= config->sata_port_map;
|
||||
pci_write_config8(dev, 0x92, reg8);
|
||||
}
|
||||
|
||||
static struct device_operations sata_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = sata_init,
|
||||
.enable = sata_enable,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const unsigned short pci_device_ids[] = {
|
||||
IDE1_DEVID, IDE2_DEVID, /* IDE */
|
||||
AHCI1_DEVID, AHCI2_DEVID, /* AHCI */
|
||||
0,
|
||||
};
|
||||
|
||||
static const struct pci_driver baytrail_sata __pci_driver = {
|
||||
.ops = &sata_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.devices = pci_device_ids,
|
||||
};
|
125
src/soc/intel/braswell/scc.c
Normal file
125
src/soc/intel/braswell/scc.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/ramstage.h>
|
||||
|
||||
static const struct reg_script scc_start_dll[] = {
|
||||
/* Configure master DLL. */
|
||||
REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4964, 0x00078000),
|
||||
/* Configure Swing,FSM for Master DLL */
|
||||
REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4970, 0x00000133),
|
||||
/* Run+Local Reset on Master DLL */
|
||||
REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4970, 0x00001933),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
static const struct reg_script scc_after_dll[] = {
|
||||
/* Configure Write Path */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4954, ~0x7fff, 0x35ad),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4958, ~0x7fff, 0x35ad),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x495c, ~0x7fff, 0x35ad),
|
||||
/* Configure Read Path */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x43e4, ~0x7fff, 0x35ad),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4324, ~0x7fff, 0x35ad),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x42b4, ~0x7fff, 0x35ad),
|
||||
/* eMMC 4.5 TX and RX DLL */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49a4, ~0x1f001f, 0xa000d),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49a8, ~0x1f001f, 0xd000d),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49ac, ~0x1f001f, 0xd000d),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b0, ~0x1f001f, 0xd000d),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b4, ~0x1f001f, 0xd000d),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b8, ~0x1, 0x0),
|
||||
/* cfio_regs_mmc1_ELECTRICAL.nslew/pslew */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c0, ~0x3c, 0x0),
|
||||
REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c4, ~0x3c, 0x0),
|
||||
/*
|
||||
* iosf2ocp_private.GENREGRW1.cr_clock_enable_clk_ocp = 01
|
||||
* iosf2ocp_private.GENREGRW1.cr_clock_enable_clk_xin = 01
|
||||
*/
|
||||
REG_IOSF_RMW(IOSF_PORT_SCC, 0x600, ~0xf, 0x5),
|
||||
/* Enable IOSF Snoop */
|
||||
REG_IOSF_OR(IOSF_PORT_SCC, 0x00, (1 << 7)),
|
||||
/* SDIO 3V Support. */
|
||||
REG_IOSF_RMW(IOSF_PORT_SCC, 0x600, ~0x30, 0x30),
|
||||
REG_SCRIPT_END,
|
||||
};
|
||||
|
||||
void baytrail_init_scc(void)
|
||||
{
|
||||
uint32_t dll_values;
|
||||
|
||||
printk(BIOS_DEBUG, "Initializing sideband SCC registers.\n");
|
||||
|
||||
/* Common Sideband Initialization for SCC */
|
||||
reg_script_run(scc_start_dll);
|
||||
|
||||
/* Override Slave Path - populate DLL settings. */
|
||||
dll_values = iosf_score_read(0x496c) & 0x7ffff;
|
||||
dll_values |= iosf_score_read(0x4950) & ~0xfffff;
|
||||
iosf_score_write(0x4950, dll_values | (1 << 19));
|
||||
|
||||
reg_script_run(scc_after_dll);
|
||||
}
|
||||
|
||||
void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
|
||||
{
|
||||
struct reg_script ops[] = {
|
||||
/* Disable PCI interrupt, enable Memory and Bus Master */
|
||||
REG_PCI_OR32(PCI_COMMAND,
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
|
||||
/* Enable ACPI mode */
|
||||
REG_IOSF_OR(IOSF_PORT_SCC, iosf_reg,
|
||||
SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
struct resource *bar;
|
||||
global_nvs_t *gnvs;
|
||||
|
||||
/* Find ACPI NVS to update BARs */
|
||||
gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
if (!gnvs) {
|
||||
printk(BIOS_ERR, "Unable to locate Global NVS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save BAR0 and BAR1 to ACPI NVS */
|
||||
bar = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
if (bar)
|
||||
gnvs->dev.scc_bar0[nvs_index] = (u32)bar->base;
|
||||
|
||||
bar = find_resource(dev, PCI_BASE_ADDRESS_1);
|
||||
if (bar)
|
||||
gnvs->dev.scc_bar1[nvs_index] = (u32)bar->base;
|
||||
|
||||
/* Device is enabled in ACPI mode */
|
||||
gnvs->dev.scc_en[nvs_index] = 1;
|
||||
|
||||
/* Put device in ACPI mode */
|
||||
reg_script_run_on_dev(dev, ops);
|
||||
}
|
70
src/soc/intel/braswell/sd.c
Normal file
70
src/soc/intel/braswell/sd.c
Normal file
@ -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
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include "chip.h"
|
||||
|
||||
#define CAP_OVERRIDE_LOW 0xa0
|
||||
#define CAP_OVERRIDE_HIGH 0xa4
|
||||
# define USE_CAP_OVERRIDES (1 << 31)
|
||||
|
||||
static void sd_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
|
||||
if (config == NULL)
|
||||
return;
|
||||
|
||||
if (config->sdcard_cap_low != 0 || config->sdcard_cap_high != 0) {
|
||||
printk(BIOS_DEBUG, "Overriding SD Card controller caps.\n");
|
||||
pci_write_config32(dev, CAP_OVERRIDE_LOW,
|
||||
config->sdcard_cap_low);
|
||||
pci_write_config32(dev, CAP_OVERRIDE_HIGH,
|
||||
config->sdcard_cap_high | USE_CAP_OVERRIDES);
|
||||
}
|
||||
|
||||
if (config->scc_acpi_mode)
|
||||
scc_enable_acpi_mode(dev, SCC_SD_CTL, SCC_NVS_SD);
|
||||
}
|
||||
|
||||
static const struct device_operations device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = sd_init,
|
||||
.enable = NULL,
|
||||
.scan_bus = NULL,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = SD_DEVID,
|
||||
};
|
483
src/soc/intel/braswell/smihandler.c
Normal file
483
src/soc/intel/braswell/smihandler.c
Normal file
@ -0,0 +1,483 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <elog.h>
|
||||
#include <halt.h>
|
||||
#include <spi-generic.h>
|
||||
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/nvs.h>
|
||||
|
||||
/* GNVS needs to be set by coreboot initiating a software SMI. */
|
||||
static global_nvs_t *gnvs;
|
||||
static int smm_initialized;
|
||||
|
||||
int southbridge_io_trap_handler(int smif)
|
||||
{
|
||||
switch (smif) {
|
||||
case 0x32:
|
||||
printk(BIOS_DEBUG, "OS Init\n");
|
||||
/* gnvs->smif:
|
||||
* On success, the IO Trap Handler returns 0
|
||||
* On failure, the IO Trap Handler returns a value != 0
|
||||
*/
|
||||
gnvs->smif = 0;
|
||||
return 1; /* IO trap handled */
|
||||
}
|
||||
|
||||
/* Not handled */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void southbridge_smi_set_eos(void)
|
||||
{
|
||||
enable_smi(EOS);
|
||||
}
|
||||
|
||||
global_nvs_t *smm_get_gnvs(void)
|
||||
{
|
||||
return gnvs;
|
||||
}
|
||||
|
||||
static void busmaster_disable_on_bus(int bus)
|
||||
{
|
||||
int slot, func;
|
||||
unsigned int val;
|
||||
unsigned char hdr;
|
||||
|
||||
for (slot = 0; slot < 0x20; slot++) {
|
||||
for (func = 0; func < 8; func++) {
|
||||
u32 reg32;
|
||||
device_t dev = PCI_DEV(bus, slot, func);
|
||||
|
||||
val = pci_read_config32(dev, PCI_VENDOR_ID);
|
||||
|
||||
if (val == 0xffffffff || val == 0x00000000 ||
|
||||
val == 0x0000ffff || val == 0xffff0000)
|
||||
continue;
|
||||
|
||||
/* Disable Bus Mastering for this one device */
|
||||
reg32 = pci_read_config32(dev, PCI_COMMAND);
|
||||
reg32 &= ~PCI_COMMAND_MASTER;
|
||||
pci_write_config32(dev, PCI_COMMAND, reg32);
|
||||
|
||||
/* If this is a bridge, then follow it. */
|
||||
hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
|
||||
hdr &= 0x7f;
|
||||
if (hdr == PCI_HEADER_TYPE_BRIDGE ||
|
||||
hdr == PCI_HEADER_TYPE_CARDBUS) {
|
||||
unsigned int buses;
|
||||
buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
|
||||
busmaster_disable_on_bus((buses >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void southbridge_smi_sleep(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
uint8_t slp_typ;
|
||||
uint16_t pmbase = get_pmbase();
|
||||
|
||||
/* First, disable further SMIs */
|
||||
disable_smi(SLP_SMI_EN);
|
||||
|
||||
/* Figure out SLP_TYP */
|
||||
reg32 = inl(pmbase + PM1_CNT);
|
||||
printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
|
||||
slp_typ = (reg32 >> 10) & 7;
|
||||
|
||||
/* Do any mainboard sleep handling */
|
||||
mainboard_smi_sleep(slp_typ-2);
|
||||
|
||||
#if CONFIG_ELOG_GSMI
|
||||
/* Log S3, S4, and S5 entry */
|
||||
if (slp_typ >= 5)
|
||||
elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ-2);
|
||||
#endif
|
||||
|
||||
/* Next, do the deed.
|
||||
*/
|
||||
|
||||
switch (slp_typ) {
|
||||
case SLP_TYP_S0:
|
||||
printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
|
||||
break;
|
||||
case SLP_TYP_S1:
|
||||
printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
|
||||
break;
|
||||
case SLP_TYP_S3:
|
||||
printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
|
||||
|
||||
/* Invalidate the cache before going to S3 */
|
||||
wbinvd();
|
||||
break;
|
||||
case SLP_TYP_S4:
|
||||
printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
|
||||
break;
|
||||
case SLP_TYP_S5:
|
||||
printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
|
||||
|
||||
/* Disable all GPE */
|
||||
disable_all_gpe();
|
||||
|
||||
/* also iterates over all bridges on bus 0 */
|
||||
busmaster_disable_on_bus(0);
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write back to the SLP register to cause the originally intended
|
||||
* event again. We need to set BIT13 (SLP_EN) though to make the
|
||||
* sleep happen.
|
||||
*/
|
||||
enable_pm1_control(SLP_EN);
|
||||
|
||||
/* Make sure to stop executing code here for S3/S4/S5 */
|
||||
if (slp_typ > 1)
|
||||
halt();
|
||||
|
||||
/* In most sleep states, the code flow of this function ends at
|
||||
* the line above. However, if we entered sleep state S1 and wake
|
||||
* up again, we will continue to execute code in this function.
|
||||
*/
|
||||
reg32 = inl(pmbase + PM1_CNT);
|
||||
if (reg32 & SCI_EN) {
|
||||
/* The OS is not an ACPI OS, so we set the state to S0 */
|
||||
disable_pm1_control(SLP_EN | SLP_TYP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for Synchronous IO SMI and use save state from that
|
||||
* core in case we are not running on the same core that
|
||||
* initiated the IO transaction.
|
||||
*/
|
||||
static em64t100_smm_state_save_area_t *smi_apmc_find_state_save(uint8_t cmd)
|
||||
{
|
||||
em64t100_smm_state_save_area_t *state;
|
||||
int node;
|
||||
|
||||
/* Check all nodes looking for the one that issued the IO */
|
||||
for (node = 0; node < CONFIG_MAX_CPUS; node++) {
|
||||
state = smm_get_save_state(node);
|
||||
|
||||
/* Check for Synchronous IO (bit0==1) */
|
||||
if (!(state->io_misc_info & (1 << 0)))
|
||||
continue;
|
||||
|
||||
/* Make sure it was a write (bit4==0) */
|
||||
if (state->io_misc_info & (1 << 4))
|
||||
continue;
|
||||
|
||||
/* Check for APMC IO port */
|
||||
if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
|
||||
continue;
|
||||
|
||||
/* Check AX against the requested command */
|
||||
if ((state->rax & 0xff) != cmd)
|
||||
continue;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_ELOG_GSMI
|
||||
static void southbridge_smi_gsmi(void)
|
||||
{
|
||||
u32 *ret, *param;
|
||||
uint8_t sub_command;
|
||||
em64t100_smm_state_save_area_t *io_smi =
|
||||
smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);
|
||||
|
||||
if (!io_smi)
|
||||
return;
|
||||
|
||||
/* Command and return value in EAX */
|
||||
ret = (u32*)&io_smi->rax;
|
||||
sub_command = (uint8_t)(*ret >> 8);
|
||||
|
||||
/* Parameter buffer in EBX */
|
||||
param = (u32*)&io_smi->rbx;
|
||||
|
||||
/* drivers/elog/gsmi.c */
|
||||
*ret = gsmi_exec(sub_command, param);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void finalize(void)
|
||||
{
|
||||
static int finalize_done;
|
||||
|
||||
if (finalize_done) {
|
||||
printk(BIOS_DEBUG, "SMM already finalized.\n");
|
||||
return;
|
||||
}
|
||||
finalize_done = 1;
|
||||
|
||||
#if CONFIG_SPI_FLASH_SMM
|
||||
/* Re-init SPI driver to handle locked BAR */
|
||||
spi_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* soc_legacy: A payload (Depthcharge) has indicated that the
|
||||
* legacy payload (SeaBIOS) is being loaded. Switch devices that are
|
||||
* in ACPI mode to PCI mode so that non-ACPI drivers may work.
|
||||
*
|
||||
*/
|
||||
static void soc_legacy(void)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
/* LPE Device */
|
||||
if (gnvs->dev.lpe_en) {
|
||||
reg32 = iosf_port58_read(LPE_PCICFGCTR1);
|
||||
reg32 &=
|
||||
~(LPE_PCICFGCTR1_PCI_CFG_DIS | LPE_PCICFGCTR1_ACPI_INT_EN);
|
||||
iosf_port58_write(LPE_PCICFGCTR1, reg32);
|
||||
}
|
||||
|
||||
/* SCC Devices */
|
||||
#define SCC_ACPI_MODE_DISABLE(name_) \
|
||||
do { if (gnvs->dev.scc_en[SCC_NVS_ ## name_]) { \
|
||||
reg32 = iosf_scc_read(SCC_ ## name_ ## _CTL); \
|
||||
reg32 &= ~(SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN); \
|
||||
iosf_scc_write(SCC_ ## name_ ## _CTL, reg32); \
|
||||
} } while (0)
|
||||
|
||||
SCC_ACPI_MODE_DISABLE(MMC);
|
||||
SCC_ACPI_MODE_DISABLE(SD);
|
||||
SCC_ACPI_MODE_DISABLE(SDIO);
|
||||
|
||||
/* LPSS Devices */
|
||||
#define LPSS_ACPI_MODE_DISABLE(name_) \
|
||||
do { if (gnvs->dev.lpss_en[LPSS_NVS_ ## name_]) { \
|
||||
reg32 = iosf_lpss_read(LPSS_ ## name_ ## _CTL); \
|
||||
reg32 &= ~LPSS_CTL_PCI_CFG_DIS | ~LPSS_CTL_ACPI_INT_EN; \
|
||||
iosf_lpss_write(LPSS_ ## name_ ## _CTL, reg32); \
|
||||
} } while (0)
|
||||
|
||||
LPSS_ACPI_MODE_DISABLE(SIO_DMA1);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C1);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C2);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C3);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C4);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C5);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C6);
|
||||
LPSS_ACPI_MODE_DISABLE(I2C7);
|
||||
LPSS_ACPI_MODE_DISABLE(SIO_DMA2);
|
||||
LPSS_ACPI_MODE_DISABLE(PWM1);
|
||||
LPSS_ACPI_MODE_DISABLE(PWM2);
|
||||
LPSS_ACPI_MODE_DISABLE(HSUART1);
|
||||
LPSS_ACPI_MODE_DISABLE(HSUART2);
|
||||
LPSS_ACPI_MODE_DISABLE(SPI);
|
||||
}
|
||||
|
||||
static void southbridge_smi_apmc(void)
|
||||
{
|
||||
uint8_t reg8;
|
||||
em64t100_smm_state_save_area_t *state;
|
||||
|
||||
/* Emulate B2 register as the FADT / Linux expects it */
|
||||
|
||||
reg8 = inb(APM_CNT);
|
||||
switch (reg8) {
|
||||
case APM_CNT_CST_CONTROL:
|
||||
/* Calling this function seems to cause
|
||||
* some kind of race condition in Linux
|
||||
* and causes a kernel oops
|
||||
*/
|
||||
printk(BIOS_DEBUG, "C-state control\n");
|
||||
break;
|
||||
case APM_CNT_PST_CONTROL:
|
||||
/* Calling this function seems to cause
|
||||
* some kind of race condition in Linux
|
||||
* and causes a kernel oops
|
||||
*/
|
||||
printk(BIOS_DEBUG, "P-state control\n");
|
||||
break;
|
||||
case APM_CNT_ACPI_DISABLE:
|
||||
disable_pm1_control(SCI_EN);
|
||||
printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
|
||||
break;
|
||||
case APM_CNT_ACPI_ENABLE:
|
||||
enable_pm1_control(SCI_EN);
|
||||
printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
|
||||
break;
|
||||
case APM_CNT_GNVS_UPDATE:
|
||||
if (smm_initialized) {
|
||||
printk(BIOS_DEBUG,
|
||||
"SMI#: SMM structures already initialized!\n");
|
||||
return;
|
||||
}
|
||||
state = smi_apmc_find_state_save(reg8);
|
||||
if (state) {
|
||||
/* EBX in the state save contains the GNVS pointer */
|
||||
gnvs = (global_nvs_t *)((uint32_t)state->rbx);
|
||||
smm_initialized = 1;
|
||||
printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
|
||||
}
|
||||
break;
|
||||
#if CONFIG_ELOG_GSMI
|
||||
case ELOG_GSMI_APM_CNT:
|
||||
southbridge_smi_gsmi();
|
||||
break;
|
||||
#endif
|
||||
case APM_CNT_FINALIZE:
|
||||
finalize();
|
||||
break;
|
||||
|
||||
case APM_CNT_LEGACY:
|
||||
soc_legacy();
|
||||
break;
|
||||
}
|
||||
|
||||
mainboard_smi_apmc(reg8);
|
||||
}
|
||||
|
||||
static void southbridge_smi_pm1(void)
|
||||
{
|
||||
uint16_t pm1_sts = clear_pm1_status();
|
||||
|
||||
/* While OSPM is not active, poweroff immediately
|
||||
* on a power button event.
|
||||
*/
|
||||
if (pm1_sts & PWRBTN_STS) {
|
||||
// power button pressed
|
||||
#if CONFIG_ELOG_GSMI
|
||||
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
||||
#endif
|
||||
disable_pm1_control(-1UL);
|
||||
enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
|
||||
}
|
||||
}
|
||||
|
||||
static void southbridge_smi_gpe0(void)
|
||||
{
|
||||
clear_gpe_status();
|
||||
}
|
||||
|
||||
static void southbridge_smi_tco(void)
|
||||
{
|
||||
uint32_t tco_sts = clear_tco_status();
|
||||
|
||||
/* Any TCO event? */
|
||||
if (!tco_sts)
|
||||
return;
|
||||
|
||||
if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
|
||||
/* Handle TCO timeout */
|
||||
printk(BIOS_DEBUG, "TCO Timeout.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void southbridge_smi_periodic(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
reg32 = inl(get_pmbase() + SMI_EN);
|
||||
|
||||
/* Are periodic SMIs enabled? */
|
||||
if ((reg32 & PERIODIC_EN) == 0)
|
||||
return;
|
||||
|
||||
printk(BIOS_DEBUG, "Periodic SMI.\n");
|
||||
}
|
||||
|
||||
typedef void (*smi_handler_t)(void);
|
||||
|
||||
static const smi_handler_t southbridge_smi[32] = {
|
||||
NULL, // [0] reserved
|
||||
NULL, // [1] reserved
|
||||
NULL, // [2] BIOS_STS
|
||||
NULL, // [3] LEGACY_USB_STS
|
||||
southbridge_smi_sleep, // [4] SLP_SMI_STS
|
||||
southbridge_smi_apmc, // [5] APM_STS
|
||||
NULL, // [6] SWSMI_TMR_STS
|
||||
NULL, // [7] reserved
|
||||
southbridge_smi_pm1, // [8] PM1_STS
|
||||
southbridge_smi_gpe0, // [9] GPE0_STS
|
||||
NULL, // [10] reserved
|
||||
NULL, // [11] reserved
|
||||
NULL, // [12] reserved
|
||||
southbridge_smi_tco, // [13] TCO_STS
|
||||
southbridge_smi_periodic, // [14] PERIODIC_STS
|
||||
NULL, // [15] SERIRQ_SMI_STS
|
||||
NULL, // [16] SMBUS_SMI_STS
|
||||
NULL, // [17] LEGACY_USB2_STS
|
||||
NULL, // [18] INTEL_USB2_STS
|
||||
NULL, // [19] reserved
|
||||
NULL, // [20] PCI_EXP_SMI_STS
|
||||
NULL, // [21] reserved
|
||||
NULL, // [22] reserved
|
||||
NULL, // [23] reserved
|
||||
NULL, // [24] reserved
|
||||
NULL, // [25] reserved
|
||||
NULL, // [26] SPI_STS
|
||||
NULL, // [27] reserved
|
||||
NULL, // [28] PUNIT
|
||||
NULL, // [29] GUNIT
|
||||
NULL, // [30] reserved
|
||||
NULL // [31] reserved
|
||||
};
|
||||
|
||||
void southbridge_smi_handler(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t smi_sts;
|
||||
|
||||
/* We need to clear the SMI status registers, or we won't see what's
|
||||
* happening in the following calls.
|
||||
*/
|
||||
smi_sts = clear_smi_status();
|
||||
|
||||
/* Call SMI sub handler for each of the status bits */
|
||||
for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {
|
||||
if (!(smi_sts & (1 << i)))
|
||||
continue;
|
||||
|
||||
if (southbridge_smi[i] != NULL) {
|
||||
southbridge_smi[i]();
|
||||
} else {
|
||||
printk(BIOS_DEBUG,
|
||||
"SMI_STS[%d] occurred, but no "
|
||||
"handler available.\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* The GPIO SMI events do not have a status bit in SMI_STS. Therefore,
|
||||
* these events need to be cleared and checked unconditionally. */
|
||||
mainboard_smi_gpi(clear_alt_status());
|
||||
}
|
133
src/soc/intel/braswell/smm.c
Normal file
133
src/soc/intel/braswell/smm.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <console/console.h>
|
||||
#include <arch/io.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
/* Save settings which will be committed in SMI functions. */
|
||||
static uint32_t smm_save_params[SMM_SAVE_PARAM_COUNT];
|
||||
|
||||
void southcluster_smm_save_param(int param, uint32_t data)
|
||||
{
|
||||
smm_save_params[param] = data;
|
||||
}
|
||||
|
||||
void southcluster_smm_clear_state(void)
|
||||
{
|
||||
uint32_t smi_en;
|
||||
|
||||
/* Log events from chipset before clearing */
|
||||
southcluster_log_state();
|
||||
|
||||
printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
|
||||
printk(BIOS_SPEW, " pmbase = 0x%04x\n", get_pmbase());
|
||||
|
||||
smi_en = inl(get_pmbase() + SMI_EN);
|
||||
if (smi_en & APMC_EN) {
|
||||
printk(BIOS_INFO, "SMI# handler already enabled?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Dump and clear status registers */
|
||||
clear_smi_status();
|
||||
clear_pm1_status();
|
||||
clear_tco_status();
|
||||
clear_gpe_status();
|
||||
clear_alt_status();
|
||||
clear_pmc_status();
|
||||
}
|
||||
|
||||
static void southcluster_smm_route_gpios(void)
|
||||
{
|
||||
u32 *gpio_rout = (u32 *)(PMC_BASE_ADDRESS + GPIO_ROUT);
|
||||
const unsigned short alt_gpio_smi = ACPI_BASE_ADDRESS + ALT_GPIO_SMI;
|
||||
uint32_t alt_gpio_reg = 0;
|
||||
uint32_t route_reg = smm_save_params[SMM_SAVE_PARAM_GPIO_ROUTE];
|
||||
int i;
|
||||
|
||||
printk(BIOS_DEBUG, "GPIO_ROUT = %08x\n", route_reg);
|
||||
|
||||
/* Start the routing for the specific gpios. */
|
||||
write32(gpio_rout, route_reg);
|
||||
|
||||
/* Enable SMIs for the gpios that are set to trigger the SMI. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((route_reg & ROUTE_MASK) == ROUTE_SMI) {
|
||||
alt_gpio_reg |= (1 << i);
|
||||
}
|
||||
route_reg >>= 2;
|
||||
}
|
||||
printk(BIOS_DEBUG, "ALT_GPIO_SMI = %08x\n", alt_gpio_reg);
|
||||
|
||||
outl(alt_gpio_reg, alt_gpio_smi);
|
||||
}
|
||||
|
||||
void southcluster_smm_enable_smi(void)
|
||||
{
|
||||
uint16_t pm1_events = PWRBTN_EN | GBL_EN;
|
||||
|
||||
printk(BIOS_DEBUG, "Enabling SMIs.\n");
|
||||
if (!smm_save_params[SMM_SAVE_PARAM_PCIE_WAKE_ENABLE])
|
||||
pm1_events |= PCIEXPWAK_DIS;
|
||||
enable_pm1(pm1_events);
|
||||
disable_gpe(PME_B0_EN);
|
||||
|
||||
/* Set up the GPIO route. */
|
||||
southcluster_smm_route_gpios();
|
||||
|
||||
/* Enable SMI generation:
|
||||
* - on APMC writes (io 0xb2)
|
||||
* - on writes to SLP_EN (sleep states)
|
||||
* - on writes to GBL_RLS (bios commands)
|
||||
* No SMIs:
|
||||
* - on TCO events
|
||||
* - on microcontroller writes (io 0x62/0x66)
|
||||
*/
|
||||
enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | EOS);
|
||||
}
|
||||
|
||||
void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
|
||||
{
|
||||
/*
|
||||
* Issue SMI to set the gnvs pointer in SMM.
|
||||
* tcg and smi1 are unused.
|
||||
*
|
||||
* EAX = APM_CNT_GNVS_UPDATE
|
||||
* EBX = gnvs pointer
|
||||
* EDX = APM_CNT
|
||||
*/
|
||||
asm volatile (
|
||||
"outb %%al, %%dx\n\t"
|
||||
: /* ignore result */
|
||||
: "a" (APM_CNT_GNVS_UPDATE),
|
||||
"b" ((uint32_t)gnvs),
|
||||
"d" (APM_CNT)
|
||||
);
|
||||
}
|
572
src/soc/intel/braswell/southcluster.c
Normal file
572
src/soc/intel/braswell/southcluster.c
Normal file
@ -0,0 +1,572 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2008-2009 coresystems GmbH
|
||||
* 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 <arch/io.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <bootstate.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <drivers/uart/uart8250reg.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/spi.h>
|
||||
#include "chip.h"
|
||||
|
||||
static inline void
|
||||
add_mmio_resource(device_t dev, int i, unsigned long addr, unsigned long size)
|
||||
{
|
||||
mmio_resource(dev, i, addr >> 10, size >> 10);
|
||||
}
|
||||
|
||||
static void sc_add_mmio_resources(device_t dev)
|
||||
{
|
||||
add_mmio_resource(dev, 0xfeb, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE);
|
||||
add_mmio_resource(dev, PBASE, PMC_BASE_ADDRESS, PMC_BASE_SIZE);
|
||||
add_mmio_resource(dev, IOBASE, IO_BASE_ADDRESS, IO_BASE_SIZE);
|
||||
add_mmio_resource(dev, IBASE, ILB_BASE_ADDRESS, ILB_BASE_SIZE);
|
||||
add_mmio_resource(dev, SBASE, SPI_BASE_ADDRESS, SPI_BASE_SIZE);
|
||||
add_mmio_resource(dev, MPBASE, MPHY_BASE_ADDRESS, MPHY_BASE_SIZE);
|
||||
add_mmio_resource(dev, PUBASE, PUNIT_BASE_ADDRESS, PUNIT_BASE_SIZE);
|
||||
add_mmio_resource(dev, RCBA, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE);
|
||||
}
|
||||
|
||||
/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
|
||||
#define LPC_DEFAULT_IO_RANGE_LOWER 0
|
||||
#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
|
||||
|
||||
static inline int io_range_in_default(int base, int size)
|
||||
{
|
||||
/* Does it start above the range? */
|
||||
if (base >= LPC_DEFAULT_IO_RANGE_UPPER)
|
||||
return 0;
|
||||
|
||||
/* Is it entirely contained? */
|
||||
if (base >= LPC_DEFAULT_IO_RANGE_LOWER &&
|
||||
(base + size) < LPC_DEFAULT_IO_RANGE_UPPER)
|
||||
return 1;
|
||||
|
||||
/* This will return not in range for partial overlaps. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: this function assumes there is no overlap with the default LPC device's
|
||||
* claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER.
|
||||
*/
|
||||
static void sc_add_io_resource(device_t dev, int base, int size, int index)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
if (io_range_in_default(base, size))
|
||||
return;
|
||||
|
||||
res = new_resource(dev, index);
|
||||
res->base = base;
|
||||
res->size = size;
|
||||
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
}
|
||||
|
||||
static void sc_add_io_resources(device_t dev)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
/* Add the default claimed IO range for the LPC device. */
|
||||
res = new_resource(dev, 0);
|
||||
res->base = LPC_DEFAULT_IO_RANGE_LOWER;
|
||||
res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
|
||||
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
|
||||
/* GPIO */
|
||||
sc_add_io_resource(dev, GPIO_BASE_ADDRESS, 256, GBASE);
|
||||
|
||||
/* ACPI */
|
||||
sc_add_io_resource(dev, ACPI_BASE_ADDRESS, 128, ABASE);
|
||||
}
|
||||
|
||||
static void sc_read_resources(device_t dev)
|
||||
{
|
||||
/* Get the normal PCI resources of this device. */
|
||||
pci_dev_read_resources(dev);
|
||||
|
||||
/* Add non-standard MMIO resources. */
|
||||
sc_add_mmio_resources(dev);
|
||||
|
||||
/* Add IO resources. */
|
||||
sc_add_io_resources(dev);
|
||||
}
|
||||
|
||||
static void sc_rtc_init(void)
|
||||
{
|
||||
uint32_t gen_pmcon1;
|
||||
int rtc_fail;
|
||||
struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
|
||||
|
||||
if (ps != NULL) {
|
||||
gen_pmcon1 = ps->gen_pmcon1;
|
||||
} else {
|
||||
gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1));
|
||||
}
|
||||
|
||||
rtc_fail = !!(gen_pmcon1 & RPS);
|
||||
|
||||
if (rtc_fail) {
|
||||
printk(BIOS_DEBUG, "RTC failure.\n");
|
||||
}
|
||||
|
||||
cmos_init(rtc_fail);
|
||||
}
|
||||
|
||||
/*
|
||||
* The UART hardware loses power while in suspend. Because of this the kernel
|
||||
* can hang because it doesn't re-initialize serial ports it is using for
|
||||
* consoles at resume time. The following function configures the UART
|
||||
* if the hardware is enabled though it may not be the correct baud rate
|
||||
* or configuration. This is definitely a hack, but it helps the kernel
|
||||
* along.
|
||||
*/
|
||||
static void com1_configure_resume(device_t dev)
|
||||
{
|
||||
const uint16_t port = 0x3f8;
|
||||
|
||||
/* Is the UART I/O port enabled? */
|
||||
if (!(pci_read_config32(dev, UART_CONT) & 1))
|
||||
return;
|
||||
|
||||
/* Disable interrupts */
|
||||
outb(0x0, port + UART8250_IER);
|
||||
|
||||
/* Enable FIFOs */
|
||||
outb(UART8250_FCR_FIFO_EN, port + UART8250_FCR);
|
||||
|
||||
/* assert DTR and RTS so the other end is happy */
|
||||
outb(UART8250_MCR_DTR | UART8250_MCR_RTS, port + UART8250_MCR);
|
||||
|
||||
/* DLAB on */
|
||||
outb(UART8250_LCR_DLAB | 3, port + UART8250_LCR);
|
||||
|
||||
/* Set Baud Rate Divisor. 1 ==> 115200 Baud */
|
||||
outb(1, port + UART8250_DLL);
|
||||
outb(0, port + UART8250_DLM);
|
||||
|
||||
/* Set to 3 for 8N1 */
|
||||
outb(3, port + UART8250_LCR);
|
||||
}
|
||||
|
||||
static void sc_init(device_t dev)
|
||||
{
|
||||
int i;
|
||||
u8 *pr_base = (u8 *)(ILB_BASE_ADDRESS + 0x08);
|
||||
u16 *ir_base = (u16 *)ILB_BASE_ADDRESS + 0x20;
|
||||
u32 *gen_pmcon1 = (u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1);
|
||||
u32 *actl = (u32 *)(ILB_BASE_ADDRESS + ACTL);
|
||||
const struct baytrail_irq_route *ir = &global_baytrail_irq_route;
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
|
||||
/* Set up the PIRQ PIC routing based on static config. */
|
||||
for (i = 0; i < NUM_PIRQS; i++) {
|
||||
write8(pr_base + i, ir->pic[i]);
|
||||
}
|
||||
/* Set up the per device PIRQ routing base on static config. */
|
||||
for (i = 0; i < NUM_IR_DEVS; i++) {
|
||||
write16(ir_base + i, ir->pcidev[i]);
|
||||
}
|
||||
|
||||
/* Route SCI to IRQ9 */
|
||||
write32(actl, (read32(actl) & ~SCIS_MASK) | SCIS_IRQ9);
|
||||
|
||||
sc_rtc_init();
|
||||
|
||||
if (config->disable_slp_x_stretch_sus_fail) {
|
||||
printk(BIOS_DEBUG, "Disabling slp_x stretching.\n");
|
||||
write32(gen_pmcon1,
|
||||
read32(gen_pmcon1) | DIS_SLP_X_STRCH_SUS_UP);
|
||||
} else {
|
||||
write32(gen_pmcon1,
|
||||
read32(gen_pmcon1) & ~DIS_SLP_X_STRCH_SUS_UP);
|
||||
}
|
||||
|
||||
if (acpi_is_wakeup_s3())
|
||||
com1_configure_resume(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Common code for the south cluster devices.
|
||||
*/
|
||||
|
||||
/* Set bit in function disable register to hide this device. */
|
||||
static void sc_disable_devfn(device_t dev)
|
||||
{
|
||||
u32 *func_dis = (u32 *)(PMC_BASE_ADDRESS + FUNC_DIS);
|
||||
u32 *func_dis2 = (u32 *)(PMC_BASE_ADDRESS + FUNC_DIS2);
|
||||
uint32_t mask = 0;
|
||||
uint32_t mask2 = 0;
|
||||
|
||||
switch (dev->path.pci.devfn) {
|
||||
case PCI_DEVFN(SDIO_DEV, SDIO_FUNC):
|
||||
mask |= SDIO_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SD_DEV, SD_FUNC):
|
||||
mask |= SD_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SATA_DEV, SATA_FUNC):
|
||||
mask |= SATA_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(XHCI_DEV, XHCI_FUNC):
|
||||
mask |= XHCI_DIS;
|
||||
/* Disable super speed PHY when XHCI is not available. */
|
||||
mask2 |= USH_SS_PHY_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(LPE_DEV, LPE_FUNC):
|
||||
mask |= LPE_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(MMC_DEV, MMC_FUNC):
|
||||
mask |= MMC_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SIO_DMA1_DEV, SIO_DMA1_FUNC):
|
||||
mask |= SIO_DMA1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C1_DEV, I2C1_FUNC):
|
||||
mask |= I2C1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C2_DEV, I2C2_FUNC):
|
||||
mask |= I2C1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C3_DEV, I2C3_FUNC):
|
||||
mask |= I2C3_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C4_DEV, I2C4_FUNC):
|
||||
mask |= I2C4_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C5_DEV, I2C5_FUNC):
|
||||
mask |= I2C5_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C6_DEV, I2C6_FUNC):
|
||||
mask |= I2C6_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(I2C7_DEV, I2C7_FUNC):
|
||||
mask |= I2C7_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(TXE_DEV, TXE_FUNC):
|
||||
mask |= TXE_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(HDA_DEV, HDA_FUNC):
|
||||
mask |= HDA_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT1_DEV, PCIE_PORT1_FUNC):
|
||||
mask |= PCIE_PORT1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT2_DEV, PCIE_PORT2_FUNC):
|
||||
mask |= PCIE_PORT2_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT3_DEV, PCIE_PORT3_FUNC):
|
||||
mask |= PCIE_PORT3_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT4_DEV, PCIE_PORT4_FUNC):
|
||||
mask |= PCIE_PORT4_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(EHCI_DEV, EHCI_FUNC):
|
||||
mask |= EHCI_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SIO_DMA2_DEV, SIO_DMA2_FUNC):
|
||||
mask |= SIO_DMA2_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PWM1_DEV, PWM1_FUNC):
|
||||
mask |= PWM1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(PWM2_DEV, PWM2_FUNC):
|
||||
mask |= PWM2_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(HSUART1_DEV, HSUART1_FUNC):
|
||||
mask |= HSUART1_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(HSUART2_DEV, HSUART2_FUNC):
|
||||
mask |= HSUART2_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SPI_DEV, SPI_FUNC):
|
||||
mask |= SPI_DIS;
|
||||
break;
|
||||
case PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC):
|
||||
mask2 |= SMBUS_DIS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask != 0) {
|
||||
write32(func_dis, read32(func_dis) | mask);
|
||||
/* Ensure posted write hits. */
|
||||
read32(func_dis);
|
||||
}
|
||||
|
||||
if (mask2 != 0) {
|
||||
write32(func_dis2, read32(func_dis2) | mask2);
|
||||
/* Ensure posted write hits. */
|
||||
read32(func_dis2);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_d3hot_bits(device_t dev, int offset)
|
||||
{
|
||||
uint32_t reg8;
|
||||
printk(BIOS_DEBUG, "Power management CAP offset 0x%x.\n", offset);
|
||||
reg8 = pci_read_config8(dev, offset + 4);
|
||||
reg8 |= 0x3;
|
||||
pci_write_config8(dev, offset + 4, reg8);
|
||||
}
|
||||
|
||||
/* Parts of the audio subsystem are powered by the HDA device. Therefore, one
|
||||
* cannot put HDA into D3Hot. Instead perform this workaround to make some of
|
||||
* the audio paths work for LPE audio. */
|
||||
static void hda_work_around(device_t dev)
|
||||
{
|
||||
u32 *gctl = (u32 *)(TEMP_BASE_ADDRESS + 0x8);
|
||||
|
||||
/* Need to set magic register 0x43 to 0xd7 in config space. */
|
||||
pci_write_config8(dev, 0x43, 0xd7);
|
||||
|
||||
/* Need to set bit 0 of GCTL to take the device out of reset. However,
|
||||
* that requires setting up the 64-bit BAR. */
|
||||
pci_write_config32(dev, PCI_BASE_ADDRESS_0, TEMP_BASE_ADDRESS);
|
||||
pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0);
|
||||
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
|
||||
write32(gctl, read32(gctl) | 0x1);
|
||||
pci_write_config8(dev, PCI_COMMAND, 0);
|
||||
pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0);
|
||||
}
|
||||
|
||||
static int place_device_in_d3hot(device_t dev)
|
||||
{
|
||||
unsigned offset;
|
||||
|
||||
/* Parts of the HDA block are used for LPE audio as well.
|
||||
* Therefore assume the HDA will never be put into D3Hot. */
|
||||
if (dev->path.pci.devfn == PCI_DEVFN(HDA_DEV, HDA_FUNC)) {
|
||||
hda_work_around(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = pci_find_capability(dev, PCI_CAP_ID_PM);
|
||||
|
||||
if (offset != 0) {
|
||||
set_d3hot_bits(dev, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For some reason some of the devices don't have the capability
|
||||
* pointer set correctly. Work around this by hard coding the offset. */
|
||||
switch (dev->path.pci.devfn) {
|
||||
case PCI_DEVFN(SDIO_DEV, SDIO_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(SD_DEV, SD_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(MMC_DEV, MMC_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(LPE_DEV, LPE_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(SIO_DMA1_DEV, SIO_DMA1_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C1_DEV, I2C1_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C2_DEV, I2C2_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C3_DEV, I2C3_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C4_DEV, I2C4_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C5_DEV, I2C5_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C6_DEV, I2C6_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(I2C7_DEV, I2C7_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(SIO_DMA2_DEV, SIO_DMA2_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(PWM1_DEV, PWM1_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(PWM2_DEV, PWM2_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(HSUART1_DEV, HSUART1_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(HSUART2_DEV, HSUART2_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(SPI_DEV, SPI_FUNC):
|
||||
offset = 0x80;
|
||||
break;
|
||||
case PCI_DEVFN(SATA_DEV, SATA_FUNC):
|
||||
offset = 0x70;
|
||||
break;
|
||||
case PCI_DEVFN(XHCI_DEV, XHCI_FUNC):
|
||||
offset = 0x70;
|
||||
break;
|
||||
case PCI_DEVFN(EHCI_DEV, EHCI_FUNC):
|
||||
offset = 0x70;
|
||||
break;
|
||||
case PCI_DEVFN(HDA_DEV, HDA_FUNC):
|
||||
offset = 0x50;
|
||||
break;
|
||||
case PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC):
|
||||
offset = 0x50;
|
||||
break;
|
||||
case PCI_DEVFN(TXE_DEV, TXE_FUNC):
|
||||
/* TXE cannot be placed in D3Hot. */
|
||||
return 0;
|
||||
case PCI_DEVFN(PCIE_PORT1_DEV, PCIE_PORT1_FUNC):
|
||||
offset = 0xa0;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT2_DEV, PCIE_PORT2_FUNC):
|
||||
offset = 0xa0;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT3_DEV, PCIE_PORT3_FUNC):
|
||||
offset = 0xa0;
|
||||
break;
|
||||
case PCI_DEVFN(PCIE_PORT4_DEV, PCIE_PORT4_FUNC):
|
||||
offset = 0xa0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset != 0) {
|
||||
set_d3hot_bits(dev, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Common PCI device function disable. */
|
||||
void southcluster_enable_dev(device_t dev)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
||||
if (!dev->enabled) {
|
||||
int slot = PCI_SLOT(dev->path.pci.devfn);
|
||||
int func = PCI_FUNC(dev->path.pci.devfn);
|
||||
printk(BIOS_DEBUG, "%s: Disabling device: %02x.%01x\n",
|
||||
dev_path(dev), slot, func);
|
||||
|
||||
/* Ensure memory, io, and bus master are all disabled */
|
||||
reg32 = pci_read_config32(dev, PCI_COMMAND);
|
||||
reg32 &= ~(PCI_COMMAND_MASTER |
|
||||
PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
|
||||
pci_write_config32(dev, PCI_COMMAND, reg32);
|
||||
|
||||
/* Place device in D3Hot */
|
||||
if (place_device_in_d3hot(dev) < 0) {
|
||||
printk(BIOS_WARNING,
|
||||
"Could not place %02x.%01x into D3Hot. "
|
||||
"Keeping device visible.\n", slot, func);
|
||||
return;
|
||||
}
|
||||
/* Disable this device if possible */
|
||||
sc_disable_devfn(dev);
|
||||
} else {
|
||||
/* Enable SERR */
|
||||
reg32 = pci_read_config32(dev, PCI_COMMAND);
|
||||
reg32 |= PCI_COMMAND_SERR;
|
||||
pci_write_config32(dev, PCI_COMMAND, reg32);
|
||||
}
|
||||
}
|
||||
|
||||
static struct device_operations device_ops = {
|
||||
.read_resources = sc_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = NULL,
|
||||
.init = sc_init,
|
||||
.enable = southcluster_enable_dev,
|
||||
.scan_bus = scan_static_bus,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver southcluster __pci_driver = {
|
||||
.ops = &device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = LPC_DEVID,
|
||||
};
|
||||
|
||||
int __attribute__((weak)) mainboard_get_spi_config(struct spi_config *cfg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void finalize_chipset(void *unused)
|
||||
{
|
||||
u32 *bcr = (u32 *)(SPI_BASE_ADDRESS + BCR);
|
||||
u32 *gcs = (u32 *)(RCBA_BASE_ADDRESS + GCS);
|
||||
u32 *gen_pmcon2 = (u32 *)(PMC_BASE_ADDRESS + GEN_PMCON2);
|
||||
u32 *etr = (u32 *)(PMC_BASE_ADDRESS + ETR);
|
||||
u8 *spi = (u8 *)SPI_BASE_ADDRESS;
|
||||
struct spi_config cfg;
|
||||
|
||||
/* Set the lock enable on the BIOS control register. */
|
||||
write32(bcr, read32(bcr) | BCR_LE);
|
||||
|
||||
/* Set BIOS lock down bit controlling boot block size and swapping. */
|
||||
write32(gcs, read32(gcs) | BILD);
|
||||
|
||||
/* Lock sleep stretching policy and set SMI lock. */
|
||||
write32(gen_pmcon2, read32(gen_pmcon2) | SLPSX_STR_POL_LOCK | SMI_LOCK);
|
||||
|
||||
/* Set the CF9 lock. */
|
||||
write32(etr, read32(etr) | CF9LOCK);
|
||||
|
||||
if (mainboard_get_spi_config(&cfg) < 0) {
|
||||
printk(BIOS_DEBUG, "No SPI lockdown configuration.\n");
|
||||
} else {
|
||||
write16(spi + PREOP, cfg.preop);
|
||||
write16(spi + OPTYPE, cfg.optype);
|
||||
write32(spi + OPMENU0, cfg.opmenu[0]);
|
||||
write32(spi + OPMENU1, cfg.opmenu[1]);
|
||||
write16(spi + HSFSTS, read16(spi + HSFSTS) | FLOCKDN);
|
||||
write32(spi + UVSCC, cfg.uvscc);
|
||||
write32(spi + LVSCC, cfg.lvscc | VCL);
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "Finalizing SMM.\n");
|
||||
outb(APM_CNT_FINALIZE, APM_CNT);
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL);
|
||||
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, finalize_chipset, NULL);
|
647
src/soc/intel/braswell/spi.c
Normal file
647
src/soc/intel/braswell/spi.c
Normal file
@ -0,0 +1,647 @@
|
||||
/*
|
||||
* 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 <bootstate.h>
|
||||
#include <delay.h>
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <spi_flash.h>
|
||||
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/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(addr, b);
|
||||
printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n",
|
||||
b, ((unsigned) addr & 0xffff) - 0xf020);
|
||||
}
|
||||
|
||||
static void writew_(u16 b, const void *addr)
|
||||
{
|
||||
write16(addr, b);
|
||||
printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n",
|
||||
b, ((unsigned) addr & 0xffff) - 0xf020);
|
||||
}
|
||||
|
||||
static void writel_(u32 b, const void *addr)
|
||||
{
|
||||
write32(addr, b);
|
||||
printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n",
|
||||
b, ((unsigned) addr & 0xffff) - 0xf020);
|
||||
}
|
||||
|
||||
#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */
|
||||
|
||||
#define readb_(a) read8(a)
|
||||
#define readw_(a) read16(a)
|
||||
#define readl_(a) read32(a)
|
||||
#define writeb_(val, addr) write8(addr, val)
|
||||
#define writew_(val, addr) write16(addr, val)
|
||||
#define writel_(val, addr) write32(addr, val)
|
||||
|
||||
#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */
|
||||
|
||||
static void write_reg(const void *value, void *dest, uint32_t size)
|
||||
{
|
||||
const uint8_t *bvalue = value;
|
||||
uint8_t *bdest = dest;
|
||||
|
||||
while (size >= 4) {
|
||||
writel_(*(const uint32_t *)bvalue, bdest);
|
||||
bdest += 4; bvalue += 4; size -= 4;
|
||||
}
|
||||
while (size) {
|
||||
writeb_(*bvalue, bdest);
|
||||
bdest++; bvalue++; size--;
|
||||
}
|
||||
}
|
||||
|
||||
static void read_reg(const void *src, void *value, uint32_t size)
|
||||
{
|
||||
const uint8_t *bsrc = src;
|
||||
uint8_t *bvalue = value;
|
||||
|
||||
while (size >= 4) {
|
||||
*(uint32_t *)bvalue = readl_(bsrc);
|
||||
bsrc += 4; bvalue += 4; size -= 4;
|
||||
}
|
||||
while (size) {
|
||||
*bvalue = readb_(bsrc);
|
||||
bsrc++; bvalue++; size--;
|
||||
}
|
||||
}
|
||||
|
||||
static void ich_set_bbar(uint32_t minaddr)
|
||||
{
|
||||
const uint32_t bbar_mask = 0x00ffff00;
|
||||
uint32_t ichspi_bbar;
|
||||
|
||||
minaddr &= bbar_mask;
|
||||
ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask;
|
||||
ichspi_bbar |= minaddr;
|
||||
writel_(ichspi_bbar, cntlr.bbar);
|
||||
}
|
||||
|
||||
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
|
||||
{
|
||||
ich_spi_slave *slave = malloc(sizeof(*slave));
|
||||
|
||||
if (!slave) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(slave, 0, sizeof(*slave));
|
||||
|
||||
slave->bus = bus;
|
||||
slave->cs = cs;
|
||||
return slave;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#ifndef __SMM__
|
||||
static void spi_init_cb(void *unused)
|
||||
{
|
||||
spi_init();
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL);
|
||||
#endif
|
||||
|
||||
int spi_claim_bus(struct spi_slave *slave)
|
||||
{
|
||||
/* Handled by ICH automatically. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_release_bus(struct spi_slave *slave)
|
||||
{
|
||||
/* Handled by ICH automatically. */
|
||||
}
|
||||
|
||||
typedef struct spi_transaction {
|
||||
const uint8_t *out;
|
||||
uint32_t bytesout;
|
||||
uint8_t *in;
|
||||
uint32_t bytesin;
|
||||
uint8_t type;
|
||||
uint8_t opcode;
|
||||
uint32_t offset;
|
||||
} spi_transaction;
|
||||
|
||||
static inline void spi_use_out(spi_transaction *trans, unsigned bytes)
|
||||
{
|
||||
trans->out += bytes;
|
||||
trans->bytesout -= bytes;
|
||||
}
|
||||
|
||||
static inline void spi_use_in(spi_transaction *trans, unsigned bytes)
|
||||
{
|
||||
trans->in += bytes;
|
||||
trans->bytesin -= bytes;
|
||||
}
|
||||
|
||||
static void spi_setup_type(spi_transaction *trans)
|
||||
{
|
||||
trans->type = 0xFF;
|
||||
|
||||
/* Try to guess spi type from read/write sizes. */
|
||||
if (trans->bytesin == 0) {
|
||||
if (trans->bytesout > 4)
|
||||
/*
|
||||
* If bytesin = 0 and bytesout > 4, we presume this is
|
||||
* a write data operation, which is accompanied by an
|
||||
* address.
|
||||
*/
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||
else
|
||||
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->bytesout == 1) { /* and bytesin is > 0 */
|
||||
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->bytesout == 4) { /* and bytesin is > 0 */
|
||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||
}
|
||||
|
||||
/* Fast read command is called with 5 bytes instead of 4 */
|
||||
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
|
||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||
--trans->bytesout;
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_setup_opcode(spi_transaction *trans)
|
||||
{
|
||||
uint16_t optypes;
|
||||
uint8_t opmenu[cntlr.menubytes];
|
||||
|
||||
trans->opcode = trans->out[0];
|
||||
spi_use_out(trans, 1);
|
||||
if (!ichspi_lock) {
|
||||
/* The lock is off, so just use index 0. */
|
||||
writeb_(trans->opcode, cntlr.opmenu);
|
||||
optypes = readw_(cntlr.optype);
|
||||
optypes = (optypes & 0xfffc) | (trans->type & 0x3);
|
||||
writew_(optypes, cntlr.optype);
|
||||
return 0;
|
||||
} else {
|
||||
/* The lock is on. See if what we need is on the menu. */
|
||||
uint8_t optype;
|
||||
uint16_t opcode_index;
|
||||
|
||||
/* Write Enable is handled as atomic prefix */
|
||||
if (trans->opcode == SPI_OPCODE_WREN)
|
||||
return 0;
|
||||
|
||||
read_reg(cntlr.opmenu, opmenu, sizeof(opmenu));
|
||||
for (opcode_index = 0; opcode_index < cntlr.menubytes;
|
||||
opcode_index++) {
|
||||
if (opmenu[opcode_index] == trans->opcode)
|
||||
break;
|
||||
}
|
||||
|
||||
if (opcode_index == cntlr.menubytes) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n",
|
||||
trans->opcode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
optypes = readw_(cntlr.optype);
|
||||
optype = (optypes >> (opcode_index * 2)) & 0x3;
|
||||
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
|
||||
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
|
||||
trans->bytesout >= 3) {
|
||||
/* We guessed wrong earlier. Fix it up. */
|
||||
trans->type = optype;
|
||||
}
|
||||
if (optype != trans->type) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n",
|
||||
optype);
|
||||
return -1;
|
||||
}
|
||||
return opcode_index;
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_setup_offset(spi_transaction *trans)
|
||||
{
|
||||
/* Separate the SPI address and data. */
|
||||
switch (trans->type) {
|
||||
case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
|
||||
case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
|
||||
return 0;
|
||||
case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
|
||||
case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
|
||||
trans->offset = ((uint32_t)trans->out[0] << 16) |
|
||||
((uint32_t)trans->out[1] << 8) |
|
||||
((uint32_t)trans->out[2] << 0);
|
||||
spi_use_out(trans, 3);
|
||||
return 1;
|
||||
default:
|
||||
printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set
|
||||
* below is True) or 0. In case the wait was for the bit(s) to set - write
|
||||
* those bits back, which would cause resetting them.
|
||||
*
|
||||
* Return the last read status value on success or -1 on failure.
|
||||
*/
|
||||
static int ich_status_poll(u16 bitmask, int wait_til_set)
|
||||
{
|
||||
int timeout = 40000; /* This will result in 400 ms */
|
||||
u16 status = 0;
|
||||
|
||||
while (timeout--) {
|
||||
status = readw_(cntlr.status);
|
||||
if (wait_til_set ^ ((status & bitmask) == 0)) {
|
||||
if (wait_til_set)
|
||||
writew_((status & bitmask), cntlr.status);
|
||||
return status;
|
||||
}
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n",
|
||||
status, bitmask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
|
||||
{
|
||||
return min(cntlr.databytes, buf_len);
|
||||
}
|
||||
|
||||
int spi_xfer(struct spi_slave *slave, const void *dout,
|
||||
unsigned int bytesout, void *din, unsigned int bytesin)
|
||||
{
|
||||
uint16_t control;
|
||||
int16_t opcode_index;
|
||||
int with_address;
|
||||
int status;
|
||||
|
||||
spi_transaction trans = {
|
||||
dout, bytesout,
|
||||
din, bytesin,
|
||||
0xff, 0xff, 0
|
||||
};
|
||||
|
||||
/* There has to always at least be an opcode. */
|
||||
if (!bytesout || !dout) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n");
|
||||
return -1;
|
||||
}
|
||||
/* Make sure if we read something we have a place to put it. */
|
||||
if (bytesin != 0 && !din) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ich_status_poll(SPIS_SCIP, 0) == -1)
|
||||
return -1;
|
||||
|
||||
writew_(SPIS_CDS | SPIS_FCERR, cntlr.status);
|
||||
|
||||
spi_setup_type(&trans);
|
||||
if ((opcode_index = spi_setup_opcode(&trans)) < 0)
|
||||
return -1;
|
||||
if ((with_address = spi_setup_offset(&trans)) < 0)
|
||||
return -1;
|
||||
|
||||
if (trans.opcode == SPI_OPCODE_WREN) {
|
||||
/*
|
||||
* Treat Write Enable as Atomic Pre-Op if possible
|
||||
* in order to prevent the Management Engine from
|
||||
* issuing a transaction between WREN and DATA.
|
||||
*/
|
||||
if (!ichspi_lock)
|
||||
writew_(trans.opcode, cntlr.preop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Preset control fields */
|
||||
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
|
||||
|
||||
/* Issue atomic preop cycle if needed */
|
||||
if (readw_(cntlr.preop))
|
||||
control |= SPIC_ACS;
|
||||
|
||||
if (!trans.bytesout && !trans.bytesin) {
|
||||
/* SPI addresses are 24 bit only */
|
||||
if (with_address)
|
||||
writel_(trans.offset & 0x00FFFFFF, cntlr.addr);
|
||||
|
||||
/*
|
||||
* This is a 'no data' command (like Write Enable), its
|
||||
* bytesout size was 1, decremented to zero while executing
|
||||
* spi_setup_opcode() above. Tell the chip to send the
|
||||
* command.
|
||||
*/
|
||||
writew_(control, cntlr.control);
|
||||
|
||||
/* wait for the result */
|
||||
status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
|
||||
if (status == -1)
|
||||
return -1;
|
||||
|
||||
if (status & SPIS_FCERR) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this is a write command attempting to transfer more bytes
|
||||
* than the controller can handle. Iterations for writes are not
|
||||
* supported here because each SPI write command needs to be preceded
|
||||
* and followed by other SPI commands, and this sequence is controlled
|
||||
* by the SPI chip driver.
|
||||
*/
|
||||
if (trans.bytesout > cntlr.databytes) {
|
||||
printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use"
|
||||
" spi_crop_chunk()?\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;
|
||||
}
|
35
src/soc/intel/braswell/stage_cache.c
Normal file
35
src/soc/intel/braswell/stage_cache.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 <cbmem.h>
|
||||
#include <stage_cache.h>
|
||||
#include <soc/smm.h>
|
||||
|
||||
void stage_cache_external_region(void **base, size_t *size)
|
||||
{
|
||||
char *smm_base;
|
||||
/* 1MiB cache size */
|
||||
const long cache_size = CONFIG_SMM_RESERVED_SIZE;
|
||||
|
||||
/* Ramstage cache lives in TSEG region which is the definition of
|
||||
* cbmem_top(). */
|
||||
smm_base = cbmem_top();
|
||||
*size = cache_size;
|
||||
*base = &smm_base[smm_region_size() - cache_size];
|
||||
}
|
84
src/soc/intel/braswell/tsc_freq.c
Normal file
84
src/soc/intel/braswell/tsc_freq.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 <soc/msr.h>
|
||||
|
||||
unsigned bus_freq_khz(void)
|
||||
{
|
||||
msr_t clk_info = rdmsr(MSR_BSEL_CR_OVERCLOCK_CONTROL);
|
||||
switch (clk_info.lo & 0x3) {
|
||||
case 0:
|
||||
return 83333;
|
||||
case 1:
|
||||
return 100000;
|
||||
case 2:
|
||||
return 133333;
|
||||
case 3:
|
||||
return 116666;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long tsc_freq_mhz(void)
|
||||
{
|
||||
msr_t platform_info;
|
||||
unsigned bclk_khz = bus_freq_khz();
|
||||
|
||||
if (!bclk_khz)
|
||||
return 0;
|
||||
|
||||
platform_info = rdmsr(MSR_PLATFORM_INFO);
|
||||
return (bclk_khz * ((platform_info.lo >> 8) & 0xff)) / 1000;
|
||||
}
|
||||
|
||||
#if !defined(__SMM__)
|
||||
#if !defined(__PRE_RAM__)
|
||||
#include <soc/ramstage.h>
|
||||
#else
|
||||
#include <soc/romstage.h>
|
||||
#endif
|
||||
|
||||
void set_max_freq(void)
|
||||
{
|
||||
msr_t perf_ctl;
|
||||
msr_t msr;
|
||||
|
||||
/* Enable speed step. */
|
||||
msr = rdmsr(MSR_IA32_MISC_ENABLES);
|
||||
msr.lo |= (1 << 16);
|
||||
wrmsr(MSR_IA32_MISC_ENABLES, msr);
|
||||
|
||||
/* Set guaranteed ratio [21:16] from IACORE_RATIOS to bits [15:8] of
|
||||
* the PERF_CTL. */
|
||||
msr = rdmsr(MSR_IACORE_RATIOS);
|
||||
perf_ctl.lo = (msr.lo & 0x3f0000) >> 8;
|
||||
/* Set guaranteed vid [21:16] from IACORE_VIDS to bits [7:0] of
|
||||
* the PERF_CTL. */
|
||||
msr = rdmsr(MSR_IACORE_VIDS);
|
||||
perf_ctl.lo |= (msr.lo & 0x7f0000) >> 16;
|
||||
perf_ctl.hi = 0;
|
||||
|
||||
wrmsr(MSR_IA32_PERF_CTL, perf_ctl);
|
||||
}
|
||||
|
||||
#endif /* __SMM__ */
|
259
src/soc/intel/braswell/xhci.c
Normal file
259
src/soc/intel/braswell/xhci.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 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/acpi.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <stdint.h>
|
||||
#include <reg_script.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/iosf.h>
|
||||
#include <soc/lpc.h>
|
||||
#include <soc/pattrs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/xhci.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
struct reg_script usb3_phy_script[] = {
|
||||
/* USB3PHYInit() */
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_CDN_PLL_CONTROL,
|
||||
~0x00700000, 0x00500000),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_CDN_VCO_START_CAL_POINT,
|
||||
~0x001f0000, 0x000A0000),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_CCDRLF,
|
||||
~0x0000000f, 0x0000000b),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_PEAKING_AMP_CONFIG_DIAG,
|
||||
~0x000000f0, 0x000000f0),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_OFFSET_COR_CONFIG_DIAG,
|
||||
~0x000001c0, 0x00000000),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_VGA_GAIN_CONFIG_DIAG,
|
||||
~0x00000070, 0x00000020),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_REE_DAC_CONTROL,
|
||||
~0x00000002, 0x00000002),
|
||||
REG_IOSF_RMW(IOSF_PORT_USHPHY, USHPHY_CDN_U1_POWER_STATE_DEF,
|
||||
~0x00000000, 0x00040000),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
const struct reg_script xhci_init_script[] = {
|
||||
/* CommonXhciHcInit() */
|
||||
/* BAR + 0x0c[31:16] = 0x0200 */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x000c, 0x0000ffff, 0x02000000),
|
||||
/* BAR + 0x0c[7:0] = 0x0a */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x000c, 0xffffff00, 0x0000000a),
|
||||
/* BAR + 0x8094[23,21,14]=111b */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8094, 0x00a04000),
|
||||
/* BAR + 0x8110[20,11,8,2]=1100b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8110, ~0x00000104, 0x00100800),
|
||||
/* BAR + 0x8144[8,7,6]=111b */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8144, 0x000001c0),
|
||||
/* BAR + 0x8154[21,13,3]=010b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8154, ~0x00200008, 0x80002000),
|
||||
/* BAR + 0x816c[19:0]=1110x100000000111100b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x816c, 0xfff08000, 0x000e0030),
|
||||
/* BAR + 0x8188[26,24]=11b */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8188, 0x05000000),
|
||||
/* BAR + 0x8174=0x1000c0a*/
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8174, 0xfe000000, 0x01000c0a),
|
||||
/* BAR + 0x854c[29]=0b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x854c, ~0x20000000, 0),
|
||||
/* BAR + 0x8178[12:0]=0b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8178, ~0xffffe000, 0),
|
||||
/* BAR + 0x8164[7:0]=0xff */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8164, 0x000000ff),
|
||||
/* BAR + 0x0010[10,9,5]=110b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x0010, ~0x00000020, 0x00000600),
|
||||
/* BAR + 0x8058[20,16,8]=110b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8058, ~0x00000100, 0x00110000),
|
||||
/* BAR + 0x8060[25]=1b */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8060, 0x02000000),
|
||||
/* BAR + 0x80f0[20]=0b */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80f0, ~0x00100000, 0),
|
||||
/* BAR + 0x8008[19]=1b (to enable LPM) */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x8008, 0x00080000),
|
||||
/* BAR + 0x80fc[25]=1b */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, 0x80fc, 0x02000000),
|
||||
/* 0x40/0x44 are written as bytes to avoid touching bit31 */
|
||||
/* D20:F0:40[21,20,18,10,9,8]=111001b (don't write byte3) */
|
||||
REG_PCI_RMW8(0x41, ~0x06, 0x01),
|
||||
/* Except [21,20,19,18]=0001b USB wake W/A is disable IIL1E */
|
||||
REG_PCI_RMW8(0x42, 0x3c, 0x04),
|
||||
/* D20:F0:44[19:14,10,9,7,3:0]=1 (don't write byte3) */
|
||||
REG_PCI_RMW8(0x44, 0x00, 0x8f),
|
||||
REG_PCI_RMW8(0x45, ~0xcf, 0xc6),
|
||||
REG_PCI_RMW8(0x46, ~0x0f, 0x0f),
|
||||
/* BAR + 0x8140 = 0xff00f03c */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x8140, 0, 0xff00f03c),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
const struct reg_script xhci_init_boot_script[] = {
|
||||
/* Setup USB3 phy */
|
||||
REG_SCRIPT_NEXT(usb3_phy_script),
|
||||
/* Initialize host controller */
|
||||
REG_SCRIPT_NEXT(xhci_init_script),
|
||||
/* BAR + 0x80e0[16,9,6]=001b, toggle bit 24=1 */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x00010200, 0x01000040),
|
||||
/* BAR + 0x80e0 toggle bit 24=0 */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x01000000, 0),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
const struct reg_script xhci_init_resume_script[] = {
|
||||
/* Setup USB3 phy */
|
||||
REG_SCRIPT_NEXT(usb3_phy_script),
|
||||
/* Initialize host controller */
|
||||
REG_SCRIPT_NEXT(xhci_init_script),
|
||||
/* BAR + 0x80e0[16,9,6]=001b, leave bit 24=0 to prevent HC reset */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, 0x80e0, ~0x01010200, 0x00000040),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
const struct reg_script xhci_clock_gating_script[] = {
|
||||
/* ConfigureXhciClockGating() */
|
||||
/* D20:F0:40[21:19,18,10:8]=000,1,001 (don't write byte 3) */
|
||||
REG_PCI_RMW16(0x40, ~0x0600, 0x0100),
|
||||
REG_PCI_RMW8(0x42, ~0x38, 0x04),
|
||||
/* D20:F0:44[5:3]=001b */
|
||||
REG_PCI_RMW16(0x44, ~0x0030, 0x0008),
|
||||
/* D20:F0:A0[19:18]=01b */
|
||||
REG_PCI_RMW32(0xa0, ~0x00080000, 0x00040000),
|
||||
/* D20:F0:A4[15:0]=0x00 */
|
||||
REG_PCI_WRITE16(0xa4, 0x0000),
|
||||
/* D20:F0:B0[21:17,14:13]=0000000b */
|
||||
REG_PCI_RMW32(0xb0, ~0x00376000, 0x00000000),
|
||||
/* D20:F0:50[31:0]=0x0bce6e5f */
|
||||
REG_PCI_WRITE32(0x50, 0x0bce6e5f),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
/* Warm Reset a USB3 port */
|
||||
static void xhci_reset_port_usb3(device_t dev, int port)
|
||||
{
|
||||
struct reg_script reset_port_usb3_script[] = {
|
||||
/* Issue Warm Port Rest to the port */
|
||||
REG_RES_OR32(PCI_BASE_ADDRESS_0, XHCI_USB3_PORTSC(port),
|
||||
XHCI_USB3_PORTSC_WPR),
|
||||
/* Wait up to 100ms for it to complete */
|
||||
REG_RES_POLL32(PCI_BASE_ADDRESS_0, XHCI_USB3_PORTSC(port),
|
||||
XHCI_USB3_PORTSC_WRC, XHCI_USB3_PORTSC_WRC,
|
||||
XHCI_RESET_TIMEOUT),
|
||||
/* Clear change status bits, do not set PED */
|
||||
REG_RES_RMW32(PCI_BASE_ADDRESS_0, XHCI_USB3_PORTSC(port),
|
||||
~XHCI_USB3_PORTSC_PED, XHCI_USB3_PORTSC_CHST),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
reg_script_run_on_dev(dev, reset_port_usb3_script);
|
||||
}
|
||||
|
||||
/* Prepare ports to be routed to EHCI or XHCI */
|
||||
static void xhci_route_all(device_t dev)
|
||||
{
|
||||
static const struct reg_script xhci_route_all_script[] = {
|
||||
/* USB3 SuperSpeed Enable */
|
||||
REG_PCI_WRITE32(XHCI_USB3PR, BYTM_USB3_PORT_MAP),
|
||||
/* USB2 Port Route to XHCI */
|
||||
REG_PCI_WRITE32(XHCI_USB2PR, BYTM_USB2_PORT_MAP),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
u32 port_disabled;
|
||||
int port;
|
||||
|
||||
printk(BIOS_INFO, "USB: Route ports to XHCI controller\n");
|
||||
|
||||
/* Route ports to XHCI controller */
|
||||
reg_script_run_on_dev(dev, xhci_route_all_script);
|
||||
|
||||
if (acpi_is_wakeup_s3())
|
||||
return;
|
||||
|
||||
/* Reset enabled USB3 ports */
|
||||
port_disabled = pci_read_config32(dev, XHCI_USB3PDO);
|
||||
for (port = 0; port < BYTM_USB3_PORT_COUNT; port++) {
|
||||
if (port_disabled & (1 << port))
|
||||
continue;
|
||||
xhci_reset_port_usb3(dev, port);
|
||||
}
|
||||
}
|
||||
|
||||
static void xhci_init(device_t dev)
|
||||
{
|
||||
struct soc_intel_baytrail_config *config = dev->chip_info;
|
||||
struct reg_script xhci_hc_init[] = {
|
||||
/* Initialize clock gating */
|
||||
REG_SCRIPT_NEXT(xhci_clock_gating_script),
|
||||
/* Finalize XHCC1 and XHCC2 */
|
||||
REG_PCI_RMW32(0x44, ~0x00000000, 0x83c00000),
|
||||
REG_PCI_RMW32(0x40, ~0x00800000, 0x80000000),
|
||||
/* Set USB2 Port Routing Mask */
|
||||
REG_PCI_WRITE32(XHCI_USB2PRM, BYTM_USB2_PORT_MAP),
|
||||
/* Set USB3 Port Routing Mask */
|
||||
REG_PCI_WRITE32(XHCI_USB3PRM, BYTM_USB3_PORT_MAP),
|
||||
/*
|
||||
* Disable ports if requested
|
||||
*/
|
||||
/* Open per-port disable control override */
|
||||
REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~0, UPRWC_WR_EN),
|
||||
REG_PCI_WRITE32(XHCI_USB2PDO, config->usb2_port_disable_mask),
|
||||
REG_PCI_WRITE32(XHCI_USB3PDO, config->usb3_port_disable_mask),
|
||||
/* Close per-port disable control override */
|
||||
REG_IO_RMW16(ACPI_BASE_ADDRESS + UPRWC, ~UPRWC_WR_EN, 0),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
/* Initialize XHCI controller for boot or resume path */
|
||||
if (acpi_is_wakeup_s3())
|
||||
reg_script_run_on_dev(dev, xhci_init_resume_script);
|
||||
else
|
||||
reg_script_run_on_dev(dev, xhci_init_boot_script);
|
||||
|
||||
/* C0 steppings change iCLK/USB PLL VCO settings from 5 to 7 */
|
||||
if (pattrs_get()->stepping == STEP_C0) {
|
||||
uint32_t reg = iosf_ushphy_read(USHPHY_CDN_PLL_CONTROL);
|
||||
reg |= 0x00700000;
|
||||
iosf_ushphy_write(USHPHY_CDN_PLL_CONTROL, reg);
|
||||
}
|
||||
|
||||
/* Finalize Initialization */
|
||||
reg_script_run_on_dev(dev, xhci_hc_init);
|
||||
|
||||
/* Route all ports to XHCI if requested */
|
||||
if (config->usb_route_to_xhci)
|
||||
xhci_route_all(dev);
|
||||
}
|
||||
|
||||
static struct device_operations xhci_device_ops = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = xhci_init,
|
||||
.ops_pci = &soc_pci_ops,
|
||||
};
|
||||
|
||||
static const struct pci_driver baytrail_xhci __pci_driver = {
|
||||
.ops = &xhci_device_ops,
|
||||
.vendor = PCI_VENDOR_ID_INTEL,
|
||||
.device = XHCI_DEVID
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user