[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