[coreboot-gerrit] New patch to review for coreboot: b2c761b haswell: Fix up GPU power management setup

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Dec 3 22:19:48 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4356

-gerrit

commit b2c761b374ca7ec0292d017578bcaa689e9e15c2
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Tue Jul 9 15:40:27 2013 -0700

    haswell: Fix up GPU power management setup
    
    New/more magic values from latest ref code.
    
    Change-Id: Ia2655333b4daca86c2f2a76f5edcd55cdaf3f851
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://gerrit.chromium.org/gerrit/61334
    Commit-Queue: Aaron Durbin <adurbin at chromium.org>
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/northbridge/intel/haswell/gma.c | 149 +++++++++++++++++++++++++++++++-----
 1 file changed, 130 insertions(+), 19 deletions(-)

diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c
index 653cbdc..f13ef7a 100644
--- a/src/northbridge/intel/haswell/gma.c
+++ b/src/northbridge/intel/haswell/gma.c
@@ -24,10 +24,69 @@
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <drivers/intel/gma/i915_reg.h>
+#include <cpu/intel/haswell/haswell.h>
 
 #include "chip.h"
 #include "haswell.h"
 
+struct gt_reg {
+	u32 reg;
+	u32 andmask;
+	u32 ormask;
+};
+
+static const struct gt_reg haswell_gt_setup[] = {
+	/* Enable Counters */
+	{ 0x0a248, 0x00000000, 0x00000016 },
+	{ 0x0a000, 0x00000000, 0x00070020 },
+	{ 0x0a180, 0xff3fffff, 0x15000000 },
+	/* Enable DOP Clock Gating */
+	{ 0x09424, 0x00000000, 0x000003fd },
+	/* Enable Unit Level Clock Gating */
+	{ 0x09400, 0x00000000, 0x00000080 },
+	{ 0x09404, 0x00000000, 0x40401000 },
+	{ 0x09408, 0x00000000, 0x00000000 },
+	{ 0x0940c, 0x00000000, 0x02000001 },
+	{ 0x0a008, 0x00000000, 0x08000000 },
+	/* Wake Rate Limits */
+	{ 0x0a090, 0xffffffff, 0x00000000 },
+	{ 0x0a098, 0xffffffff, 0x03e80000 },
+	{ 0x0a09c, 0xffffffff, 0x00280000 },
+	{ 0x0a0a8, 0xffffffff, 0x0001e848 },
+	{ 0x0a0ac, 0xffffffff, 0x00000019 },
+	/* Render/Video/Blitter Idle Max Count */
+	{ 0x02054, 0x00000000, 0x0000000a },
+	{ 0x12054, 0x00000000, 0x0000000a },
+	{ 0x22054, 0x00000000, 0x0000000a },
+	/* RC Sleep / RCx Thresholds */
+	{ 0x0a0b0, 0xffffffff, 0x00000000 },
+	{ 0x0a0b4, 0xffffffff, 0x000003e8 },
+	{ 0x0a0b8, 0xffffffff, 0x0000c350 },
+	/* RP Settings */
+	{ 0x0a010, 0xffffffff, 0x000f4240 },
+	{ 0x0a014, 0xffffffff, 0x12060000 },
+	{ 0x0a02c, 0xffffffff, 0x0000e808 },
+	{ 0x0a030, 0xffffffff, 0x0003bd08 },
+	{ 0x0a068, 0xffffffff, 0x000101d0 },
+	{ 0x0a06c, 0xffffffff, 0x00055730 },
+	{ 0x0a070, 0xffffffff, 0x0000000a },
+	/* RP Control */
+	{ 0x0a024, 0x00000000, 0x00000b92 },
+	/* HW RC6 Control */
+	{ 0x0a090, 0x00000000, 0x88040000 },
+	/* Video Frequency Request */
+	{ 0x0a00c, 0x00000000, 0x08000000 },
+	{ 0 },
+};
+
+static const struct gt_reg haswell_gt_lock[] = {
+	{ 0x0a248, 0xffffffff, 0x80000000 },
+	{ 0x0a004, 0xffffffff, 0x00000010 },
+	{ 0x0a080, 0xffffffff, 0x00000004 },
+	{ 0x0a180, 0xffffffff, 0x80000000 },
+	{ 0 },
+};
+
 /* some vga option roms are used for several chipsets but they only have one
  * PCI ID in their header. If we encounter such an option rom, we need to do
  * the mapping ourselfes
@@ -72,6 +131,24 @@ static inline void gtt_write(u32 reg, u32 data)
 	write32(gtt_res->base + reg, data);
 }
 
+static inline void gtt_rmw(u32 reg, u32 andmask, u32 ormask)
+{
+	u32 val = gtt_read(reg);
+	val &= andmask;
+	val |= ormask;
+	gtt_write(reg, val);
+}
+
+static inline void gtt_write_regs(const struct gt_reg *gt)
+{
+	for (; gt && gt->reg; gt++) {
+		if (gt->andmask)
+			gtt_rmw(gt->reg, gt->andmask, gt->ormask);
+		else
+			gtt_write(gt->reg, gt->ormask);
+	}
+}
+
 #define GTT_RETRY 1000
 static int gtt_poll(u32 reg, u32 mask, u32 value)
 {
@@ -114,30 +191,26 @@ static void gma_pm_init_pre_vbios(struct device *dev)
 	gtt_write(0x0a188, 0x00010001);
 	gtt_poll(0x130044, 1 << 0, 1 << 0);
 
-	/* Enable counters and lock */
-	gtt_write(0x0a248, 0x80000016);
-	gtt_write(0x0a000, 0x00070020);
-	gtt_write(0x0a180, 0xc5000020);
-
-	/* Enable DOP clock gating */
-	gtt_write(0x09424, 0x00000001);
+	/* GT Settings */
+	gtt_write_regs(haswell_gt_setup);
 
-	/* Enable unit level clock gating */
-	gtt_write(0x09400, 0x00000080);
-	gtt_write(0x09404, 0x40401000);
-	gtt_write(0x09408, 0x00000000);
-	gtt_write(0x0940c, 0x02000001);
+	/* Wait for Mailbox Ready */
+	gtt_poll(0x138124, (1 << 31), (0 << 31));
+	/* Mailbox Data - RC6 VIDS */
+	gtt_write(0x138128, 0x00000000);
+	/* Mailbox Command */
+	gtt_write(0x138124, 0x80000004);
+	/* Wait for Mailbox Ready */
+	gtt_poll(0x138124, (1 << 31), (0 << 31));
 
-	/* Configure max ilde count */
-	gtt_write(0x02054, 0x0000000a);
-	gtt_write(0x12054, 0x0000000a);
-	gtt_write(0x22054, 0x0000000a);
-
-	gtt_write(0x0a008, 0x80000000);
-	gtt_write(0x0a024, 0x00000b92);
+	/* Enable PM Interrupts */
+	gtt_write(0x4402c, 0x03000076);
 
 	/* Enable RC6 in idle */
 	gtt_write(0x0a094, 0x00040000);
+
+	/* PM Lock Settings */
+	gtt_write_regs(haswell_gt_lock);
 }
 
 static void gma_setup_panel(struct device *dev)
@@ -269,9 +342,47 @@ static void gma_setup_panel(struct device *dev)
 
 static void gma_pm_init_post_vbios(struct device *dev)
 {
+	int cdclk = 0;
+	int devid = pci_read_config16(dev, PCI_DEVICE_ID);
+	int gpu_is_ulx = 0;
+
+	if (devid == 0x0a0e || devid == 0x0a1e)
+		gpu_is_ulx = 1;
+
+	/* CD Frequency */
+	if (gtt_read(0x42014) & 0x1000000) {
+		cdclk = 0; /* only 450mhz */
+	} else {
+		cdclk = 2; /* 337.5mhz, 450mhz, or 540mhz */
+		if (gpu_is_ulx)
+			cdclk = 0; /* only 337.5mhz */
+
+		/* TODO: this check does not seem right... */
+		if (haswell_is_ult() &&
+		    haswell_stepping() < HASWELL_STEPPING_MOBILE_D0)
+			cdclk = 0; /* only 450mhz */
+		else
+			cdclk = 1; /* 337.5mhz and 450mhz */
+	}
+	if (gpu_is_ulx || cdclk != 0)
+		gtt_rmw(0x130040, 0xf7ffffff, 0x04000000);
+	else
+		gtt_rmw(0x130040, 0xf3ffffff, 0x00000000);
+
+	/* More magic */
+	if (haswell_is_ult() || gpu_is_ulx) {
+		if (cdclk == 1 && gpu_is_ulx == 0)
+			gtt_write(0x138128, 0x00000000);
+		else
+			gtt_write(0x138128, 0x00000001);
+		gtt_write(0x13812c, 0x00000000);
+		gtt_write(0x138124, 0x80000017);
+	}
+
 	/* Disable Force Wake */
 	gtt_write(0x0a188, 0x00010000);
 	gtt_poll(0x130044, 1 << 0, 0 << 0);
+	gtt_write(0x0a188, 0x00000001);
 }
 
 static void gma_func0_init(struct device *dev)



More information about the coreboot-gerrit mailing list