soc/intel/broadwell: add support for Intel GMA OpRegion

Add global/ACPI nvs variables required for IGD OpRegion.
Add functions necessary to generate ACPI OpRegion, save the
table address in ASLB, and restore table address upon S3 resume.

Implementation largely based on existing Haswell/Lynxpoint code.

Test: boot Windows 10 on google/lulu with Tianocore payload and
GOP display init, observe display driver loaded and functional,
display not black screen when resuming from S3 suspend.

Change-Id: I024f4f0784df3cbbb9977692e9ef0ff9c3552725
Signed-off-by: CoolStar <coolstarorganization@gmail.com>
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/25094
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Matt DeVillier 2017-10-18 12:27:25 -05:00 committed by Martin Roth
parent cb9f55ec38
commit 773488f3f7
4 changed files with 123 additions and 1 deletions

View File

@ -41,6 +41,7 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
select HAVE_SPI_CONSOLE_SUPPORT select HAVE_SPI_CONSOLE_SUPPORT
select CPU_INTEL_COMMON select CPU_INTEL_COMMON
select INTEL_GMA_ACPI
config PCIEXP_ASPM config PCIEXP_ASPM
bool bool

View File

@ -59,6 +59,48 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
PM1I, 64, // 0x20 - 0x27 - PM1 wake status bit PM1I, 64, // 0x20 - 0x27 - PM1 wake status bit
GPEI, 64, // 0x28 - 0x2f - GPE wake status bit GPEI, 64, // 0x28 - 0x2f - GPE wake status bit
/* IGD OpRegion */
Offset (0xb4),
ASLB, 32, // 0xb4 - IGD OpRegion Base Address
IBTT, 8, // 0xb8 - IGD boot panel device
IPAT, 8, // 0xb9 - IGD panel type cmos option
ITVF, 8, // 0xba - IGD TV format cmos option
ITVM, 8, // 0xbb - IGD TV minor format option
IPSC, 8, // 0xbc - IGD panel scaling
IBLC, 8, // 0xbd - IGD BLC config
IBIA, 8, // 0xbe - IGD BIA config
ISSC, 8, // 0xbf - IGD SSC config
I409, 8, // 0xc0 - IGD 0409 modified settings
I509, 8, // 0xc1 - IGD 0509 modified settings
I609, 8, // 0xc2 - IGD 0609 modified settings
I709, 8, // 0xc3 - IGD 0709 modified settings
IDMM, 8, // 0xc4 - IGD Power conservation feature
IDMS, 8, // 0xc5 - IGD DVMT memory size
IF1E, 8, // 0xc6 - IGD function 1 enable
HVCO, 8, // 0xc7 - IGD HPLL VCO
NXD1, 32, // 0xc8 - IGD _DGS next DID1
NXD2, 32, // 0xcc - IGD _DGS next DID2
NXD3, 32, // 0xd0 - IGD _DGS next DID3
NXD4, 32, // 0xd4 - IGD _DGS next DID4
NXD5, 32, // 0xd8 - IGD _DGS next DID5
NXD6, 32, // 0xdc - IGD _DGS next DID6
NXD7, 32, // 0xe0 - IGD _DGS next DID7
NXD8, 32, // 0xe4 - IGD _DGS next DID8
ISCI, 8, // 0xe8 - IGD SMI/SCI mode (0: SCI)
PAVP, 8, // 0xe9 - IGD PAVP data
Offset (0xeb),
OSCC, 8, // 0xeb - PCIe OSC control
NPCE, 8, // 0xec - native pcie support
PLFL, 8, // 0xed - platform flavor
BREV, 8, // 0xee - board revision
DPBM, 8, // 0xef - digital port b mode
DPCM, 8, // 0xf0 - digital port c mode
DPDM, 8, // 0xf1 - digital port d mode
ALFP, 8, // 0xf2 - active lfp
IMON, 8, // 0xf3 - current graphics turbo imon value
MMIO, 8, // 0xf4 - 64bit mmio support
/* ChromeOS specific */ /* ChromeOS specific */
Offset (0x100), Offset (0x100),
#include <vendorcode/google/chromeos/acpi/gnvs.asl> #include <vendorcode/google/chromeos/acpi/gnvs.asl>

View File

@ -24,8 +24,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <reg_script.h> #include <reg_script.h>
#include <cbmem.h>
#include <drivers/intel/gma/i915_reg.h> #include <drivers/intel/gma/i915_reg.h>
#include <drivers/intel/gma/opregion.h>
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/nvs.h>
#include <soc/pm.h> #include <soc/pm.h>
#include <soc/ramstage.h> #include <soc/ramstage.h>
#include <soc/systemagent.h> #include <soc/systemagent.h>
@ -479,6 +482,19 @@ static void igd_cdclk_init(struct device *dev, const int is_broadwell)
gtt_rmw(0x64810, 0xfffff800, dpdiv); gtt_rmw(0x64810, 0xfffff800, dpdiv);
} }
uintptr_t gma_get_gnvs_aslb(const void *gnvs)
{
const global_nvs_t *gnvs_ptr = gnvs;
return (uintptr_t)(gnvs_ptr ? gnvs_ptr->aslb : 0);
}
void gma_set_gnvs_aslb(void *gnvs, uintptr_t aslb)
{
global_nvs_t *gnvs_ptr = gnvs;
if (gnvs_ptr)
gnvs_ptr->aslb = aslb;
}
static void igd_init(struct device *dev) static void igd_init(struct device *dev)
{ {
int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT); int is_broadwell = !!(cpu_family_model() == BROADWELL_FAMILY_ULT);
@ -555,6 +571,33 @@ static void igd_init(struct device *dev)
gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES | gtt_write(DDI_BUF_CTL_A, DDI_BUF_IS_IDLE | DDI_A_4_LANES |
DDI_INIT_DISPLAY_DETECTED); DDI_INIT_DISPLAY_DETECTED);
} }
intel_gma_restore_opregion();
}
static unsigned long
gma_write_acpi_tables(struct device *const dev, unsigned long current,
struct acpi_rsdp *const rsdp)
{
igd_opregion_t *opregion = (igd_opregion_t *)current;
global_nvs_t *gnvs;
if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS)
return current;
current += sizeof(igd_opregion_t);
/* GNVS has been already set up */
gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
if (gnvs) {
/* IGD OpRegion Base Address */
gma_set_gnvs_aslb(gnvs, (uintptr_t)opregion);
} else {
printk(BIOS_ERR, "Error: GNVS table not found.\n");
}
current = acpi_align_current(current);
return current;
} }
static struct device_operations igd_ops = { static struct device_operations igd_ops = {
@ -563,6 +606,7 @@ static struct device_operations igd_ops = {
.enable_resources = &pci_dev_enable_resources, .enable_resources = &pci_dev_enable_resources,
.init = &igd_init, .init = &igd_init,
.ops_pci = &broadwell_pci_ops, .ops_pci = &broadwell_pci_ops,
.write_acpi_tables = gma_write_acpi_tables,
}; };
static const unsigned short pci_device_ids[] = { static const unsigned short pci_device_ids[] = {

View File

@ -51,7 +51,42 @@ typedef struct global_nvs_t {
u32 cbmc; /* 0x1c - 0x1f - coreboot Memory Console */ u32 cbmc; /* 0x1c - 0x1f - coreboot Memory Console */
u64 pm1i; /* 0x20 - 0x27 - PM1 wake status bit */ u64 pm1i; /* 0x20 - 0x27 - PM1 wake status bit */
u64 gpei; /* 0x28 - 0x2f - GPE wake status bit */ u64 gpei; /* 0x28 - 0x2f - GPE wake status bit */
u8 unused[208]; u8 unused1[132]; /* 0x30 - 0xb3 - unused */
/* IGD OpRegion */
u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
u8 ibtt; /* 0xb8 - IGD boot type */
u8 ipat; /* 0xb9 - IGD panel type */
u8 itvf; /* 0xba - IGD TV format */
u8 itvm; /* 0xbb - IGD TV minor format */
u8 ipsc; /* 0xbc - IGD Panel Scaling */
u8 iblc; /* 0xbd - IGD BLC configuration */
u8 ibia; /* 0xbe - IGD BIA configuration */
u8 issc; /* 0xbf - IGD SSC configuration */
u8 i409; /* 0xc0 - IGD 0409 modified settings */
u8 i509; /* 0xc1 - IGD 0509 modified settings */
u8 i609; /* 0xc2 - IGD 0609 modified settings */
u8 i709; /* 0xc3 - IGD 0709 modified settings */
u8 idmm; /* 0xc4 - IGD Power Conservation */
u8 idms; /* 0xc5 - IGD DVMT memory size */
u8 if1e; /* 0xc6 - IGD Function 1 Enable */
u8 hvco; /* 0xc7 - IGD HPLL VCO */
u32 nxd[8]; /* 0xc8 - IGD next state DIDx for _DGS */
u8 isci; /* 0xe8 - IGD SMI/SCI mode (0: SCI) */
u8 pavp; /* 0xe9 - IGD PAVP data */
u8 rsvd2; /* 0xea - rsvd */
u8 oscc; /* 0xeb - PCIe OSC control */
u8 npce; /* 0xec - native pcie support */
u8 plfl; /* 0xed - platform flavor */
u8 brev; /* 0xee - board revision */
u8 dpbm; /* 0xef - digital port b mode */
u8 dpcm; /* 0xf0 - digital port c mode */
u8 dpdm; /* 0xf1 - digital port c mode */
u8 alfp; /* 0xf2 - active lfp */
u8 imon; /* 0xf3 - current graphics turbo imon value */
u8 mmio; /* 0xf4 - 64bit mmio support */
u8 unused2[11];
/* ChromeOS specific (0x100 - 0xfff) */ /* ChromeOS specific (0x100 - 0xfff) */
chromeos_acpi_t chromeos; chromeos_acpi_t chromeos;