intel/skylake: Add support for Gfx PEIM (AKA GOP)
This patch implements the igd_opregion using the write_acpi_tables mechanism to support GOP usage. BRANCH=none BUG=chrome-os-partner:44559 TEST=W/o GOP_SUPPORT in config, Built and boot on kunimitsu/glados. W/ GOP_SUPPORT enabled, build and boot on kunimitsu/glados, but on glados Dev screen can not be seen (OS display is fine). CQ-DEPEND=CL:303539 Change-Id: I4cd63dfe0d3f456c5f084e38db976425143f79e7 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 4db57463a69c6114b1e2ed4035d378ee3a82783f Original-Change-Id: I6f3c29c1b608eeaad8f2bf79d17394d49f8e412c Original-Signed-off-by: robbie zhang <robbie.zhang@intel.com> Original-Reviewed-on: https://chromium-review.googlesource.com/303387 Original-Commit-Ready: Robbie Zhang <robbie.zhang@intel.com> Original-Tested-by: Robbie Zhang <robbie.zhang@intel.com> Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/12142 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
32074149f7
commit
b45dde0b78
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
#include <arch/acpigen.h>
|
#include <arch/acpigen.h>
|
||||||
|
#include <arch/cpu.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <arch/ioapic.h>
|
#include <arch/ioapic.h>
|
||||||
#include <arch/smp/mpspec.h>
|
#include <arch/smp/mpspec.h>
|
||||||
|
@ -29,14 +30,10 @@
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/cpu.h>
|
#include <cpu/cpu.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <types.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <arch/cpu.h>
|
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
#include <cpu/x86/tsc.h>
|
#include <cpu/x86/tsc.h>
|
||||||
#include <cpu/intel/turbo.h>
|
#include <cpu/intel/turbo.h>
|
||||||
#include <ec/google/chromeec/ec.h>
|
#include <ec/google/chromeec/ec.h>
|
||||||
#include <vendorcode/google/chromeos/gnvs.h>
|
|
||||||
#include <soc/intel/common/acpi.h>
|
#include <soc/intel/common/acpi.h>
|
||||||
#include <soc/acpi.h>
|
#include <soc/acpi.h>
|
||||||
#include <soc/cpu.h>
|
#include <soc/cpu.h>
|
||||||
|
@ -45,6 +42,9 @@
|
||||||
#include <soc/msr.h>
|
#include <soc/msr.h>
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
#include <soc/pm.h>
|
#include <soc/pm.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <types.h>
|
||||||
|
#include <vendorcode/google/chromeos/gnvs.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of suported C-states in this processor.
|
* List of suported C-states in this processor.
|
||||||
|
@ -541,8 +541,6 @@ unsigned long acpi_madt_irq_overrides(unsigned long current)
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ALIGN_CURRENT current = (ALIGN(current, 16))
|
|
||||||
|
|
||||||
unsigned long southcluster_write_acpi_tables(device_t device,
|
unsigned long southcluster_write_acpi_tables(device_t device,
|
||||||
unsigned long current,
|
unsigned long current,
|
||||||
struct acpi_rsdp *rsdp)
|
struct acpi_rsdp *rsdp)
|
||||||
|
@ -552,16 +550,6 @@ unsigned long southcluster_write_acpi_tables(device_t device,
|
||||||
current = acpi_write_hpet(device, current, rsdp);
|
current = acpi_write_hpet(device, current, rsdp);
|
||||||
ALIGN_CURRENT;
|
ALIGN_CURRENT;
|
||||||
|
|
||||||
#if CONFIG_GOP_SUPPORT
|
|
||||||
igd_opregion_t *opregion;
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n");
|
|
||||||
opregion = (igd_opregion_t *)current;
|
|
||||||
init_igd_opregion(opregion);
|
|
||||||
current += sizeof(igd_opregion_t);
|
|
||||||
ALIGN_CURRENT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ssdt2 = (acpi_header_t *)current;
|
ssdt2 = (acpi_header_t *)current;
|
||||||
memset(ssdt2, 0, sizeof(acpi_header_t));
|
memset(ssdt2, 0, sizeof(acpi_header_t));
|
||||||
if (ssdt2->length) {
|
if (ssdt2->length) {
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <device/pci.h>
|
#include <device/pci.h>
|
||||||
#include <device/pci_ids.h>
|
#include <device/pci_ids.h>
|
||||||
#include <drivers/intel/gma/i915_reg.h>
|
#include <drivers/intel/gma/i915_reg.h>
|
||||||
|
#include <fsp/gop.h>
|
||||||
|
#include <soc/acpi.h>
|
||||||
#include <soc/cpu.h>
|
#include <soc/cpu.h>
|
||||||
#include <soc/pm.h>
|
#include <soc/pm.h>
|
||||||
#include <soc/ramstage.h>
|
#include <soc/ramstage.h>
|
||||||
|
@ -64,6 +66,9 @@ static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask)
|
||||||
|
|
||||||
static void igd_init(struct device *dev)
|
static void igd_init(struct device *dev)
|
||||||
{
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_GOP_SUPPORT))
|
||||||
|
return;
|
||||||
|
|
||||||
/* IGD needs to be Bus Master */
|
/* IGD needs to be Bus Master */
|
||||||
u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
|
u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
|
||||||
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
|
||||||
|
@ -102,12 +107,93 @@ static void igd_init(struct device *dev)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize IGD OpRegion, called from ACPI code */
|
||||||
|
static int init_igd_opregion(igd_opregion_t *opregion)
|
||||||
|
{
|
||||||
|
const optionrom_vbt_t *vbt;
|
||||||
|
uint32_t vbt_len;
|
||||||
|
u16 reg16;
|
||||||
|
|
||||||
|
memset(opregion, 0, sizeof(igd_opregion_t));
|
||||||
|
|
||||||
|
/* Read VBT table from flash */
|
||||||
|
vbt = fsp_get_vbt(&vbt_len);
|
||||||
|
if (!vbt)
|
||||||
|
die("vbt data not found");
|
||||||
|
|
||||||
|
memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,
|
||||||
|
sizeof(IGD_OPREGION_SIGNATURE));
|
||||||
|
memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, sizeof(u32));
|
||||||
|
memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size <
|
||||||
|
sizeof(opregion->vbt.gvd1) ? vbt->hdr_vbt_size :
|
||||||
|
sizeof(opregion->vbt.gvd1));
|
||||||
|
|
||||||
|
/* Size, in KB, of the entire OpRegion structure (including header)*/
|
||||||
|
opregion->header.size = sizeof(igd_opregion_t) / KiB;
|
||||||
|
opregion->header.version = IGD_OPREGION_VERSION;
|
||||||
|
|
||||||
|
/* We just assume we're mobile for now */
|
||||||
|
opregion->header.mailboxes = MAILBOXES_MOBILE;
|
||||||
|
|
||||||
|
/* TODO Initialize Mailbox 1 */
|
||||||
|
|
||||||
|
/* Initialize Mailbox 3 */
|
||||||
|
opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS;
|
||||||
|
opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH;
|
||||||
|
opregion->mailbox3.pcft = 0; /* should be (IMON << 1) & 0x3e */
|
||||||
|
opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS;
|
||||||
|
opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000;
|
||||||
|
opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19;
|
||||||
|
opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433;
|
||||||
|
opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c;
|
||||||
|
opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866;
|
||||||
|
opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f;
|
||||||
|
opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99;
|
||||||
|
opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2;
|
||||||
|
opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc;
|
||||||
|
opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5;
|
||||||
|
opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff;
|
||||||
|
|
||||||
|
/* TODO This may need to happen in S3 resume */
|
||||||
|
pci_write_config32(SA_DEV_IGD, ASLS, (u32)opregion);
|
||||||
|
reg16 = pci_read_config16(SA_DEV_IGD, SWSCI);
|
||||||
|
reg16 &= ~GSSCIE;
|
||||||
|
reg16 |= SMISCISEL;
|
||||||
|
pci_write_config16(SA_DEV_IGD, SWSCI, reg16);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long write_acpi_igd_opregion(device_t device,
|
||||||
|
unsigned long current, struct acpi_rsdp *rsdp)
|
||||||
|
{
|
||||||
|
igd_opregion_t *opregion;
|
||||||
|
|
||||||
|
/* If GOP is not used, exit here */
|
||||||
|
if (!IS_ENABLED(CONFIG_GOP_SUPPORT))
|
||||||
|
return current;
|
||||||
|
|
||||||
|
/* If IGD is disabled, exit here */
|
||||||
|
if (pci_read_config16(device, PCI_VENDOR_ID) == 0xFFFF)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n");
|
||||||
|
opregion = (igd_opregion_t *)current;
|
||||||
|
init_igd_opregion(opregion);
|
||||||
|
current += sizeof(igd_opregion_t);
|
||||||
|
ALIGN_CURRENT;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "current = %lx\n", current);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
static struct device_operations igd_ops = {
|
static struct device_operations igd_ops = {
|
||||||
.read_resources = &pci_dev_read_resources,
|
.read_resources = &pci_dev_read_resources,
|
||||||
.set_resources = &pci_dev_set_resources,
|
.set_resources = &pci_dev_set_resources,
|
||||||
.enable_resources = &pci_dev_enable_resources,
|
.enable_resources = &pci_dev_enable_resources,
|
||||||
.init = &igd_init,
|
.init = &igd_init,
|
||||||
.ops_pci = &soc_pci_ops,
|
.ops_pci = &soc_pci_ops,
|
||||||
|
.write_acpi_tables = write_acpi_igd_opregion,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned short pci_device_ids[] = {
|
static const unsigned short pci_device_ids[] = {
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#define PSS_LATENCY_TRANSITION 10
|
#define PSS_LATENCY_TRANSITION 10
|
||||||
#define PSS_LATENCY_BUSMASTER 10
|
#define PSS_LATENCY_BUSMASTER 10
|
||||||
|
|
||||||
|
#define ALIGN_CURRENT current = (ALIGN(current, 16))
|
||||||
|
|
||||||
void acpi_fill_in_fadt(acpi_fadt_t *fadt);
|
void acpi_fill_in_fadt(acpi_fadt_t *fadt);
|
||||||
unsigned long acpi_madt_irq_overrides(unsigned long current);
|
unsigned long acpi_madt_irq_overrides(unsigned long current);
|
||||||
void acpi_mainboard_gnvs(global_nvs_t *gnvs);
|
void acpi_mainboard_gnvs(global_nvs_t *gnvs);
|
||||||
|
|
Loading…
Reference in New Issue