aboutsummaryrefslogtreecommitdiff
path: root/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d')
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch174
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0006-i945-gma.c-add-native-VGA-init.patch241
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0007-i945-gma.c-generate-fake-VBT.patch43
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/reused.list2
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-Enable-brightness-controls-native-graphic.patch36
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-add-hda_verb.c.patch53
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0003-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch174
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch174
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0006-i945-gma.c-add-native-VGA-init.patch241
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0007-i945-gma.c-generate-fake-VBT.patch43
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/INFO3
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/reused.list3
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch88
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch158
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-lenovo-x60-add-hda_verb.c.patch65
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0002-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch31
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch50
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch174
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0006-i945-gma.c-add-native-VGA-init.patch241
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0007-i945-gma.c-generate-fake-VBT.patch43
-rw-r--r--resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/INFO7
21 files changed, 2044 insertions, 0 deletions
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
new file mode 100644
index 00000000..884b2829
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
@@ -0,0 +1,174 @@
+From 34f8cdbc30f1fdf4700c73aad26e0fc159af70ab Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Fri, 2 Sep 2016 22:35:32 +0200
+Subject: [PATCH 1/2] i945/gma.c use latest linux code to calculate divisors.
+
+The code to compute n, m1, m2, p1 divisors is not correct in coreboot and
+on some targets hits a working mode at lower refresh rate, which is why
+display is working on some targets.
+This patch also fixes reference frequency.
+
+This patch reuses linux code to correctly compute divisors.
+
+The result is that some previously not working displays (Lenovo T60 with
+1024x786, 1400x1050, 2048x1536)
+
+TESTED on T60 with 1024x786.
+
+Change-Id: I2c7f3bb0024ac005029eaebe3ecdc70c38ac777e
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 82 +++++++++++++++++++---------------------
+ 1 file changed, 38 insertions(+), 44 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..3f0b5b4 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -26,6 +26,8 @@
+ #include <string.h>
+ #include <pc80/vga.h>
+ #include <pc80/vga_io.h>
++#include <commonlib/helpers.h>
++
+
+ #include "i945.h"
+ #include "chip.h"
+@@ -43,7 +45,7 @@
+ #define PGETBL_CTL 0x2020
+ #define PGETBL_ENABLED 0x00000001
+
+-#define BASE_FREQUENCY 120000
++#define BASE_FREQUENCY 100000
+
+ #if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
+
+@@ -85,10 +87,10 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ u8 edid_data[128];
+ unsigned long temp;
+ int hpolarity, vpolarity;
+- u32 candp1, candn;
+- u32 best_delta = 0xffffffff;
++ u32 smallest_err = 0xffffffff;
+ u32 target_frequency;
+ u32 pixel_p1 = 1;
++ u32 pixel_p2;
+ u32 pixel_n = 1;
+ u32 pixel_m1 = 1;
+ u32 pixel_m2 = 1;
+@@ -158,43 +160,37 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PORT_HOTPLUG_EN, conf->gpu_hotplug);
+ write32(pmmio + INSTPM, 0x08000000 | INSTPM_AGPBUSY_DIS);
+
+- target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
+- : (2 * mode->pixel_clock);
+-
+- /* Find suitable divisors. */
+- for (candp1 = 1; candp1 <= 8; candp1++) {
+- for (candn = 5; candn <= 10; candn++) {
+- u32 cur_frequency;
+- u32 m; /* 77 - 131. */
+- u32 denom; /* 35 - 560. */
+- u32 current_delta;
+-
+- denom = candn * candp1 * 7;
+- /* Doesnt overflow for up to
+- 5000000 kHz = 5 GHz. */
+- m = (target_frequency * denom
+- + BASE_FREQUENCY / 2) / BASE_FREQUENCY;
+-
+- if (m < 77 || m > 131)
+- continue;
+-
+- cur_frequency = (BASE_FREQUENCY * m) / denom;
+- if (target_frequency > cur_frequency)
+- current_delta = target_frequency - cur_frequency;
+- else
+- current_delta = cur_frequency - target_frequency;
+-
+- if (best_delta > current_delta) {
+- best_delta = current_delta;
+- pixel_n = candn;
+- pixel_p1 = candp1;
+- pixel_m2 = ((m + 3) % 5) + 7;
+- pixel_m1 = (m - pixel_m2) / 5;
++ pixel_p2 = mode->lvds_dual_channel ? 7 : 14;
++ target_frequency = mode->pixel_clock;
++
++ /* Find suitable divisors, m1, m2, p1, n. */
++ /* refclock * (5 * (m1 + 2) + (m1 + 2)) / (n + 2) / p1 / p2 */
++ /* should be closest to target frequency as possible */
++ u32 candn, candm1, candm2, candp1;
++ for (candm1 = 8; candm1 <= 18; candm1++) {
++ for (candm2 = 3; candm2 <= 7; candm2++) {
++ for (candn = 1; candn <= 6; candn++) {
++ for (candp1 = 1; candp1 <= 8; candp1++) {
++ u32 m = 5 * (candm1 + 2) + (candm2 + 2);
++ u32 p = candp1 * pixel_p2;
++ u32 vco = DIV_ROUND_CLOSEST(BASE_FREQUENCY * m, candn + 2);
++ u32 dot = DIV_ROUND_CLOSEST(vco, p);
++ u32 this_err = ABS(dot - target_frequency);
++ if ((m < 70) || (m > 120))
++ continue;
++ if (this_err < smallest_err) {
++ smallest_err = this_err;
++ pixel_n = candn;
++ pixel_m1 = candm1;
++ pixel_m2 = candm2;
++ pixel_p1 = candp1;
++ }
++ }
+ }
+ }
+ }
+
+- if (best_delta == 0xffffffff) {
++ if (smallest_err == 0xffffffff) {
+ printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
+ return -1;
+ }
+@@ -216,8 +212,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
+ pixel_n, pixel_m1, pixel_m2, pixel_p1);
+ printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
+- BASE_FREQUENCY * (5 * pixel_m1 + pixel_m2) / pixel_n
+- / (pixel_p1 * 7));
++ BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
++ (pixel_n + 2) / (pixel_p1 * pixel_p2));
+
+ #if !IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
+ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
+@@ -242,8 +238,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PP_CONTROL, PANEL_UNLOCK_REGS
+ | (read32(pmmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
+ write32(pmmio + FP0(1),
+- ((pixel_n - 2) << 16)
+- | ((pixel_m1 - 2) << 8) | pixel_m2);
++ (pixel_n << 16)
++ | (pixel_m1 << 8) | pixel_m2);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+ DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
+@@ -252,8 +248,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (conf->gpu_lvds_use_spread_spectrum_clock
+ ? DPLL_INTEGRATED_CLOCK_VLV | DPLL_INTEGRATED_CRI_CLK_VLV
+ : 0)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+@@ -261,8 +256,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
+ : DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | ((conf->gpu_lvds_use_spread_spectrum_clock ? 3 : 0) << 13)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + HTOTAL(1),
+ ((hactive + right_border + hblank - 1) << 16)
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0006-i945-gma.c-add-native-VGA-init.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0006-i945-gma.c-add-native-VGA-init.patch
new file mode 100644
index 00000000..26eed5b4
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0006-i945-gma.c-add-native-VGA-init.patch
@@ -0,0 +1,241 @@
+From 7ed0951bcf59dfd8b1893232b674455ff8f03f83 Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Mon, 5 Sep 2016 22:46:11 +0200
+Subject: [PATCH 2/2] i945/gma.c: add native VGA init
+
+This reuses the Intel Pineview native graphic initialization
+to have output on the VGA connector of i945 devices.
+
+The behavior is the same as with the vendor VBIOS BLOB.
+It uses the external VGA display if it is connected.
+
+Change-Id: I7eaee87d16df2e5c9ebeaaff01d36ec1aa4ea495
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 196 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 194 insertions(+), 2 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 3f0b5b4..ac19d5a 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -78,7 +78,7 @@ static int gtt_setup(void *mmiobase)
+ return 0;
+ }
+
+-static int intel_gma_init(struct northbridge_intel_i945_config *conf,
++static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf,
+ unsigned int pphysbase, unsigned int piobase,
+ void *pmmio, unsigned int pgfx)
+ {
+@@ -382,6 +382,194 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ #endif
+ return 0;
+ }
++
++static int intel_gma_init_vga(struct northbridge_intel_i945_config *conf,
++ unsigned int pphysbase, unsigned int piobase,
++ void *pmmio, unsigned int pgfx)
++{
++ int i;
++ u32 hactive, vactive;
++ u16 reg16;
++ u32 uma_size;
++
++ printk(BIOS_SPEW, "pmmio %x addrport %x physbase %x\n",
++ (u32)pmmio, piobase, pphysbase);
++
++ gtt_setup(pmmio);
++
++ /* Disable VGA. */
++ write32(pmmio + VGACNTRL, VGA_DISP_DISABLE);
++
++ /* Disable pipes. */
++ write32(pmmio + PIPECONF(0), 0);
++ write32(pmmio + PIPECONF(1), 0);
++
++ write32(pmmio + INSTPM, 0x800);
++
++ vga_gr_write(0x18, 0);
++
++ write32(pmmio + VGA0, 0x200074);
++ write32(pmmio + VGA1, 0x200074);
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
++ write32(pmmio + DSPCLK_GATE_D, 0);
++ write32(pmmio + FW_BLC, 0x03060106);
++ write32(pmmio + FW_BLC2, 0x00000306);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + 0x7041c, 0x0);
++
++ write32(pmmio + DPLL_MD(0), 0x3);
++ write32(pmmio + DPLL_MD(1), 0x3);
++ write32(pmmio + DSPCNTR(1), 0x1000000);
++ write32(pmmio + PIPESRC(1), 0x027f01df);
++
++ vga_misc_write(0x67);
++ const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
++ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
++ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
++ 0xff
++ };
++ vga_cr_write(0x11, 0);
++
++ for (i = 0; i <= 0x18; i++)
++ vga_cr_write(i, cr[i]);
++
++ // Disable screen memory to prevent garbage from appearing.
++ vga_sr_write(1, vga_sr_read(1) | 0x20);
++ hactive = 640;
++ vactive = 400;
++
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + HTOTAL(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HBLANK(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HSYNC(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++
++ write32(pmmio + VTOTAL(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VBLANK(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VSYNC(0),
++ ((vactive - 1) << 16)
++ | (vactive - 1));
++
++ write32(pmmio + PF_WIN_POS(0), 0);
++
++ write32(pmmio + PIPESRC(0), (639 << 16) | 399);
++ write32(pmmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
++ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
++ write32(pmmio + PFIT_CONTROL, 0x0);
++
++ mdelay(1);
++
++ write32(pmmio + FDI_RX_CTL(0), 0x00002040);
++ mdelay(1);
++ write32(pmmio + FDI_RX_CTL(0), 0x80002050);
++ write32(pmmio + FDI_TX_CTL(0), 0x00044000);
++ mdelay(1);
++ write32(pmmio + FDI_TX_CTL(0), 0x80044000);
++ write32(pmmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
++
++ write32(pmmio + VGACNTRL, 0x0);
++ write32(pmmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
++ mdelay(1);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1);
++ write32(pmmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
++ write32(pmmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
++ write32(pmmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
++
++ /* Set up GTT. */
++
++ reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC);
++ uma_size = 0;
++ if (!(reg16 & 2)) {
++ uma_size = decode_igd_memory_size((reg16 >> 4) & 7);
++ printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
++ }
++
++ for (i = 0; i < (uma_size - 256) / 4; i++)
++ {
++ outl((i << 2) | 1, piobase);
++ outl(pphysbase + (i << 12) + 1, piobase + 4);
++ }
++
++ /* Clear interrupts. */
++ write32(pmmio + DEIIR, 0xffffffff);
++ write32(pmmio + SDEIIR, 0xffffffff);
++ write32(pmmio + IIR, 0xffffffff);
++ write32(pmmio + IMR, 0xffffffff);
++ write32(pmmio + EIR, 0xffffffff);
++
++ vga_textmode_init();
++
++ /* Enable screen memory. */
++ vga_sr_write(1, vga_sr_read(1) & ~0x20);
++
++ return 0;
++
++}
++
++/* compare the header of the vga edid header */
++/* if vga is not connected it should have a correct header */
++static int vga_connected(u8 *pmmio) {
++ u8 vga_edid[128];
++ u8 header[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
++ intel_gmbus_read_edid(pmmio + GMBUS0, 2, 0x50, vga_edid, 128);
++ intel_gmbus_stop(pmmio + GMBUS0);
++ for (int i = 0; i < 8; i++) {
++ if (vga_edid[i] != header[i]) {
++ printk(BIOS_DEBUG, "VGA not connected. Using LVDS display\n");
++ return 0;
++ }
++ }
++ printk(BIOS_SPEW, "VGA display connected\n");
++ return 1;
++}
++
+ #endif
+
+ static void gma_func0_init(struct device *dev)
+@@ -423,7 +611,11 @@ static void gma_func0_init(struct device *dev)
+ );
+
+ int err;
+- err = intel_gma_init(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ if (vga_connected(mmiobase))
++ err = intel_gma_init_vga(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ iobase, mmiobase, graphics_base);
++ else
++ err = intel_gma_init_lvds(conf, pci_read_config32(dev, 0x5c) & ~0xf,
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0007-i945-gma.c-generate-fake-VBT.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0007-i945-gma.c-generate-fake-VBT.patch
new file mode 100644
index 00000000..6f0272fd
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/0007-i945-gma.c-generate-fake-VBT.patch
@@ -0,0 +1,43 @@
+From 60cc2c4532f63a40486b7c4e891fb87fb6d4ab7f Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Wed, 7 Sep 2016 22:10:57 +0200
+Subject: [PATCH] i945/gma.c: generate fake VBT
+
+This generates a fake VBT for the Intel i945 graphic device.
+i945 supports both the mobile chipset 945gm (calistoga)
+and the desktop chipset 945gc (lakeport),
+which is why a VBT with a different id string
+needs to be created for each target.
+
+The VBT id string is obtained from the vbios blob in the following way:
+"strings vbios.bin | grep VBT".
+
+Change-Id: I8245b12b16a4426efbe1f584d4163fc257231a98
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..f0944b9 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -433,6 +433,15 @@ static void gma_func0_init(struct device *dev)
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
++ /* Linux relies on VBT for panel info. */
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT CALISTOGA ");
++ }
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT LAKEPORT-G ");
++ }
+ #endif
+ }
+
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/reused.list b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/reused.list
new file mode 100644
index 00000000..5dd5800f
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/macbook21/reused.list
@@ -0,0 +1,2 @@
+/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch
+/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-Enable-brightness-controls-native-graphic.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-Enable-brightness-controls-native-graphic.patch
new file mode 100644
index 00000000..2e3ee65b
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-Enable-brightness-controls-native-graphic.patch
@@ -0,0 +1,36 @@
+From 770021ce66a0fddebb9639c4df0696ecfca45488 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <info@minifree.org>
+Date: Mon, 15 Jun 2015 19:59:46 +0100
+Subject: [PATCH 4/9] lenovo/t60: Enable brightness controls (native graphics)
+
+This makes the Fn Home/End keys work for controlling the
+brightness of the display. Value obtained by reading
+BLC_PWM_CTL when running the VBIOS (option ROM).
+
+On i945 legacy brightness control is enabled by a single
+bit in BLC_PWM_CTL. It's bit 16 or bit 0 (the other one
+reverses polarity). Set the bit to enable brightness
+controls.
+
+Change-Id: I22e261f2ce28ec81cd208a73e6311ec67146eb72
+Signed-off-by: Leah Rowe <info@minifree.org>
+---
+ src/mainboard/lenovo/t60/devicetree.cb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb
+index b28f1ad..9e6ce02 100644
+--- a/src/mainboard/lenovo/t60/devicetree.cb
++++ b/src/mainboard/lenovo/t60/devicetree.cb
+@@ -26,7 +26,7 @@ chip northbridge/intel/i945
+
+ register "gpu_hotplug" = "0x00000220"
+ register "gpu_lvds_use_spread_spectrum_clock" = "1"
+- register "gpu_backlight" = "0x1280128"
++ register "gpu_backlight" = "0x58BF58BE"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_mFCPGA478
+--
+1.9.1
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-add-hda_verb.c.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-add-hda_verb.c.patch
new file mode 100644
index 00000000..0b8e146a
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0001-lenovo-t60-add-hda_verb.c.patch
@@ -0,0 +1,53 @@
+From bbd04909524d7b9fd2e2b4dbd804801bbde66e44 Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Wed, 7 Sep 2016 21:16:21 +0200
+Subject: [PATCH] lenovo/t60: add hda_verb.c
+
+This creates a config for the Lenovo T60 sound card based
+on values taken from vendor bios
+(in /sys/class/sound/hwC0D0/init_pin_configs on linux 3.16).
+The sound card configuration on the vendor bios is the same
+as the one on the Lenovo x60.
+
+It improves the default behavior of the sound card:
+- internal microphone is chosen by default
+- when jack is inserted it is chosen instead of internal speaker
+
+Change-Id: I44e3eaac437fe4ad97ff2b0eb32d36b33222c09b
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/mainboard/lenovo/t60/hda_verb.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/src/mainboard/lenovo/t60/hda_verb.c b/src/mainboard/lenovo/t60/hda_verb.c
+index 072a306..dee3e80 100644
+--- a/src/mainboard/lenovo/t60/hda_verb.c
++++ b/src/mainboard/lenovo/t60/hda_verb.c
+@@ -1,7 +1,22 @@
+ #include <device/azalia_device.h>
+
+-const u32 cim_verb_data[0] = {};
++const u32 cim_verb_data[] = {
++ 0x11d41981, /* Codec Vendor / Device ID: Analog Devices AD1981 */
++ 0x17aa2025, /* Subsystem ID */
++ 0x0000000b, /* Number of 4 dword sets */
+
+-const u32 pc_beep_verbs[0] = {};
++ AZALIA_SUBVENDOR(0x0, 0x17aa2025),
+
++ AZALIA_PIN_CFG(0, 0x05, 0xc3014110),
++ AZALIA_PIN_CFG(0, 0x06, 0x4221401f),
++ AZALIA_PIN_CFG(0, 0x07, 0x591311f0),
++ AZALIA_PIN_CFG(0, 0x08, 0xc3a15020),
++ AZALIA_PIN_CFG(0, 0x09, 0x41813021),
++ AZALIA_PIN_CFG(0, 0x0a, 0x014470f0),
++ AZALIA_PIN_CFG(0, 0x16, 0x59f311f0),
++ AZALIA_PIN_CFG(0, 0x17, 0x59931122),
++ AZALIA_PIN_CFG(0, 0x18, 0x41a19023),
++ AZALIA_PIN_CFG(0, 0x19, 0x9933e12e)
++};
++const u32 pc_beep_verbs[0] = {};
+ AZALIA_ARRAY_SIZES;
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0003-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0003-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
new file mode 100644
index 00000000..86bd6cb0
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0003-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
@@ -0,0 +1,174 @@
+From 34f8cdbc30f1fdf4700c73aad26e0fc159af70ab Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Fri, 2 Sep 2016 22:35:32 +0200
+Subject: [PATCH] i945/gma.c use latest linux code to calculate divisors.
+
+The code to compute n, m1, m2, p1 divisors is not correct in coreboot and
+on some targets hits a working mode at lower refresh rate, which is why
+display is working on some targets.
+This patch also fixes reference frequency.
+
+This patch reuses linux code to correctly compute divisors.
+
+The result is that some previously not working displays (Lenovo T60 with
+1024x786, 1400x1050, 2048x1536)
+
+TESTED on T60 with 1024x786.
+
+Change-Id: I2c7f3bb0024ac005029eaebe3ecdc70c38ac777e
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 82 +++++++++++++++++++---------------------
+ 1 file changed, 38 insertions(+), 44 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..3f0b5b4 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -26,6 +26,8 @@
+ #include <string.h>
+ #include <pc80/vga.h>
+ #include <pc80/vga_io.h>
++#include <commonlib/helpers.h>
++
+
+ #include "i945.h"
+ #include "chip.h"
+@@ -43,7 +45,7 @@
+ #define PGETBL_CTL 0x2020
+ #define PGETBL_ENABLED 0x00000001
+
+-#define BASE_FREQUENCY 120000
++#define BASE_FREQUENCY 100000
+
+ #if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
+
+@@ -85,10 +87,10 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ u8 edid_data[128];
+ unsigned long temp;
+ int hpolarity, vpolarity;
+- u32 candp1, candn;
+- u32 best_delta = 0xffffffff;
++ u32 smallest_err = 0xffffffff;
+ u32 target_frequency;
+ u32 pixel_p1 = 1;
++ u32 pixel_p2;
+ u32 pixel_n = 1;
+ u32 pixel_m1 = 1;
+ u32 pixel_m2 = 1;
+@@ -158,43 +160,37 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PORT_HOTPLUG_EN, conf->gpu_hotplug);
+ write32(pmmio + INSTPM, 0x08000000 | INSTPM_AGPBUSY_DIS);
+
+- target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
+- : (2 * mode->pixel_clock);
+-
+- /* Find suitable divisors. */
+- for (candp1 = 1; candp1 <= 8; candp1++) {
+- for (candn = 5; candn <= 10; candn++) {
+- u32 cur_frequency;
+- u32 m; /* 77 - 131. */
+- u32 denom; /* 35 - 560. */
+- u32 current_delta;
+-
+- denom = candn * candp1 * 7;
+- /* Doesnt overflow for up to
+- 5000000 kHz = 5 GHz. */
+- m = (target_frequency * denom
+- + BASE_FREQUENCY / 2) / BASE_FREQUENCY;
+-
+- if (m < 77 || m > 131)
+- continue;
+-
+- cur_frequency = (BASE_FREQUENCY * m) / denom;
+- if (target_frequency > cur_frequency)
+- current_delta = target_frequency - cur_frequency;
+- else
+- current_delta = cur_frequency - target_frequency;
+-
+- if (best_delta > current_delta) {
+- best_delta = current_delta;
+- pixel_n = candn;
+- pixel_p1 = candp1;
+- pixel_m2 = ((m + 3) % 5) + 7;
+- pixel_m1 = (m - pixel_m2) / 5;
++ pixel_p2 = mode->lvds_dual_channel ? 7 : 14;
++ target_frequency = mode->pixel_clock;
++
++ /* Find suitable divisors, m1, m2, p1, n. */
++ /* refclock * (5 * (m1 + 2) + (m1 + 2)) / (n + 2) / p1 / p2 */
++ /* should be closest to target frequency as possible */
++ u32 candn, candm1, candm2, candp1;
++ for (candm1 = 8; candm1 <= 18; candm1++) {
++ for (candm2 = 3; candm2 <= 7; candm2++) {
++ for (candn = 1; candn <= 6; candn++) {
++ for (candp1 = 1; candp1 <= 8; candp1++) {
++ u32 m = 5 * (candm1 + 2) + (candm2 + 2);
++ u32 p = candp1 * pixel_p2;
++ u32 vco = DIV_ROUND_CLOSEST(BASE_FREQUENCY * m, candn + 2);
++ u32 dot = DIV_ROUND_CLOSEST(vco, p);
++ u32 this_err = ABS(dot - target_frequency);
++ if ((m < 70) || (m > 120))
++ continue;
++ if (this_err < smallest_err) {
++ smallest_err = this_err;
++ pixel_n = candn;
++ pixel_m1 = candm1;
++ pixel_m2 = candm2;
++ pixel_p1 = candp1;
++ }
++ }
+ }
+ }
+ }
+
+- if (best_delta == 0xffffffff) {
++ if (smallest_err == 0xffffffff) {
+ printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
+ return -1;
+ }
+@@ -216,8 +212,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
+ pixel_n, pixel_m1, pixel_m2, pixel_p1);
+ printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
+- BASE_FREQUENCY * (5 * pixel_m1 + pixel_m2) / pixel_n
+- / (pixel_p1 * 7));
++ BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
++ (pixel_n + 2) / (pixel_p1 * pixel_p2));
+
+ #if !IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
+ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
+@@ -242,8 +238,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PP_CONTROL, PANEL_UNLOCK_REGS
+ | (read32(pmmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
+ write32(pmmio + FP0(1),
+- ((pixel_n - 2) << 16)
+- | ((pixel_m1 - 2) << 8) | pixel_m2);
++ (pixel_n << 16)
++ | (pixel_m1 << 8) | pixel_m2);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+ DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
+@@ -252,8 +248,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (conf->gpu_lvds_use_spread_spectrum_clock
+ ? DPLL_INTEGRATED_CLOCK_VLV | DPLL_INTEGRATED_CRI_CLK_VLV
+ : 0)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+@@ -261,8 +256,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
+ : DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | ((conf->gpu_lvds_use_spread_spectrum_clock ? 3 : 0) << 13)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + HTOTAL(1),
+ ((hactive + right_border + hblank - 1) << 16)
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
new file mode 100644
index 00000000..884b2829
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
@@ -0,0 +1,174 @@
+From 34f8cdbc30f1fdf4700c73aad26e0fc159af70ab Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Fri, 2 Sep 2016 22:35:32 +0200
+Subject: [PATCH 1/2] i945/gma.c use latest linux code to calculate divisors.
+
+The code to compute n, m1, m2, p1 divisors is not correct in coreboot and
+on some targets hits a working mode at lower refresh rate, which is why
+display is working on some targets.
+This patch also fixes reference frequency.
+
+This patch reuses linux code to correctly compute divisors.
+
+The result is that some previously not working displays (Lenovo T60 with
+1024x786, 1400x1050, 2048x1536)
+
+TESTED on T60 with 1024x786.
+
+Change-Id: I2c7f3bb0024ac005029eaebe3ecdc70c38ac777e
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 82 +++++++++++++++++++---------------------
+ 1 file changed, 38 insertions(+), 44 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..3f0b5b4 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -26,6 +26,8 @@
+ #include <string.h>
+ #include <pc80/vga.h>
+ #include <pc80/vga_io.h>
++#include <commonlib/helpers.h>
++
+
+ #include "i945.h"
+ #include "chip.h"
+@@ -43,7 +45,7 @@
+ #define PGETBL_CTL 0x2020
+ #define PGETBL_ENABLED 0x00000001
+
+-#define BASE_FREQUENCY 120000
++#define BASE_FREQUENCY 100000
+
+ #if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
+
+@@ -85,10 +87,10 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ u8 edid_data[128];
+ unsigned long temp;
+ int hpolarity, vpolarity;
+- u32 candp1, candn;
+- u32 best_delta = 0xffffffff;
++ u32 smallest_err = 0xffffffff;
+ u32 target_frequency;
+ u32 pixel_p1 = 1;
++ u32 pixel_p2;
+ u32 pixel_n = 1;
+ u32 pixel_m1 = 1;
+ u32 pixel_m2 = 1;
+@@ -158,43 +160,37 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PORT_HOTPLUG_EN, conf->gpu_hotplug);
+ write32(pmmio + INSTPM, 0x08000000 | INSTPM_AGPBUSY_DIS);
+
+- target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
+- : (2 * mode->pixel_clock);
+-
+- /* Find suitable divisors. */
+- for (candp1 = 1; candp1 <= 8; candp1++) {
+- for (candn = 5; candn <= 10; candn++) {
+- u32 cur_frequency;
+- u32 m; /* 77 - 131. */
+- u32 denom; /* 35 - 560. */
+- u32 current_delta;
+-
+- denom = candn * candp1 * 7;
+- /* Doesnt overflow for up to
+- 5000000 kHz = 5 GHz. */
+- m = (target_frequency * denom
+- + BASE_FREQUENCY / 2) / BASE_FREQUENCY;
+-
+- if (m < 77 || m > 131)
+- continue;
+-
+- cur_frequency = (BASE_FREQUENCY * m) / denom;
+- if (target_frequency > cur_frequency)
+- current_delta = target_frequency - cur_frequency;
+- else
+- current_delta = cur_frequency - target_frequency;
+-
+- if (best_delta > current_delta) {
+- best_delta = current_delta;
+- pixel_n = candn;
+- pixel_p1 = candp1;
+- pixel_m2 = ((m + 3) % 5) + 7;
+- pixel_m1 = (m - pixel_m2) / 5;
++ pixel_p2 = mode->lvds_dual_channel ? 7 : 14;
++ target_frequency = mode->pixel_clock;
++
++ /* Find suitable divisors, m1, m2, p1, n. */
++ /* refclock * (5 * (m1 + 2) + (m1 + 2)) / (n + 2) / p1 / p2 */
++ /* should be closest to target frequency as possible */
++ u32 candn, candm1, candm2, candp1;
++ for (candm1 = 8; candm1 <= 18; candm1++) {
++ for (candm2 = 3; candm2 <= 7; candm2++) {
++ for (candn = 1; candn <= 6; candn++) {
++ for (candp1 = 1; candp1 <= 8; candp1++) {
++ u32 m = 5 * (candm1 + 2) + (candm2 + 2);
++ u32 p = candp1 * pixel_p2;
++ u32 vco = DIV_ROUND_CLOSEST(BASE_FREQUENCY * m, candn + 2);
++ u32 dot = DIV_ROUND_CLOSEST(vco, p);
++ u32 this_err = ABS(dot - target_frequency);
++ if ((m < 70) || (m > 120))
++ continue;
++ if (this_err < smallest_err) {
++ smallest_err = this_err;
++ pixel_n = candn;
++ pixel_m1 = candm1;
++ pixel_m2 = candm2;
++ pixel_p1 = candp1;
++ }
++ }
+ }
+ }
+ }
+
+- if (best_delta == 0xffffffff) {
++ if (smallest_err == 0xffffffff) {
+ printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
+ return -1;
+ }
+@@ -216,8 +212,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
+ pixel_n, pixel_m1, pixel_m2, pixel_p1);
+ printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
+- BASE_FREQUENCY * (5 * pixel_m1 + pixel_m2) / pixel_n
+- / (pixel_p1 * 7));
++ BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
++ (pixel_n + 2) / (pixel_p1 * pixel_p2));
+
+ #if !IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
+ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
+@@ -242,8 +238,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PP_CONTROL, PANEL_UNLOCK_REGS
+ | (read32(pmmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
+ write32(pmmio + FP0(1),
+- ((pixel_n - 2) << 16)
+- | ((pixel_m1 - 2) << 8) | pixel_m2);
++ (pixel_n << 16)
++ | (pixel_m1 << 8) | pixel_m2);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+ DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
+@@ -252,8 +248,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (conf->gpu_lvds_use_spread_spectrum_clock
+ ? DPLL_INTEGRATED_CLOCK_VLV | DPLL_INTEGRATED_CRI_CLK_VLV
+ : 0)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+@@ -261,8 +256,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
+ : DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | ((conf->gpu_lvds_use_spread_spectrum_clock ? 3 : 0) << 13)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + HTOTAL(1),
+ ((hactive + right_border + hblank - 1) << 16)
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0006-i945-gma.c-add-native-VGA-init.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0006-i945-gma.c-add-native-VGA-init.patch
new file mode 100644
index 00000000..26eed5b4
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0006-i945-gma.c-add-native-VGA-init.patch
@@ -0,0 +1,241 @@
+From 7ed0951bcf59dfd8b1893232b674455ff8f03f83 Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Mon, 5 Sep 2016 22:46:11 +0200
+Subject: [PATCH 2/2] i945/gma.c: add native VGA init
+
+This reuses the Intel Pineview native graphic initialization
+to have output on the VGA connector of i945 devices.
+
+The behavior is the same as with the vendor VBIOS BLOB.
+It uses the external VGA display if it is connected.
+
+Change-Id: I7eaee87d16df2e5c9ebeaaff01d36ec1aa4ea495
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 196 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 194 insertions(+), 2 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 3f0b5b4..ac19d5a 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -78,7 +78,7 @@ static int gtt_setup(void *mmiobase)
+ return 0;
+ }
+
+-static int intel_gma_init(struct northbridge_intel_i945_config *conf,
++static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf,
+ unsigned int pphysbase, unsigned int piobase,
+ void *pmmio, unsigned int pgfx)
+ {
+@@ -382,6 +382,194 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ #endif
+ return 0;
+ }
++
++static int intel_gma_init_vga(struct northbridge_intel_i945_config *conf,
++ unsigned int pphysbase, unsigned int piobase,
++ void *pmmio, unsigned int pgfx)
++{
++ int i;
++ u32 hactive, vactive;
++ u16 reg16;
++ u32 uma_size;
++
++ printk(BIOS_SPEW, "pmmio %x addrport %x physbase %x\n",
++ (u32)pmmio, piobase, pphysbase);
++
++ gtt_setup(pmmio);
++
++ /* Disable VGA. */
++ write32(pmmio + VGACNTRL, VGA_DISP_DISABLE);
++
++ /* Disable pipes. */
++ write32(pmmio + PIPECONF(0), 0);
++ write32(pmmio + PIPECONF(1), 0);
++
++ write32(pmmio + INSTPM, 0x800);
++
++ vga_gr_write(0x18, 0);
++
++ write32(pmmio + VGA0, 0x200074);
++ write32(pmmio + VGA1, 0x200074);
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
++ write32(pmmio + DSPCLK_GATE_D, 0);
++ write32(pmmio + FW_BLC, 0x03060106);
++ write32(pmmio + FW_BLC2, 0x00000306);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + 0x7041c, 0x0);
++
++ write32(pmmio + DPLL_MD(0), 0x3);
++ write32(pmmio + DPLL_MD(1), 0x3);
++ write32(pmmio + DSPCNTR(1), 0x1000000);
++ write32(pmmio + PIPESRC(1), 0x027f01df);
++
++ vga_misc_write(0x67);
++ const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
++ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
++ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
++ 0xff
++ };
++ vga_cr_write(0x11, 0);
++
++ for (i = 0; i <= 0x18; i++)
++ vga_cr_write(i, cr[i]);
++
++ // Disable screen memory to prevent garbage from appearing.
++ vga_sr_write(1, vga_sr_read(1) | 0x20);
++ hactive = 640;
++ vactive = 400;
++
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + HTOTAL(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HBLANK(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HSYNC(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++
++ write32(pmmio + VTOTAL(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VBLANK(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VSYNC(0),
++ ((vactive - 1) << 16)
++ | (vactive - 1));
++
++ write32(pmmio + PF_WIN_POS(0), 0);
++
++ write32(pmmio + PIPESRC(0), (639 << 16) | 399);
++ write32(pmmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
++ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
++ write32(pmmio + PFIT_CONTROL, 0x0);
++
++ mdelay(1);
++
++ write32(pmmio + FDI_RX_CTL(0), 0x00002040);
++ mdelay(1);
++ write32(pmmio + FDI_RX_CTL(0), 0x80002050);
++ write32(pmmio + FDI_TX_CTL(0), 0x00044000);
++ mdelay(1);
++ write32(pmmio + FDI_TX_CTL(0), 0x80044000);
++ write32(pmmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
++
++ write32(pmmio + VGACNTRL, 0x0);
++ write32(pmmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
++ mdelay(1);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1);
++ write32(pmmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
++ write32(pmmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
++ write32(pmmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
++
++ /* Set up GTT. */
++
++ reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC);
++ uma_size = 0;
++ if (!(reg16 & 2)) {
++ uma_size = decode_igd_memory_size((reg16 >> 4) & 7);
++ printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
++ }
++
++ for (i = 0; i < (uma_size - 256) / 4; i++)
++ {
++ outl((i << 2) | 1, piobase);
++ outl(pphysbase + (i << 12) + 1, piobase + 4);
++ }
++
++ /* Clear interrupts. */
++ write32(pmmio + DEIIR, 0xffffffff);
++ write32(pmmio + SDEIIR, 0xffffffff);
++ write32(pmmio + IIR, 0xffffffff);
++ write32(pmmio + IMR, 0xffffffff);
++ write32(pmmio + EIR, 0xffffffff);
++
++ vga_textmode_init();
++
++ /* Enable screen memory. */
++ vga_sr_write(1, vga_sr_read(1) & ~0x20);
++
++ return 0;
++
++}
++
++/* compare the header of the vga edid header */
++/* if vga is not connected it should have a correct header */
++static int vga_connected(u8 *pmmio) {
++ u8 vga_edid[128];
++ u8 header[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
++ intel_gmbus_read_edid(pmmio + GMBUS0, 2, 0x50, vga_edid, 128);
++ intel_gmbus_stop(pmmio + GMBUS0);
++ for (int i = 0; i < 8; i++) {
++ if (vga_edid[i] != header[i]) {
++ printk(BIOS_DEBUG, "VGA not connected. Using LVDS display\n");
++ return 0;
++ }
++ }
++ printk(BIOS_SPEW, "VGA display connected\n");
++ return 1;
++}
++
+ #endif
+
+ static void gma_func0_init(struct device *dev)
+@@ -423,7 +611,11 @@ static void gma_func0_init(struct device *dev)
+ );
+
+ int err;
+- err = intel_gma_init(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ if (vga_connected(mmiobase))
++ err = intel_gma_init_vga(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ iobase, mmiobase, graphics_base);
++ else
++ err = intel_gma_init_lvds(conf, pci_read_config32(dev, 0x5c) & ~0xf,
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0007-i945-gma.c-generate-fake-VBT.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0007-i945-gma.c-generate-fake-VBT.patch
new file mode 100644
index 00000000..6f0272fd
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/0007-i945-gma.c-generate-fake-VBT.patch
@@ -0,0 +1,43 @@
+From 60cc2c4532f63a40486b7c4e891fb87fb6d4ab7f Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Wed, 7 Sep 2016 22:10:57 +0200
+Subject: [PATCH] i945/gma.c: generate fake VBT
+
+This generates a fake VBT for the Intel i945 graphic device.
+i945 supports both the mobile chipset 945gm (calistoga)
+and the desktop chipset 945gc (lakeport),
+which is why a VBT with a different id string
+needs to be created for each target.
+
+The VBT id string is obtained from the vbios blob in the following way:
+"strings vbios.bin | grep VBT".
+
+Change-Id: I8245b12b16a4426efbe1f584d4163fc257231a98
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..f0944b9 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -433,6 +433,15 @@ static void gma_func0_init(struct device *dev)
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
++ /* Linux relies on VBT for panel info. */
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT CALISTOGA ");
++ }
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT LAKEPORT-G ");
++ }
+ #endif
+ }
+
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/INFO b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/INFO
new file mode 100644
index 00000000..cb543aae
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/INFO
@@ -0,0 +1,3 @@
+printf "lenovo/t60: Enable brightness controls (native graphics)\n"
+git am "../resources/libreboot/patch/misc/0004-lenovo-t60-Enable-brightness-controls-native-graphic.patch"
+# git fetch http://review.coreboot.org/coreboot refs/changes/52/10552/2 && git cherry-pick FETCH_HEAD
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/reused.list b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/reused.list
new file mode 100644
index 00000000..157e1cf6
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/t60/reused.list
@@ -0,0 +1,3 @@
+/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch
+/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch
+/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch
new file mode 100644
index 00000000..6f8b5307
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch
@@ -0,0 +1,88 @@
+From 1024b5e6c476dcc195dca742746735277f63236b Mon Sep 17 00:00:00 2001
+From: Leah Rowe <info@minifree.org>
+Date: Mon, 13 Oct 2014 00:14:53 +0100
+Subject: [PATCH 5/9] NOTFORMERGE: ec/lenovo/h8:
+ wlan/trackpoint/touchpad/bluetooth/wwan
+
+Permanently enable them.
+
+Change-Id: Ic76ab9ab9c865f30312378e18af58bece6c3260a
+Signed-off-by: Leah Rowe <info@minifree.org>
+---
+ src/ec/lenovo/h8/h8.c | 21 +++++++++++----------
+ src/ec/lenovo/pmh7/pmh7.c | 11 ++++-------
+ 2 files changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c
+index 2cafc88..a6cb6b6 100644
+--- a/src/ec/lenovo/h8/h8.c
++++ b/src/ec/lenovo/h8/h8.c
+@@ -255,9 +255,11 @@ static void h8_enable(struct device *dev)
+
+ ec_write(H8_FAN_CONTROL, H8_FAN_CONTROL_AUTO);
+
+- if (get_option(&val, "wlan") != CB_SUCCESS)
+- val = 1;
+- h8_wlan_enable(val);
++ // Permanently enable wifi
++ // Intel wifi could be a security risk because it uses firmware. Wlan chip has DMA
++ // and could leak data over a side-channel. Using another manufacturer is recommended.
++ // see http://libreboot.org/docs/index.html#recommended_wifi
++ h8_wlan_enable(1);
+
+ h8_trackpoint_enable(1);
+ h8_usb_power_enable(1);
+@@ -265,14 +267,13 @@ static void h8_enable(struct device *dev)
+ if (get_option(&val, "volume") == CB_SUCCESS)
+ ec_write(H8_VOLUME_CONTROL, val);
+
+- if (get_option(&val, "bluetooth") != CB_SUCCESS)
+- val = 1;
+- h8_bluetooth_enable(val);
+-
+- if (get_option(&val, "wwan") != CB_SUCCESS)
+- val = 1;
++ // Permanently enable bluetooth.
++ // NOTE: bluetooth is a potential security risk. Physical removal of the bluetooth module is recommended.
++ h8_bluetooth_enable(1);
+
+- h8_wwan_enable(val);
++ // Permanently enable wwan.
++ // NOTE: wwan is a security risk (remove access plus DMA). Physical removal of both the wwan and sim card is recommended.
++ h8_wwan_enable(1);
+
+ if (conf->has_uwb) {
+ if (get_option(&val, "uwb") != CB_SUCCESS)
+diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c
+index cc6e891..38aef16 100644
+--- a/src/ec/lenovo/pmh7/pmh7.c
++++ b/src/ec/lenovo/pmh7/pmh7.c
+@@ -106,7 +106,6 @@ static void enable_dev(struct device *dev)
+ {
+ struct ec_lenovo_pmh7_config *conf = dev->chip_info;
+ struct resource *resource;
+- u8 val;
+
+ resource = new_resource(dev, EC_LENOVO_PMH7_INDEX);
+ resource->flags = IORESOURCE_IO | IORESOURCE_FIXED;
+@@ -118,13 +117,11 @@ static void enable_dev(struct device *dev)
+ pmh7_backlight_enable(conf->backlight_enable);
+ pmh7_dock_event_enable(conf->dock_event_enable);
+
+- if (get_option(&val, "touchpad") != CB_SUCCESS)
+- val = 1;
+- pmh7_touchpad_enable(val);
++ // Permanently enable touchpad
++ pmh7_touchpad_enable(1);
+
+- if (get_option(&val, "trackpoint") != CB_SUCCESS)
+- val = 1;
+- pmh7_trackpoint_enable(val);
++ // Permanently enable trackpoint
++ pmh7_trackpoint_enable(1);
+ }
+
+ struct chip_operations ec_lenovo_pmh7_ops = {
+--
+1.9.1
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch
new file mode 100644
index 00000000..ce1d37c0
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-i945-Enable-changing-VRAM-size.patch
@@ -0,0 +1,158 @@
+From 44b3d02a49bc25dc8e9119a11bd948db2c37a931 Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Sun, 15 May 2016 02:17:12 +0200
+Subject: [PATCH] i945: Enable changing VRAM size
+
+On i945 the vram size was the default 8mb. It was also possible
+to set it 1mb or 0mb hardcoding the GGC register in early_init.c
+
+The intel documentation on i945 only documents those three options.
+They are set using 3 bits. The documententation also makes mention
+of 4mb, 16mb, 32mb, 48mb, 64mb but not how to set it.
+
+The other non documented (straight forward) bit combinations allows
+to change the VRAM size to those other states.
+
+Change-Id: I5e510e81322a4c8315c01b7963ac4b5f7f58a17e
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+
+diff --git a/src/northbridge/intel/i945/Kconfig b/src/northbridge/intel/i945/Kconfig
+index 6e8d35b..484ed78 100644
+--- a/src/northbridge/intel/i945/Kconfig
++++ b/src/northbridge/intel/i945/Kconfig
+@@ -72,3 +72,56 @@ config CHECK_SLFRCS_ON_RESUME
+ effectively making it impossible to resume.
+
+ endif
++
++config VRAM_CHOICE
++ bool
++choice
++ prompt "VRAM Size"
++ depends on NORTHBRIDGE_INTEL_I945
++ default VRAM_SIZE_8MB
++ help
++ Set the size of vram that the integrated graphic device can use
++ for a framebuffer.
++
++config VRAM_SIZE_1MB
++ bool "1 MB"
++ help
++ Set VRAM size to 1MB.
++config VRAM_SIZE_4MB
++ bool "4 MB"
++ help
++ Set VRAM size to 4MB.
++config VRAM_SIZE_8MB
++ bool "8 MB"
++ help
++ Set VRAM size to 8MB.
++config VRAM_SIZE_16MB
++ bool "16 MB"
++ help
++ Set VRAM size to 16MB.
++config VRAM_SIZE_32MB
++ bool "32 MB"
++ help
++ Set VRAM size to 32MB.
++config VRAM_SIZE_48MB
++ bool "48 MB"
++ help
++ Set VRAM size to 48MB.
++config VRAM_SIZE_64MB
++ bool "64 MB"
++ help
++ Set VRAM size to 64MB.
++
++endchoice
++
++config VRAM_SIZE
++ hex
++ default 0x10 if VRAM_SIZE_1MB
++ default 0x20 if VRAM_SIZE_4MB
++ default 0x30 if VRAM_SIZE_8MB
++ default 0x40 if VRAM_SIZE_16MB
++ default 0x50 if VRAM_SIZE_32MB
++ default 0x60 if VRAM_SIZE_48MB
++ default 0x70 if VRAM_SIZE_64MB
++ help
++ map the vram sizes to an integer.
+diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c
+index 475e88a..bd062ad 100644
+--- a/src/northbridge/intel/i945/early_init.c
++++ b/src/northbridge/intel/i945/early_init.c
+@@ -177,11 +177,8 @@ static void i945_setup_bars(void)
+ pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR, (uintptr_t)DEFAULT_DMIBAR | 1);
+ pci_write_config32(PCI_DEV(0, 0x00, 0), X60BAR, DEFAULT_X60BAR | 1);
+
+- /* Hardware default is 8MB UMA. If someone wants to make this a
+- * CMOS or compile time option, send a patch.
+- * pci_write_config16(PCI_DEV(0, 0x00, 0), GGC, 0x30);
+- */
+-
++ /* Sets up VRAM size from the build option VRAM_SIZE */
++ pci_write_config16(PCI_DEV(0, 0x00, 0), GGC, CONFIG_VRAM_SIZE);
+ /* Set C0000-FFFFF to access RAM on both reads and writes */
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM0, 0x30);
+ pci_write_config8(PCI_DEV(0, 0x00, 0), PAM1, 0x33);
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index df13ef4..f853cc8 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -359,9 +359,24 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ case 1:
+ uma_size = 1024;
+ break;
++ case 2:
++ uma_size = 4096;
++ break;
+ case 3:
+ uma_size = 8192;
+ break;
++ case 4:
++ uma_size = 16384;
++ break;
++ case 5:
++ uma_size = 32768;
++ break;
++ case 6:
++ uma_size = 49152;
++ break;
++ case 7:
++ uma_size = 65536;
++ break;
+ }
+
+ printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
+diff --git a/src/northbridge/intel/i945/northbridge.c b/src/northbridge/intel/i945/northbridge.c
+index 514f88c..4be9827 100644
+--- a/src/northbridge/intel/i945/northbridge.c
++++ b/src/northbridge/intel/i945/northbridge.c
+@@ -112,9 +112,24 @@ static void pci_domain_set_resources(device_t dev)
+ case 1:
+ uma_size = 1024;
+ break;
++ case 2:
++ uma_size = 4096;
++ break;
+ case 3:
+ uma_size = 8192;
+ break;
++ case 4:
++ uma_size = 16384;
++ break;
++ case 5:
++ uma_size = 32768;
++ break;
++ case 6:
++ uma_size = 49152;
++ break;
++ case 7:
++ uma_size = 65536;
++ break;
+ }
+
+ printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
+--
+2.8.2
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-lenovo-x60-add-hda_verb.c.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-lenovo-x60-add-hda_verb.c.patch
new file mode 100644
index 00000000..80eda28b
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0001-lenovo-x60-add-hda_verb.c.patch
@@ -0,0 +1,65 @@
+From 4f3452fc544d4e799445c3271b1022496932473c Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Fri, 3 Jun 2016 18:37:38 +0200
+Subject: [PATCH] lenovo/x60: add hda_verb.c
+
+This creates a config for the x60 audio based
+on values taken from vendor bios.
+
+What is improved:
+- internal microphone is chosen by default
+- when jack is inserted it chosen instead of internal speaker
+
+Before this had to be done manually.
+
+Change-Id: Id3b700fd84905a72cc1f69e7d8bfa6145f231756
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+
+diff --git a/src/mainboard/lenovo/x60/hda_verb.c b/src/mainboard/lenovo/x60/hda_verb.c
+index 072a306..c4b1f3a 100644
+--- a/src/mainboard/lenovo/x60/hda_verb.c
++++ b/src/mainboard/lenovo/x60/hda_verb.c
+@@ -1,7 +1,38 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2016 Arthur Heymans <arthur@aheymans.xyz>
++ *
++ * 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 <device/azalia_device.h>
+
+-const u32 cim_verb_data[0] = {};
++const u32 cim_verb_data[] = {
++ 0x11d41981, /* Codec Vendor / Device ID: Analog Devices AD1981 */
++ 0x17aa2025, /* Subsystem ID */
++ 0x0000000b, /* Number of 4 dword sets */
+
+-const u32 pc_beep_verbs[0] = {};
++ AZALIA_SUBVENDOR(0x0, 0x17aa2025),
+
++ AZALIA_PIN_CFG(0, 0x05, 0xc3014110),
++ AZALIA_PIN_CFG(0, 0x06, 0x4221401f),
++ AZALIA_PIN_CFG(0, 0x07, 0x591311f0),
++ AZALIA_PIN_CFG(0, 0x08, 0xc3a15020),
++ AZALIA_PIN_CFG(0, 0x09, 0x41813021),
++ AZALIA_PIN_CFG(0, 0x0a, 0x014470f0),
++ AZALIA_PIN_CFG(0, 0x16, 0x59f311f0),
++ AZALIA_PIN_CFG(0, 0x17, 0x59931122),
++ AZALIA_PIN_CFG(0, 0x18, 0x41a19023),
++ AZALIA_PIN_CFG(0, 0x19, 0x9933e12e)
++};
++const u32 pc_beep_verbs[0] = {};
+ AZALIA_ARRAY_SIZES;
+--
+2.8.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0002-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0002-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch
new file mode 100644
index 00000000..7470dd60
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0002-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch
@@ -0,0 +1,31 @@
+From e4b5b65c93122126344771f2042f8d7a3468be19 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <info@minifree.org>
+Date: Mon, 22 Jun 2015 17:37:06 +0100
+Subject: [PATCH 3/9] lenovo/x60: use correct BLC_PWM_CTL value
+
+Bit 16 in BLC_PWM_CTL enables brightness controls, but the
+current value is generic. Use the proper value, obtained
+by reading BLC_PWM_CTL while running the VBIOS.
+
+Change-Id: Ib273359e1c285b405a9bb26fc217c2f7e255b99f
+Signed-off-by: Leah Rowe <info@minifree.org>
+---
+ src/mainboard/lenovo/x60/devicetree.cb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb
+index b4d1144..4d62116 100644
+--- a/src/mainboard/lenovo/x60/devicetree.cb
++++ b/src/mainboard/lenovo/x60/devicetree.cb
+@@ -26,7 +26,7 @@ chip northbridge/intel/i945
+
+ register "gpu_hotplug" = "0x00000220"
+ register "gpu_lvds_use_spread_spectrum_clock" = "1"
+- register "gpu_backlight" = "0x1290128"
++ register "gpu_backlight" = "0x879F879E"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_mFCPGA478
+--
+1.9.1
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch
new file mode 100644
index 00000000..14f809a9
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0004-model_6ex-enable-C2E-C4E-dynamic-lvl-2-cache.patch
@@ -0,0 +1,50 @@
+From 483bbb3ec7965ca2416fda9e11687bcd655d078d Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Tue, 31 May 2016 16:51:59 +0200
+Subject: [PATCH] model_6ex: enable C2E, C4E, dynamic lvl 2 cache.
+
+Change-Id: Ie538d2145640c7b50ac0a0fa432d98ae2c4be060
+
+diff --git a/src/cpu/intel/model_6ex/model_6ex_init.c b/src/cpu/intel/model_6ex/model_6ex_init.c
+index 6fa6d3a..8ff276a 100644
+--- a/src/cpu/intel/model_6ex/model_6ex_init.c
++++ b/src/cpu/intel/model_6ex/model_6ex_init.c
+@@ -67,9 +67,10 @@ static void configure_c_states(void)
+
+ msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL);
+ msr.lo |= (1 << 15); // config lock until next reset.
++ msr.lo |= (1 << 14); // Deeper Sleep
+ msr.lo |= (1 << 10); // Enable I/O MWAIT redirection for C-States
+ msr.lo &= ~(1 << 9); // Issue a single stop grant cycle upon stpclk
+- // TODO Do we want Deep C4 and Dynamic L2 shrinking?
++ msr.lo |= (1 << 3); // Dynamic L2
+
+ /* Number of supported C-States */
+ msr.lo &= ~7;
+@@ -94,16 +95,20 @@ static void configure_misc(void)
+ msr_t msr;
+
+ msr = rdmsr(IA32_MISC_ENABLE);
+- msr.lo |= (1 << 3); /* TM1 enable */
++ msr.lo |= (1 << 3); /* TM1 enable */
+ msr.lo |= (1 << 13); /* TM2 enable */
+ msr.lo |= (1 << 17); /* Bidirectional PROCHOT# */
+
+ msr.lo |= (1 << 10); /* FERR# multiplexing */
+
+- // TODO: Only if IA32_PLATFORM_ID[17] = 0 and IA32_PLATFORM_ID[50] = 1
+ msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
++ /* Enable C2E */
++ msr.lo |= (1 << 26);
++
++ /* Enable C4E */
++ msr.hi |= (1 << (32 - 32)); // C4E
++ msr.hi |= (1 << (33 - 32)); // Hard C4E
+
+- // TODO Do we want Deep C4 and Dynamic L2 shrinking?
+ wrmsr(IA32_MISC_ENABLE, msr);
+
+ msr.lo |= (1 << 20); /* Lock Enhanced SpeedStep Enable */
+--
+2.8.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
new file mode 100644
index 00000000..884b2829
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0005-i945-gma.c-use-latest-linux-code-to-calculate-diviso.patch
@@ -0,0 +1,174 @@
+From 34f8cdbc30f1fdf4700c73aad26e0fc159af70ab Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Fri, 2 Sep 2016 22:35:32 +0200
+Subject: [PATCH 1/2] i945/gma.c use latest linux code to calculate divisors.
+
+The code to compute n, m1, m2, p1 divisors is not correct in coreboot and
+on some targets hits a working mode at lower refresh rate, which is why
+display is working on some targets.
+This patch also fixes reference frequency.
+
+This patch reuses linux code to correctly compute divisors.
+
+The result is that some previously not working displays (Lenovo T60 with
+1024x786, 1400x1050, 2048x1536)
+
+TESTED on T60 with 1024x786.
+
+Change-Id: I2c7f3bb0024ac005029eaebe3ecdc70c38ac777e
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 82 +++++++++++++++++++---------------------
+ 1 file changed, 38 insertions(+), 44 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..3f0b5b4 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -26,6 +26,8 @@
+ #include <string.h>
+ #include <pc80/vga.h>
+ #include <pc80/vga_io.h>
++#include <commonlib/helpers.h>
++
+
+ #include "i945.h"
+ #include "chip.h"
+@@ -43,7 +45,7 @@
+ #define PGETBL_CTL 0x2020
+ #define PGETBL_ENABLED 0x00000001
+
+-#define BASE_FREQUENCY 120000
++#define BASE_FREQUENCY 100000
+
+ #if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT
+
+@@ -85,10 +87,10 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ u8 edid_data[128];
+ unsigned long temp;
+ int hpolarity, vpolarity;
+- u32 candp1, candn;
+- u32 best_delta = 0xffffffff;
++ u32 smallest_err = 0xffffffff;
+ u32 target_frequency;
+ u32 pixel_p1 = 1;
++ u32 pixel_p2;
+ u32 pixel_n = 1;
+ u32 pixel_m1 = 1;
+ u32 pixel_m2 = 1;
+@@ -158,43 +160,37 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PORT_HOTPLUG_EN, conf->gpu_hotplug);
+ write32(pmmio + INSTPM, 0x08000000 | INSTPM_AGPBUSY_DIS);
+
+- target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
+- : (2 * mode->pixel_clock);
+-
+- /* Find suitable divisors. */
+- for (candp1 = 1; candp1 <= 8; candp1++) {
+- for (candn = 5; candn <= 10; candn++) {
+- u32 cur_frequency;
+- u32 m; /* 77 - 131. */
+- u32 denom; /* 35 - 560. */
+- u32 current_delta;
+-
+- denom = candn * candp1 * 7;
+- /* Doesnt overflow for up to
+- 5000000 kHz = 5 GHz. */
+- m = (target_frequency * denom
+- + BASE_FREQUENCY / 2) / BASE_FREQUENCY;
+-
+- if (m < 77 || m > 131)
+- continue;
+-
+- cur_frequency = (BASE_FREQUENCY * m) / denom;
+- if (target_frequency > cur_frequency)
+- current_delta = target_frequency - cur_frequency;
+- else
+- current_delta = cur_frequency - target_frequency;
+-
+- if (best_delta > current_delta) {
+- best_delta = current_delta;
+- pixel_n = candn;
+- pixel_p1 = candp1;
+- pixel_m2 = ((m + 3) % 5) + 7;
+- pixel_m1 = (m - pixel_m2) / 5;
++ pixel_p2 = mode->lvds_dual_channel ? 7 : 14;
++ target_frequency = mode->pixel_clock;
++
++ /* Find suitable divisors, m1, m2, p1, n. */
++ /* refclock * (5 * (m1 + 2) + (m1 + 2)) / (n + 2) / p1 / p2 */
++ /* should be closest to target frequency as possible */
++ u32 candn, candm1, candm2, candp1;
++ for (candm1 = 8; candm1 <= 18; candm1++) {
++ for (candm2 = 3; candm2 <= 7; candm2++) {
++ for (candn = 1; candn <= 6; candn++) {
++ for (candp1 = 1; candp1 <= 8; candp1++) {
++ u32 m = 5 * (candm1 + 2) + (candm2 + 2);
++ u32 p = candp1 * pixel_p2;
++ u32 vco = DIV_ROUND_CLOSEST(BASE_FREQUENCY * m, candn + 2);
++ u32 dot = DIV_ROUND_CLOSEST(vco, p);
++ u32 this_err = ABS(dot - target_frequency);
++ if ((m < 70) || (m > 120))
++ continue;
++ if (this_err < smallest_err) {
++ smallest_err = this_err;
++ pixel_n = candn;
++ pixel_m1 = candm1;
++ pixel_m2 = candm2;
++ pixel_p1 = candp1;
++ }
++ }
+ }
+ }
+ }
+
+- if (best_delta == 0xffffffff) {
++ if (smallest_err == 0xffffffff) {
+ printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
+ return -1;
+ }
+@@ -216,8 +212,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
+ pixel_n, pixel_m1, pixel_m2, pixel_p1);
+ printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
+- BASE_FREQUENCY * (5 * pixel_m1 + pixel_m2) / pixel_n
+- / (pixel_p1 * 7));
++ BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
++ (pixel_n + 2) / (pixel_p1 * pixel_p2));
+
+ #if !IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)
+ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
+@@ -242,8 +238,8 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ write32(pmmio + PP_CONTROL, PANEL_UNLOCK_REGS
+ | (read32(pmmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
+ write32(pmmio + FP0(1),
+- ((pixel_n - 2) << 16)
+- | ((pixel_m1 - 2) << 8) | pixel_m2);
++ (pixel_n << 16)
++ | (pixel_m1 << 8) | pixel_m2);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+ DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
+@@ -252,8 +248,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (conf->gpu_lvds_use_spread_spectrum_clock
+ ? DPLL_INTEGRATED_CLOCK_VLV | DPLL_INTEGRATED_CRI_CLK_VLV
+ : 0)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + DPLL(1),
+ DPLL_VGA_MODE_DIS |
+@@ -261,8 +256,7 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ | (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
+ : DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | ((conf->gpu_lvds_use_spread_spectrum_clock ? 3 : 0) << 13)
+- | (pixel_p1 << 16)
+- | (pixel_p1));
++ | (0x10000 << pixel_p1));
+ mdelay(1);
+ write32(pmmio + HTOTAL(1),
+ ((hactive + right_border + hblank - 1) << 16)
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0006-i945-gma.c-add-native-VGA-init.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0006-i945-gma.c-add-native-VGA-init.patch
new file mode 100644
index 00000000..26eed5b4
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0006-i945-gma.c-add-native-VGA-init.patch
@@ -0,0 +1,241 @@
+From 7ed0951bcf59dfd8b1893232b674455ff8f03f83 Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Mon, 5 Sep 2016 22:46:11 +0200
+Subject: [PATCH 2/2] i945/gma.c: add native VGA init
+
+This reuses the Intel Pineview native graphic initialization
+to have output on the VGA connector of i945 devices.
+
+The behavior is the same as with the vendor VBIOS BLOB.
+It uses the external VGA display if it is connected.
+
+Change-Id: I7eaee87d16df2e5c9ebeaaff01d36ec1aa4ea495
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 196 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 194 insertions(+), 2 deletions(-)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 3f0b5b4..ac19d5a 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -78,7 +78,7 @@ static int gtt_setup(void *mmiobase)
+ return 0;
+ }
+
+-static int intel_gma_init(struct northbridge_intel_i945_config *conf,
++static int intel_gma_init_lvds(struct northbridge_intel_i945_config *conf,
+ unsigned int pphysbase, unsigned int piobase,
+ void *pmmio, unsigned int pgfx)
+ {
+@@ -382,6 +382,194 @@ static int intel_gma_init(struct northbridge_intel_i945_config *conf,
+ #endif
+ return 0;
+ }
++
++static int intel_gma_init_vga(struct northbridge_intel_i945_config *conf,
++ unsigned int pphysbase, unsigned int piobase,
++ void *pmmio, unsigned int pgfx)
++{
++ int i;
++ u32 hactive, vactive;
++ u16 reg16;
++ u32 uma_size;
++
++ printk(BIOS_SPEW, "pmmio %x addrport %x physbase %x\n",
++ (u32)pmmio, piobase, pphysbase);
++
++ gtt_setup(pmmio);
++
++ /* Disable VGA. */
++ write32(pmmio + VGACNTRL, VGA_DISP_DISABLE);
++
++ /* Disable pipes. */
++ write32(pmmio + PIPECONF(0), 0);
++ write32(pmmio + PIPECONF(1), 0);
++
++ write32(pmmio + INSTPM, 0x800);
++
++ vga_gr_write(0x18, 0);
++
++ write32(pmmio + VGA0, 0x200074);
++ write32(pmmio + VGA1, 0x200074);
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1 & ~PINEVIEW_SELF_REFRESH_EN);
++ write32(pmmio + DSPCLK_GATE_D, 0);
++ write32(pmmio + FW_BLC, 0x03060106);
++ write32(pmmio + FW_BLC2, 0x00000306);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + 0x7041c, 0x0);
++
++ write32(pmmio + DPLL_MD(0), 0x3);
++ write32(pmmio + DPLL_MD(1), 0x3);
++ write32(pmmio + DSPCNTR(1), 0x1000000);
++ write32(pmmio + PIPESRC(1), 0x027f01df);
++
++ vga_misc_write(0x67);
++ const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
++ 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
++ 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
++ 0xff
++ };
++ vga_cr_write(0x11, 0);
++
++ for (i = 0; i <= 0x18; i++)
++ vga_cr_write(i, cr[i]);
++
++ // Disable screen memory to prevent garbage from appearing.
++ vga_sr_write(1, vga_sr_read(1) | 0x20);
++ hactive = 640;
++ vactive = 400;
++
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++ mdelay(1);
++ write32(pmmio + DPLL(0),
++ DPLL_VCO_ENABLE | DPLLB_MODE_DAC_SERIAL
++ | DPLL_VGA_MODE_DIS
++ | DPLL_DAC_SERIAL_P2_CLOCK_DIV_10
++ | 0x400601
++ );
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + HTOTAL(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HBLANK(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++ write32(pmmio + HSYNC(0),
++ ((hactive - 1) << 16)
++ | (hactive - 1));
++
++ write32(pmmio + VTOTAL(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VBLANK(0), ((vactive - 1) << 16)
++ | (vactive - 1));
++ write32(pmmio + VSYNC(0),
++ ((vactive - 1) << 16)
++ | (vactive - 1));
++
++ write32(pmmio + PF_WIN_POS(0), 0);
++
++ write32(pmmio + PIPESRC(0), (639 << 16) | 399);
++ write32(pmmio + PF_CTL(0),PF_ENABLE | PF_FILTER_MED_3x3);
++ write32(pmmio + PF_WIN_SZ(0), vactive | (hactive << 16));
++ write32(pmmio + PFIT_CONTROL, 0x0);
++
++ mdelay(1);
++
++ write32(pmmio + FDI_RX_CTL(0), 0x00002040);
++ mdelay(1);
++ write32(pmmio + FDI_RX_CTL(0), 0x80002050);
++ write32(pmmio + FDI_TX_CTL(0), 0x00044000);
++ mdelay(1);
++ write32(pmmio + FDI_TX_CTL(0), 0x80044000);
++ write32(pmmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
++
++ write32(pmmio + VGACNTRL, 0x0);
++ write32(pmmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);
++ mdelay(1);
++
++ write32(pmmio + ADPA, ADPA_DAC_ENABLE
++ | ADPA_PIPE_A_SELECT
++ | ADPA_USE_VGA_HVPOLARITY
++ | ADPA_VSYNC_CNTL_ENABLE
++ | ADPA_HSYNC_CNTL_ENABLE
++ | ADPA_DPMS_ON
++ );
++
++ write32(pmmio + DSPFW3, 0x7f3f00c1);
++ write32(pmmio + MI_MODE, 0x200 | VS_TIMER_DISPATCH);
++ write32(pmmio + CACHE_MODE_0, (0x6820 | (1 << 9)) & ~(1 << 5));
++ write32(pmmio + CACHE_MODE_1, 0x380 & ~(1 << 9));
++
++ /* Set up GTT. */
++
++ reg16 = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0, 0)), GGC);
++ uma_size = 0;
++ if (!(reg16 & 2)) {
++ uma_size = decode_igd_memory_size((reg16 >> 4) & 7);
++ printk(BIOS_DEBUG, "%dM UMA\n", uma_size >> 10);
++ }
++
++ for (i = 0; i < (uma_size - 256) / 4; i++)
++ {
++ outl((i << 2) | 1, piobase);
++ outl(pphysbase + (i << 12) + 1, piobase + 4);
++ }
++
++ /* Clear interrupts. */
++ write32(pmmio + DEIIR, 0xffffffff);
++ write32(pmmio + SDEIIR, 0xffffffff);
++ write32(pmmio + IIR, 0xffffffff);
++ write32(pmmio + IMR, 0xffffffff);
++ write32(pmmio + EIR, 0xffffffff);
++
++ vga_textmode_init();
++
++ /* Enable screen memory. */
++ vga_sr_write(1, vga_sr_read(1) & ~0x20);
++
++ return 0;
++
++}
++
++/* compare the header of the vga edid header */
++/* if vga is not connected it should have a correct header */
++static int vga_connected(u8 *pmmio) {
++ u8 vga_edid[128];
++ u8 header[8] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
++ intel_gmbus_read_edid(pmmio + GMBUS0, 2, 0x50, vga_edid, 128);
++ intel_gmbus_stop(pmmio + GMBUS0);
++ for (int i = 0; i < 8; i++) {
++ if (vga_edid[i] != header[i]) {
++ printk(BIOS_DEBUG, "VGA not connected. Using LVDS display\n");
++ return 0;
++ }
++ }
++ printk(BIOS_SPEW, "VGA display connected\n");
++ return 1;
++}
++
+ #endif
+
+ static void gma_func0_init(struct device *dev)
+@@ -423,7 +611,11 @@ static void gma_func0_init(struct device *dev)
+ );
+
+ int err;
+- err = intel_gma_init(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ if (vga_connected(mmiobase))
++ err = intel_gma_init_vga(conf, pci_read_config32(dev, 0x5c) & ~0xf,
++ iobase, mmiobase, graphics_base);
++ else
++ err = intel_gma_init_lvds(conf, pci_read_config32(dev, 0x5c) & ~0xf,
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0007-i945-gma.c-generate-fake-VBT.patch b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0007-i945-gma.c-generate-fake-VBT.patch
new file mode 100644
index 00000000..6f0272fd
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/0007-i945-gma.c-generate-fake-VBT.patch
@@ -0,0 +1,43 @@
+From 60cc2c4532f63a40486b7c4e891fb87fb6d4ab7f Mon Sep 17 00:00:00 2001
+From: Arthur Heymans <arthur@aheymans.xyz>
+Date: Wed, 7 Sep 2016 22:10:57 +0200
+Subject: [PATCH] i945/gma.c: generate fake VBT
+
+This generates a fake VBT for the Intel i945 graphic device.
+i945 supports both the mobile chipset 945gm (calistoga)
+and the desktop chipset 945gc (lakeport),
+which is why a VBT with a different id string
+needs to be created for each target.
+
+The VBT id string is obtained from the vbios blob in the following way:
+"strings vbios.bin | grep VBT".
+
+Change-Id: I8245b12b16a4426efbe1f584d4163fc257231a98
+Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
+---
+ src/northbridge/intel/i945/gma.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 02caa0a..f0944b9 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -433,6 +433,15 @@ static void gma_func0_init(struct device *dev)
+ iobase, mmiobase, graphics_base);
+ if (err == 0)
+ gfx_set_init_done(1);
++ /* Linux relies on VBT for panel info. */
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT CALISTOGA ");
++ }
++ if (CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC) {
++ generate_fake_intel_oprom(&conf->gfx, dev,
++ "$VBT LAKEPORT-G ");
++ }
+ #endif
+ }
+
+--
+2.9.3
+
diff --git a/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/INFO b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/INFO
new file mode 100644
index 00000000..4f5931f9
--- /dev/null
+++ b/resources/libreboot/patch/coreboot/2a3434757ef425dbdfedf1fc69e1a033a6e7310d/grub/x60/INFO
@@ -0,0 +1,7 @@
+printf "lenovo/x60: use correct BLC_PWM_CTL value\n"
+git am "../resources/libreboot/patch/misc/0003-lenovo-x60-use-correct-BLC_PWM_CTL-value.patch"
+# git fetch http://review.coreboot.org/coreboot refs/changes/24/10624/2 && git cherry-pick FETCH_HEAD
+
+printf "ec/lenovo/h8: permanently enable wifi/trackpoint/touchpad/bluetooth/wwan\n"
+git am "../resources/libreboot/patch/misc/0005-NOTFORMERGE-ec-lenovo-h8-wlan-trackpoint-touchpad-bl.patch"
+# git fetch http://review.coreboot.org/coreboot refs/changes/58/7058/9 && git cherry-pick FETCH_HEAD