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

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I2378043a82bdf785df10a702afef1123662e04d9 </div>
<div style="display:none"> Gerrit-Change-Number: 20394 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt DeVillier <matt.devillier@gmail.com> </div>