diff options
author | robbie zhang <robbie.zhang@intel.com> | 2015-10-01 17:21:33 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-10-27 15:15:22 +0100 |
commit | b45dde0b78cbe646e12316408ac67cdc72ed9a9d (patch) | |
tree | 5b736a2e5ae7f8f4a28b764f01485e6c6c87867f /src | |
parent | 32074149f702d988e07753b5ff5633dbd0e3409c (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/skylake/acpi.c | 20 | ||||
-rw-r--r-- | src/soc/intel/skylake/igd.c | 86 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/acpi.h | 2 |
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); |