[coreboot-gerrit] Change in coreboot[master]: [WIP] drv/intel/gma/opregion: Add common init_idg_opregion()
Matt DeVillier (Code Review)
gerrit at coreboot.org
Tue Jun 27 20:19:37 CEST 2017
Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/20394
Change subject: [WIP] drv/intel/gma/opregion: Add common init_idg_opregion()
......................................................................
[WIP] drv/intel/gma/opregion: Add common init_idg_opregion()
Add a new common method to initialize ACPI OpRegion.
Change-Id: I2378043a82bdf785df10a702afef1123662e04d9
Signed-off-by: Matt DeVillier <matt.devillier at gmail.com>
---
M src/drivers/intel/gma/Kconfig
M src/drivers/intel/gma/Makefile.inc
M src/drivers/intel/gma/opregion.c
M src/drivers/intel/gma/opregion.h
4 files changed, 171 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/20394/1
diff --git a/src/drivers/intel/gma/Kconfig b/src/drivers/intel/gma/Kconfig
index 1e60a42..c3bb8e0 100644
--- a/src/drivers/intel/gma/Kconfig
+++ b/src/drivers/intel/gma/Kconfig
@@ -109,3 +109,21 @@
read over the I2C interface of the coupled digital port.
endif
+
+config INTEL_GMA_OPREGION
+ def_bool n
+
+config ADD_VBT_DATA_FILE
+ bool "Add a Video Bios Table (VBT) binary to CBFS"
+ depends on INTEL_GMA_OPREGION
+ default y if INTEL_GMA_OPREGION
+ help
+ Add a VBT file data file to CBFS. The VBT describes the integrated
+ GPU and connections, and can be used in leiu of a VBIOS in order to
+ populate the ACPI OpRegion VBT data.
+
+config VBT_FILE
+ string "VBT binary path and filename"
+ depends on ADD_VBT_DATA_FILE
+ help
+ The path and filename of the VBT binary.
diff --git a/src/drivers/intel/gma/Makefile.inc b/src/drivers/intel/gma/Makefile.inc
index 50494e1..ce81d37 100644
--- a/src/drivers/intel/gma/Makefile.inc
+++ b/src/drivers/intel/gma/Makefile.inc
@@ -19,8 +19,11 @@
ramstage-$(CONFIG_INTEL_INT15) += int15.c
endif
ramstage-$(CONFIG_INTEL_GMA_ACPI) += acpi.c
-ramstage-$(CONFIG_INTEL_GMA_ACPI) += opregion.c
+ramstage-$(CONFIG_INTEL_GMA_OPREGION) += opregion.c
+cbfs-files-$(CONFIG_ADD_VBT_DATA_FILE) += vbt.bin
+vbt.bin-file := $(call strip_quotes,$(CONFIG_VBT_FILE))
+vbt.bin-type := raw
ifeq ($(CONFIG_MAINBOARD_USE_LIBGFXINIT),y)
diff --git a/src/drivers/intel/gma/opregion.c b/src/drivers/intel/gma/opregion.c
index 5cd04ae..02563d0 100644
--- a/src/drivers/intel/gma/opregion.c
+++ b/src/drivers/intel/gma/opregion.c
@@ -14,10 +14,15 @@
* GNU General Public License for more details.
*/
+#include <cbfs.h>
+#include <cbmem.h>
+#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
+#include <string.h>
+#include "intel_bios.h"
#include "opregion.h"
/* Write ASLS PCI register and enables SWSCI. */
@@ -39,3 +44,145 @@
reg16 |= SMISCISEL;
pci_write_config16(igd, SWSCI, reg16);
}
+
+void * __attribute__((weak))get_fake_vbt_signature(void)
+{
+ return NULL;
+}
+
+static void
+generate_vbt(struct vbt_header *const head, const char *const idstr)
+{
+ u8 *ptr;
+
+ memset(head, 0, sizeof (*head));
+
+ memset(head->signature, ' ', sizeof (head->signature));
+ memcpy(head->signature, idstr,
+ MIN(strlen(idstr), sizeof (head->signature)));
+ head->version = 100;
+ head->header_size = sizeof (*head);
+ head->bdb_offset = sizeof (*head);
+
+ struct bdb_header *const bdb_head = (struct bdb_header *)(head + 1);
+ memset(bdb_head, 0, sizeof (*bdb_head));
+ memcpy(bdb_head->signature, "BIOS_DATA_BLOCK ", 16);
+ bdb_head->version = 0xa8;
+ bdb_head->header_size = sizeof (*bdb_head);
+
+ ptr = (u8 *)(bdb_head + 1);
+
+ ptr[0] = BDB_GENERAL_FEATURES;
+ ptr[1] = sizeof (struct bdb_general_features);
+ ptr[2] = sizeof (struct bdb_general_features) >> 8;
+ ptr += 3;
+
+ struct bdb_general_features *const genfeat =
+ (struct bdb_general_features *)ptr;
+ memset(genfeat, 0, sizeof (*genfeat));
+ genfeat->panel_fitting = 3;
+ genfeat->flexaim = 1;
+ genfeat->download_ext_vbt = 1;
+ genfeat->enable_ssc = IS_ENABLED(CONFIG_INTEL_GMA_SSC_ALTERNATE_REF);
+ genfeat->ssc_freq = IS_ENABLED(CONFIG_INTEL_GMA_SSC_ALTERNATE_REF);
+ genfeat->rsvd10 = 0x4;
+ genfeat->legacy_monitor_detect = 1;
+ genfeat->int_crt_support = 1;
+ genfeat->dp_ssc_enb = 1;
+
+ ptr += sizeof (*genfeat);
+
+ bdb_head->bdb_size = ptr - (u8 *)bdb_head;
+ head->vbt_size = ptr - (u8 *)head;
+ head->vbt_checksum = 0;
+}
+
+enum cb_err
+init_igd_opregion(igd_opregion_t *opregion)
+{
+ struct region_device vbt_rdev;
+ optionrom_vbt_t *vbt = NULL;
+ optionrom_vbt_t *ext_vbt;
+ uint32_t vbtsig = 0;
+ struct cbfsf file_desc;
+ int need_unmap = 0;
+
+ /* try to locate vbt.bin in CBFS */
+ if (cbfs_boot_locate(&file_desc, "vbt.bin", NULL) == CB_SUCCESS) {
+ cbfs_file_data(&vbt_rdev, &file_desc);
+ vbt = rdev_mmap_full(&vbt_rdev);
+ if (vbt) {
+ /* Validate the vbt file */
+ memcpy(&vbtsig, vbt, sizeof(uint32_t));
+ if (vbtsig != VBT_SIGNATURE) {
+ printk(BIOS_ERR, "Invalid signature in VBT data file (vbt.bin)!\n");
+ rdev_munmap(&vbt_rdev, vbt);
+ vbt = NULL;
+ }
+ need_unmap = 1;
+ } else {
+ printk(BIOS_ERR, "VBT couldn't be read\n");
+ }
+ } else {
+ printk(BIOS_NOTICE, "Could not locate a VBT file in in CBFS\n");
+ }
+
+ /* If no vbt.bin, try to load from VBIOS in CBFS */
+ if (!vbt) {
+ optionrom_header_t *oprom = (optionrom_header_t *) pci_rom_probe(dev_find_slot(0, PCI_DEVFN(0x2,0)));
+ if (oprom) {
+ printk(BIOS_DEBUG, "VBIOS found at %p\n", oprom);
+ vbt = (optionrom_vbt_t *)(oprom + oprom->vbt_offset);
+ if (read32(vbt->hdr_signature) != VBT_SIGNATURE) {
+ printk(BIOS_DEBUG, "VBIOS VBT not found!\n");
+ vbt = NULL;
+ }
+ } else {
+ printk(BIOS_DEBUG, "VBIOS not found.\n");
+ }
+ }
+
+ /* TODO: 3rd option - generate fake VBT */
+ if (!vbt) {
+ optionrom_vbt_t fake_vbt;
+ generate_vbt((struct vbt_header *)&fake_vbt, get_fake_vbt_signature());
+ vbt = &fake_vbt;
+ }
+
+ /* Ensure we have something to load into opregion */
+ if (!vbt)
+ return CB_ERR;
+
+ memset(opregion, 0, sizeof(igd_opregion_t));
+
+ memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,
+ sizeof(opregion->header.signature));
+ memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild,
+ ARRAY_SIZE(vbt->coreblock_biosbuild));
+ /* Extended VBT support */
+ if (vbt->hdr_vbt_size > sizeof(opregion->vbt.gvd1)) {
+ ext_vbt = cbmem_add(CBMEM_ID_EXT_VBT, vbt->hdr_vbt_size);
+
+ if (ext_vbt == NULL) {
+ printk(BIOS_ERR, "Unable to add Ext VBT to cbmem!\n");
+ rdev_munmap(&vbt_rdev, vbt);
+ return CB_ERR;
+ }
+
+ memcpy(ext_vbt, vbt, vbt->hdr_vbt_size);
+ opregion->mailbox3.rvda = (uintptr_t)ext_vbt;
+ opregion->mailbox3.rvds = vbt->hdr_vbt_size;
+ } else {
+ /* Raw VBT size which can fit in gvd1 */
+ memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size);
+ }
+
+ /* 8KiB */
+ opregion->header.size = sizeof(igd_opregion_t) / KiB;
+ opregion->header.version = (IGD_OPREGION_VERSION << 24);
+
+ if (need_unmap)
+ rdev_munmap(&vbt_rdev, vbt);
+
+ return CB_SUCCESS;
+}
diff --git a/src/drivers/intel/gma/opregion.h b/src/drivers/intel/gma/opregion.h
index c590805..85b54f1 100644
--- a/src/drivers/intel/gma/opregion.h
+++ b/src/drivers/intel/gma/opregion.h
@@ -246,5 +246,7 @@
} __attribute__((packed)) optionrom_vbt_t;
void intel_gma_opregion_register(uintptr_t opregion);
+void * __attribute__((weak)) get_fake_vbt_signature(void);
+enum cb_err init_igd_opregion(igd_opregion_t *opregion);
#endif /* _COMMON_GMA_H_ */
--
To view, visit https://review.coreboot.org/20394
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2378043a82bdf785df10a702afef1123662e04d9
Gerrit-Change-Number: 20394
Gerrit-PatchSet: 1
Gerrit-Owner: Matt DeVillier <matt.devillier at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170627/b158bfe8/attachment.html>
More information about the coreboot-gerrit
mailing list