coreboot-kgpe-d16/src/soc/intel/skylake/chip_fsp20.c

312 lines
10 KiB
C
Raw Normal View History

/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016-2017 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <chip.h>
#include <bootmode.h>
#include <bootstate.h>
#include <device/pci.h>
#include <fsp/api.h>
#include <arch/acpi.h>
#include <chip.h>
#include <bootstate.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <fsp/api.h>
#include <fsp/util.h>
#include <romstage_handoff.h>
#include <soc/acpi.h>
#include <soc/intel/common/vbt.h>
#include <soc/interrupt.h>
#include <soc/irq.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
#include <string.h>
void soc_init_pre_device(void *chip_info)
{
/* Perform silicon specific init. */
fsp_silicon_init(romstage_handoff_is_resume());
}
void soc_fsp_load(void)
{
fsps_load(romstage_handoff_is_resume());
}
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,
.scan_bus = &pci_domain_scan_bus,
.ops_pci_bus = &pci_bus_default_ops,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &soc_acpi_name,
#endif
};
static struct device_operations cpu_bus_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.init = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_fill_ssdt_generator = generate_cpu_entries,
#endif
};
static void soc_enable(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 PCH device enable */
if (PCI_SLOT(dev->path.pci.devfn) > SA_DEV_SLOT_IGD &&
(dev->ops == NULL || dev->ops->enable == NULL)) {
pch_enable_dev(dev);
}
}
}
struct chip_operations soc_intel_skylake_ops = {
CHIP_NAME("Intel 6th Gen")
.enable_dev = &soc_enable,
.init = &soc_init_pre_device,
};
/* UPD parameters to be initialized before SiliconInit */
void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
{
FSP_S_CONFIG *params = &supd->FspsConfig;
FSP_S_TEST_CONFIG *tconfig = &supd->FspsTestConfig;
static struct soc_intel_skylake_config *config;
uintptr_t vbt_data = 0;
int i;
int is_s3_wakeup = acpi_is_wakeup_s3();
struct device *dev = SA_DEV_ROOT;
if (!dev || !dev->chip_info) {
printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n");
return;
}
config = dev->chip_info;
mainboard_silicon_init_params(params);
/* Load VBT */
if (is_s3_wakeup) {
printk(BIOS_DEBUG, "S3 resume do not pass VBT to GOP\n");
} else if (display_init_required() && IS_ENABLED(CONFIG_RUN_FSP_GOP)) {
/* Get VBT data */
vbt_data = (uintptr_t)locate_vbt();
if (vbt_data)
printk(BIOS_DEBUG, "Passing VBT to GOP\n");
else
printk(BIOS_DEBUG, "VBT not found!\n");
} else {
printk(BIOS_DEBUG, "Not passing VBT to GOP\n");
}
params->GraphicsConfigPtr = (u32) vbt_data;
for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
params->PortUsb20Enable[i] =
config->usb2_ports[i].enable;
params->Usb2OverCurrentPin[i] =
config->usb2_ports[i].ocpin;
params->Usb2AfePetxiset[i] =
config->usb2_ports[i].pre_emp_bias;
params->Usb2AfeTxiset[i] =
config->usb2_ports[i].tx_bias;
params->Usb2AfePredeemp[i] =
config->usb2_ports[i].tx_emp_enable;
params->Usb2AfePehalfbit[i] =
config->usb2_ports[i].pre_emp_bit;
}
for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
if (config->usb3_ports[i].tx_de_emp) {
params->Usb3HsioTxDeEmphEnable[i] = 1;
params->Usb3HsioTxDeEmph[i] =
config->usb3_ports[i].tx_de_emp;
}
if (config->usb3_ports[i].tx_downscale_amp) {
params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
params->Usb3HsioTxDownscaleAmp[i] =
config->usb3_ports[i].tx_downscale_amp;
}
}
memcpy(params->SataPortsEnable, config->SataPortsEnable,
sizeof(params->SataPortsEnable));
memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp,
sizeof(params->SataPortsDevSlp));
memcpy(params->PcieRpClkReqSupport, config->PcieRpClkReqSupport,
sizeof(params->PcieRpClkReqSupport));
memcpy(params->PcieRpClkReqNumber, config->PcieRpClkReqNumber,
sizeof(params->PcieRpClkReqNumber));
memcpy(params->PcieRpAdvancedErrorReporting,
config->PcieRpAdvancedErrorReporting,
sizeof(params->PcieRpAdvancedErrorReporting));
soc/intel/skylake: Add config for enabling LTR for PCIe Root port There are a lot errors reported by AER driver for root port 0. The erors are being caused by an unsupported request from the device to the upstream port. Enabling LTR on the root port stops these errors, it is because LTR is enabled on the device side but not on the root port and hence root port was logging the LTR messages from the device as unsupported. The PCIe base spec (v3.1a) section 6.18 also states that: LTR support is discovered and enabled through reporting and control registers described in Chapter 7. Software must not enable LTR in an Endpoint unless the Root Complex and all intermediate Switches indicate support for LTR. Note that it is not required that all Endpoints support LTR to permit enabling LTR in those Endpoints that do support it. When enabling the LTR mechanism in a hierarchy, devices closest to the Root Port must be enabled first. If an LTR Message is received at a Downstream Port that does not support LTR or if LTR is not enabled, the Message must be treated as an Unsupported Request. FSP has a UPD for enabling/disabling LTR on root port, use the same for configuring LTR on PCIe root ports. BUG=b:65570878 TEST=After enbaling LTR on port 0 on the MB devicetree, No errors reported by AER driver for root port 0. Change-Id: Ica97faa78fcd991dad63ae54d2ada82194b4202a Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Reviewed-on: https://review.coreboot.org/21547 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
2017-09-15 22:24:20 +02:00
memcpy(params->PcieRpLtrEnable, config->PcieRpLtrEnable,
sizeof(params->PcieRpLtrEnable));
/* disable Legacy PME */
memset(params->PcieRpPmSci, 0, sizeof(params->PcieRpPmSci));
memcpy(params->SerialIoDevMode, config->SerialIoDevMode,
sizeof(params->SerialIoDevMode));
params->PchCio2Enable = config->Cio2Enable;
params->SaImguEnable = config->SaImguEnable;
params->Heci3Enabled = config->Heci3Enabled;
params->LogoPtr = config->LogoPtr;
params->LogoSize = config->LogoSize;
params->CpuConfig.Bits.VmxEnable = config->VmxEnable;
params->PchPmWoWlanEnable = config->PchPmWoWlanEnable;
params->PchPmWoWlanDeepSxEnable = config->PchPmWoWlanDeepSxEnable;
params->PchPmLanWakeFromDeepSx = config->WakeConfigPcieWakeFromDeepSx;
params->PchLanEnable = config->EnableLan;
params->SataSalpSupport = config->SataSalpSupport;
params->SsicPortEnable = config->SsicPortEnable;
params->ScsEmmcEnabled = config->ScsEmmcEnabled;
params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled;
params->ScsSdCardEnabled = config->ScsSdCardEnabled;
params->PchIshEnable = config->IshEnable;
params->PchHdaEnable = config->EnableAzalia;
params->PchHdaIoBufferOwnership = config->IoBufferOwnership;
params->PchHdaDspEnable = config->DspEnable;
params->XdciEnable = config->XdciEnable;
params->Device4Enable = config->Device4Enable;
params->SataEnable = config->EnableSata;
params->SataMode = config->SataMode;
params->SataSpeedLimit = config->SataSpeedLimit;
tconfig->PchLockDownGlobalSmi = config->LockDownConfigGlobalSmi;
tconfig->PchLockDownRtcLock = config->LockDownConfigRtcLock;
/*
* To disable HECI, the Psf needs to be left unlocked
* by FSP till end of post sequence. Based on the devicetree
* setting, we set the appropriate PsfUnlock policy in FSP,
* do the changes and then lock it back in coreboot during finalize.
*/
tconfig->PchSbAccessUnlock = (config->HeciEnabled == 0) ? 1 : 0;
if (config->chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {
tconfig->PchLockDownBiosInterface = 0;
params->PchLockDownBiosLock = 0;
params->PchLockDownSpiEiss = 0;
/*
* Skip Spi Flash Lockdown from inside FSP.
* Making this config "0" means FSP won't set the FLOCKDN bit
* of SPIBAR + 0x04 (i.e., Bit 15 of BIOS_HSFSTS_CTL).
* So, it becomes coreboot's responsibility to set this bit
* before end of POST for security concerns.
*/
params->SpiFlashCfgLockDown = 0;
}
params->PchSubSystemVendorId = config->PchConfigSubSystemVendorId;
params->PchSubSystemId = config->PchConfigSubSystemId;
params->PchPmWolEnableOverride = config->WakeConfigWolEnableOverride;
params->PchPmPcieWakeFromDeepSx = config->WakeConfigPcieWakeFromDeepSx;
params->PchPmDeepSxPol = config->PmConfigDeepSxPol;
params->PchPmSlpS0Enable = config->s0ix_enable;
params->PchPmSlpS3MinAssert = config->PmConfigSlpS3MinAssert;
params->PchPmSlpS4MinAssert = config->PmConfigSlpS4MinAssert;
params->PchPmSlpSusMinAssert = config->PmConfigSlpSusMinAssert;
params->PchPmSlpAMinAssert = config->PmConfigSlpAMinAssert;
params->PchPmLpcClockRun = config->PmConfigPciClockRun;
params->PchPmSlpStrchSusUp = config->PmConfigSlpStrchSusUp;
params->PchPmPwrBtnOverridePeriod =
config->PmConfigPwrBtnOverridePeriod;
params->PchPmPwrCycDur = config->PmConfigPwrCycDur;
/* Indicate whether platform supports Voltage Margining */
params->PchPmSlpS0VmEnable = config->PchPmSlpS0VmEnable;
params->PchSirqEnable = config->SerialIrqConfigSirqEnable;
params->PchSirqMode = config->SerialIrqConfigSirqMode;
params->CpuConfig.Bits.SkipMpInit = config->FspSkipMpInit;
for (i = 0; i < ARRAY_SIZE(config->i2c); i++)
params->SerialIoI2cVoltage[i] = config->i2c_voltage[i];
for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
fill_vr_domain_config(params, i, &config->domain_vr_config[i]);
/* Show SPI controller if enabled in devicetree.cb */
dev = dev_find_slot(0, PCH_DEVFN_SPI);
params->ShowSpiController = dev->enabled;
/*
* Send VR specific mailbox commands:
* 000b - no VR specific command sent
* 001b - VR mailbox command specifically for the MPS IMPV8 VR
* will be sent
* 010b - VR specific command sent for PS4 exit issue
* 100b - VR specific command sent for MPS VR decay issue
*/
params->SendVrMbxCmd1 = config->SendVrMbxCmd;
/*
* Activates VR mailbox command for Intersil VR C-state issues.
* 0 - no mailbox command sent.
* 1 - VR mailbox command sent for IA/GT rails only.
* 2 - VR mailbox command sent for IA/GT/SA rails.
*/
params->IslVrCmd = config->IslVrCmd;
/* Acoustic Noise Mitigation */
params->AcousticNoiseMitigation = config->AcousticNoiseMitigation;
params->SlowSlewRateForIa = config->SlowSlewRateForIa;
params->SlowSlewRateForGt = config->SlowSlewRateForGt;
params->SlowSlewRateForSa = config->SlowSlewRateForSa;
params->FastPkgCRampDisableIa = config->FastPkgCRampDisableIa;
params->FastPkgCRampDisableGt = config->FastPkgCRampDisableGt;
params->FastPkgCRampDisableSa = config->FastPkgCRampDisableSa;
/* Enable PMC XRAM read */
tconfig->PchPmPmcReadDisable = config->PchPmPmcReadDisable;
/* Enable/Disable EIST */
tconfig->Eist = config->eist_enable;
soc_irq_settings(params);
}
struct pci_operations soc_pci_ops = {
.set_subsystem = &pci_dev_set_subsystem
};
/* Mainboard GPIO Configuration */
__attribute__((weak)) void mainboard_silicon_init_params(FSP_S_CONFIG *params)
{
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
}