summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobbie zhang <robbie.zhang@intel.com>2015-10-01 17:21:33 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-10-27 15:15:22 +0100
commitb45dde0b78cbe646e12316408ac67cdc72ed9a9d (patch)
tree5b736a2e5ae7f8f4a28b764f01485e6c6c87867f
parent32074149f702d988e07753b5ff5633dbd0e3409c (diff)
downloadcoreboot-b45dde0b78cbe646e12316408ac67cdc72ed9a9d.tar.xz
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>
-rw-r--r--src/soc/intel/skylake/acpi.c20
-rw-r--r--src/soc/intel/skylake/igd.c86
-rw-r--r--src/soc/intel/skylake/include/soc/acpi.h2
3 files changed, 92 insertions, 16 deletions
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c
index 471fd17981..4b9440a068 100644
--- a/src/soc/intel/skylake/acpi.c
+++ b/src/soc/intel/skylake/acpi.c
@@ -21,6 +21,7 @@
#include <arch/acpi.h>
#include <arch/acpigen.h>
+#include <arch/cpu.h>
#include <arch/io.h>
#include <arch/ioapic.h>
#include <arch/smp/mpspec.h>
@@ -29,14 +30,10 @@
#include <console/console.h>
#include <cpu/cpu.h>
#include <cpu/x86/smm.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 <ec/google/chromeec/ec.h>
-#include <vendorcode/google/chromeos/gnvs.h>
#include <soc/intel/common/acpi.h>
#include <soc/acpi.h>
#include <soc/cpu.h>
@@ -45,6 +42,9 @@
#include <soc/msr.h>
#include <soc/pci_devs.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.
@@ -541,8 +541,6 @@ unsigned long acpi_madt_irq_overrides(unsigned long current)
return current;
}
-#define ALIGN_CURRENT current = (ALIGN(current, 16))
-
unsigned long southcluster_write_acpi_tables(device_t device,
unsigned long current,
struct acpi_rsdp *rsdp)
@@ -552,16 +550,6 @@ unsigned long southcluster_write_acpi_tables(device_t device,
current = acpi_write_hpet(device, current, rsdp);
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;
memset(ssdt2, 0, sizeof(acpi_header_t));
if (ssdt2->length) {
diff --git a/src/soc/intel/skylake/igd.c b/src/soc/intel/skylake/igd.c
index 5422217351..d105fc9b9f 100644
--- a/src/soc/intel/skylake/igd.c
+++ b/src/soc/intel/skylake/igd.c
@@ -27,6 +27,8 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <drivers/intel/gma/i915_reg.h>
+#include <fsp/gop.h>
+#include <soc/acpi.h>
#include <soc/cpu.h>
#include <soc/pm.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)
{
+ if (IS_ENABLED(CONFIG_GOP_SUPPORT))
+ return;
+
/* IGD needs to be Bus Master */
u32 reg32 = pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
@@ -102,12 +107,93 @@ static void igd_init(struct device *dev)
#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 = {
.read_resources = &pci_dev_read_resources,
.set_resources = &pci_dev_set_resources,
.enable_resources = &pci_dev_enable_resources,
.init = &igd_init,
.ops_pci = &soc_pci_ops,
+ .write_acpi_tables = write_acpi_igd_opregion,
};
static const unsigned short pci_device_ids[] = {
diff --git a/src/soc/intel/skylake/include/soc/acpi.h b/src/soc/intel/skylake/include/soc/acpi.h
index 7418fe0be5..7e9a3dba88 100644
--- a/src/soc/intel/skylake/include/soc/acpi.h
+++ b/src/soc/intel/skylake/include/soc/acpi.h
@@ -30,6 +30,8 @@
#define PSS_LATENCY_TRANSITION 10
#define PSS_LATENCY_BUSMASTER 10
+#define ALIGN_CURRENT current = (ALIGN(current, 16))
+
void acpi_fill_in_fadt(acpi_fadt_t *fadt);
unsigned long acpi_madt_irq_overrides(unsigned long current);
void acpi_mainboard_gnvs(global_nvs_t *gnvs);