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:
robbie zhang 2015-10-01 17:21:33 -07:00 committed by Patrick Georgi
parent 32074149f7
commit b45dde0b78
3 changed files with 92 additions and 16 deletions

View File

@ -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) {

View File

@ -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[] = {

View File

@ -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);