From 96c3ef81fc875d57de17ece5ab11032a846770f6 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 17 May 2017 19:28:32 +0200 Subject: nb/intel/common: Create a common init_igd_opregion method Copy Haswell's init_igd_opregion to common folder. Remove platform specific code. Will replace all Intel NB implementations. Change-Id: I14dfb5986df264ffd71183a159f98b79e8e3230e Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/19905 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Stefan Reinauer --- src/northbridge/intel/common/Kconfig | 3 + src/northbridge/intel/common/Makefile.inc | 1 + src/northbridge/intel/common/gma_opregion.c | 135 ++++++++++++++++++++++++++++ src/northbridge/intel/common/gma_opregion.h | 24 +++++ 4 files changed, 163 insertions(+) create mode 100644 src/northbridge/intel/common/gma_opregion.c create mode 100644 src/northbridge/intel/common/gma_opregion.h diff --git a/src/northbridge/intel/common/Kconfig b/src/northbridge/intel/common/Kconfig index 80593d6bf8..672010ecf5 100644 --- a/src/northbridge/intel/common/Kconfig +++ b/src/northbridge/intel/common/Kconfig @@ -1,2 +1,5 @@ config NORTHBRIDGE_INTEL_COMMON_MRC_CACHE def_bool n + +config NORTHBRIDGE_INTEL_COMMON_GMA_OPREGION + def_bool n diff --git a/src/northbridge/intel/common/Makefile.inc b/src/northbridge/intel/common/Makefile.inc index 73427cbbb1..fe729707e9 100644 --- a/src/northbridge/intel/common/Makefile.inc +++ b/src/northbridge/intel/common/Makefile.inc @@ -15,3 +15,4 @@ romstage-$(CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE) += mrc_cache.c ramstage-$(CONFIG_NORTHBRIDGE_INTEL_COMMON_MRC_CACHE) += mrc_cache.c +ramstage-$(CONFIG_NORTHBRIDGE_INTEL_COMMON_GMA_OPREGION) += gma_opregion.c diff --git a/src/northbridge/intel/common/gma_opregion.c b/src/northbridge/intel/common/gma_opregion.c new file mode 100644 index 0000000000..7d4c3f1c05 --- /dev/null +++ b/src/northbridge/intel/common/gma_opregion.c @@ -0,0 +1,135 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "gma_opregion.h" + +static void *get_intel_vbios(void) +{ + /* This should probably be looking at CBFS or we should always + * deploy the VBIOS on Intel systems, even if we don't run it + * in coreboot (e.g. SeaBIOS only scenarios). + */ + u8 *vbios = (u8 *)0xc0000; + + optionrom_header_t *oprom = (optionrom_header_t *)vbios; + optionrom_pcir_t *pcir = (optionrom_pcir_t *)(vbios + + oprom->pcir_offset); + + printk(BIOS_DEBUG, "GET_VBIOS: %x %x %x %x %x\n", + oprom->signature, pcir->vendor, pcir->classcode[0], + pcir->classcode[1], pcir->classcode[2]); + + + if ((oprom->signature == OPROM_SIGNATURE) && + (pcir->vendor == PCI_VENDOR_ID_INTEL) && + (pcir->classcode[0] == 0x00) && + (pcir->classcode[1] == 0x00) && + (pcir->classcode[2] == 0x03)) + return (void *)vbios; + + return NULL; +} + +static enum cb_err init_opregion_vbt(igd_opregion_t *opregion) +{ + void *vbios; + vbios = get_intel_vbios(); + if (!vbios) { + printk(BIOS_DEBUG, "VBIOS not found.\n"); + return CB_ERR; + } + + printk(BIOS_DEBUG, " ... VBIOS found at %p\n", vbios); + optionrom_header_t *oprom = (optionrom_header_t *)vbios; + optionrom_vbt_t *vbt = (optionrom_vbt_t *)(vbios + + oprom->vbt_offset); + + if (read32(vbt->hdr_signature) != VBT_SIGNATURE) { + printk(BIOS_DEBUG, "VBT not found!\n"); + return CB_ERR; + } + + memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4); + memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < 7168 ? + vbt->hdr_vbt_size : 7168); + + return CB_SUCCESS; +} + +/* Initialize IGD OpRegion, called from ACPI code and OS drivers */ +enum cb_err init_igd_opregion(igd_opregion_t *opregion) +{ + enum cb_err ret; + device_t igd; + u16 reg16; + + memset((void *)opregion, 0, sizeof(igd_opregion_t)); + + // FIXME if IGD is disabled, we should exit here. + + memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE, + sizeof(opregion->header.signature)); + + /* 8kb */ + opregion->header.size = sizeof(igd_opregion_t) / 1024; + opregion->header.version = IGD_OPREGION_VERSION; + + // FIXME We just assume we're mobile for now + opregion->header.mailboxes = MAILBOXES_MOBILE; + + // TODO Initialize Mailbox 1 + + // TODO 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; + + ret = init_opregion_vbt(opregion); + if (ret != CB_SUCCESS) + return ret; + + /* TODO This needs to happen in S3 resume, too. + * Maybe it should move to the finalize handler + */ + igd = dev_find_slot(0, PCI_DEVFN(0x2, 0)); + pci_write_config32(igd, ASLS, (u32)opregion); + + /* Intel's Windows driver relies on this: */ + reg16 = pci_read_config16(igd, SWSCI); + reg16 &= ~GSSCIE; + reg16 |= SMISCISEL; + pci_write_config16(igd, SWSCI, reg16); + + return CB_SUCCESS; +} diff --git a/src/northbridge/intel/common/gma_opregion.h b/src/northbridge/intel/common/gma_opregion.h new file mode 100644 index 0000000000..6e6d5c2d69 --- /dev/null +++ b/src/northbridge/intel/common/gma_opregion.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef NORTHBRIDGE_INTEL_COMMON_GMA_OPREGION_H_ +#define NORTHBRIDGE_INTEL_COMMON_GMA_OPREGION_H_ + +#include +#include + +enum cb_err init_igd_opregion(igd_opregion_t *opregion); + +#endif /* NORTHBRIDGE_INTEL_COMMON_GMA_OPREGION_H_ */ -- cgit v1.2.3