From dd585b8825a513d5e304cd3b04da7aeb847b9e8b Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Mon, 9 Apr 2012 12:05:18 -0700 Subject: Update ivybridge graphics initialization - Add config options to set backlight registers - Update powermeter weight tables for IvyBridge GT1 and add a new table for GT2 SKU - Fix a few registers used during GPU PM init sequence Change-Id: I1500bc07e3ba1bc10c77e7856089e716489dc07a Signed-off-by: Duncan Laurie Reviewed-on: http://review.coreboot.org/973 Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/chip.h | 3 + src/northbridge/intel/sandybridge/gma.c | 309 +++++++++++++++++++++---------- 2 files changed, 213 insertions(+), 99 deletions(-) (limited to 'src/northbridge') diff --git a/src/northbridge/intel/sandybridge/chip.h b/src/northbridge/intel/sandybridge/chip.h index b891884c9d..bd89787463 100644 --- a/src/northbridge/intel/sandybridge/chip.h +++ b/src/northbridge/intel/sandybridge/chip.h @@ -35,6 +35,9 @@ struct northbridge_intel_sandybridge_config { u16 gpu_panel_power_down_delay; /* T3 time sequence */ u16 gpu_panel_power_backlight_on_delay; /* T5 time sequence */ u16 gpu_panel_power_backlight_off_delay; /* Tx time sequence */ + + u32 gpu_cpu_backlight; /* CPU Backlight PWM value */ + u32 gpu_pch_backlight; /* PCH Backlight PWM value */ }; extern struct chip_operations northbridge_intel_sandybridge_ops; diff --git a/src/northbridge/intel/sandybridge/gma.c b/src/northbridge/intel/sandybridge/gma.c index 4aabb7547c..181d901705 100644 --- a/src/northbridge/intel/sandybridge/gma.c +++ b/src/northbridge/intel/sandybridge/gma.c @@ -27,6 +27,169 @@ #include "chip.h" #include "sandybridge.h" +struct gt_powermeter { + u16 reg; + u32 value; +}; + +struct gt_powermeter snb_pm_gt1[] = { + { 0xa200, 0xcc000000 }, + { 0xa204, 0x07000040 }, + { 0xa208, 0x0000fe00 }, + { 0xa20c, 0x00000000 }, + { 0xa210, 0x17000000 }, + { 0xa214, 0x00000021 }, + { 0xa218, 0x0817fe19 }, + { 0xa21c, 0x00000000 }, + { 0xa220, 0x00000000 }, + { 0xa224, 0xcc000000 }, + { 0xa228, 0x07000040 }, + { 0xa22c, 0x0000fe00 }, + { 0xa230, 0x00000000 }, + { 0xa234, 0x17000000 }, + { 0xa238, 0x00000021 }, + { 0xa23c, 0x0817fe19 }, + { 0xa240, 0x00000000 }, + { 0xa244, 0x00000000 }, + { 0xa248, 0x8000421e }, + { 0 } +}; + +struct gt_powermeter snb_pm_gt2[] = { + { 0xa200, 0x330000a6 }, + { 0xa204, 0x402d0031 }, + { 0xa208, 0x00165f83 }, + { 0xa20c, 0xf1000000 }, + { 0xa210, 0x00000000 }, + { 0xa214, 0x00160016 }, + { 0xa218, 0x002a002b }, + { 0xa21c, 0x00000000 }, + { 0xa220, 0x00000000 }, + { 0xa224, 0x330000a6 }, + { 0xa228, 0x402d0031 }, + { 0xa22c, 0x00165f83 }, + { 0xa230, 0xf1000000 }, + { 0xa234, 0x00000000 }, + { 0xa238, 0x00160016 }, + { 0xa23c, 0x002a002b }, + { 0xa240, 0x00000000 }, + { 0xa244, 0x00000000 }, + { 0xa248, 0x8000421e }, + { 0 } +}; + +struct gt_powermeter ivb_pm_gt1[] = { + { 0xa800, 0x10000000 }, + { 0xa804, 0x00033800 }, + { 0xa808, 0x00000902 }, + { 0xa80c, 0x0c002f00 }, + { 0xa810, 0x12000400 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00d20800 }, + { 0xa81c, 0x00000002 }, + { 0xa820, 0x03004b02 }, + { 0xa824, 0x00000600 }, + { 0xa828, 0x07000773 }, + { 0xa82c, 0x00000000 }, + { 0xa830, 0x00010032 }, + { 0xa834, 0x1520040d }, + { 0xa838, 0x00020105 }, + { 0xa83c, 0x00083700 }, + { 0xa840, 0x0000151d }, + { 0xa844, 0x00000000 }, + { 0xa848, 0x20001b00 }, + { 0xa84c, 0x0a000010 }, + { 0xa850, 0x00000000 }, + { 0xa854, 0x00000008 }, + { 0xa858, 0x00000008 }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00020000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00003500 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x0c000000 }, + { 0xa910, 0x12000500 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00b20000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x08004b02 }, + { 0xa924, 0x00000200 }, + { 0xa928, 0x07000820 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00030000 }, + { 0xa934, 0x050f020d }, + { 0xa938, 0x00020300 }, + { 0xa93c, 0x00903900 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x20001b00 }, + { 0xa94c, 0x0a000010 }, + { 0xa950, 0x00000000 }, + { 0xa954, 0x00000008 }, + { 0xa960, 0x00110000 }, + { 0xaa3c, 0x00003900 }, + { 0xaa54, 0x00000008 }, + { 0xaa60, 0x00110000 }, + { 0 } +}; + +struct gt_powermeter ivb_pm_gt2[] = { + { 0xa800, 0x20000000 }, + { 0xa804, 0x000e3800 }, + { 0xa808, 0x00000806 }, + { 0xa80c, 0x0c002f00 }, + { 0xa810, 0x0c000800 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00d20d00 }, + { 0xa81c, 0x000000ff }, + { 0xa820, 0x03004b02 }, + { 0xa824, 0x00000600 }, + { 0xa828, 0x07000773 }, + { 0xa82c, 0x00000000 }, + { 0xa830, 0x00020032 }, + { 0xa834, 0x1520040d }, + { 0xa838, 0x00020105 }, + { 0xa83c, 0x00083700 }, + { 0xa840, 0x000016ff }, + { 0xa844, 0x00000000 }, + { 0xa848, 0xff000000 }, + { 0xa84c, 0x0a000010 }, + { 0xa850, 0x00000004 }, + { 0xa854, 0x00000008 }, + { 0xa858, 0x00000018 }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00020000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00003800 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x0c000000 }, + { 0xa910, 0x12000500 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00b20000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x08004b02 }, + { 0xa924, 0x00000200 }, + { 0xa928, 0x07000820 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00030000 }, + { 0xa934, 0x050f020d }, + { 0xa938, 0x00020300 }, + { 0xa93c, 0x00903900 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x20001b00 }, + { 0xa94c, 0x0a000010 }, + { 0xa950, 0x00000000 }, + { 0xa954, 0x00000008 }, + { 0xa960, 0x00110000 }, + { 0xaa3c, 0x00003900 }, + { 0xaa54, 0x00000008 }, + { 0xaa60, 0x00110000 }, + { 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 @@ -63,6 +226,12 @@ static inline void gtt_write(u32 reg, u32 data) write32(gtt_res->base + reg, data); } +static inline void gtt_write_powermeter(struct gt_powermeter *pm) +{ + for (; pm && pm->reg; pm++) + gtt_write(pm->reg, pm->value); +} + #define GTT_RETRY 1000 static int gtt_poll(u32 reg, u32 mask, u32 value) { @@ -98,7 +267,7 @@ static void gma_pm_init_pre_vbios(struct device *dev) } else { gtt_write(0xa180, 1 << 5); gtt_write(0xa188, 0xffff0001); - if (!gtt_poll(0x130090, (1 << 0), (1 << 0))) + if (!gtt_poll(0x130040, (1 << 0), (1 << 0))) return; } @@ -111,112 +280,35 @@ static void gma_pm_init_pre_vbios(struct device *dev) if (bridge_silicon_revision() >= IVB_STEP_A0) { /* Display Reset Acknowledge Settings */ - gtt_write(0xa18c, 0x00000001); reg32 = gtt_read(0x45010); reg32 |= (1 << 1) | (1 << 0); gtt_write(0x45010, reg32); } /* 2: Get GT SKU from GTT+0x911c[13] */ + reg32 = gtt_read(0x911c); if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { - reg32 = gtt_read(0x911c); if (reg32 & (1 << 13)) { - printk(BIOS_DEBUG, "GT1 Power Meter Weights\n"); - gtt_write(0xa200, 0xcc000000); - gtt_write(0xa204, 0x07000040); - gtt_write(0xa208, 0x0000fe00); - gtt_write(0xa20c, 0x00000000); - gtt_write(0xa210, 0x17000000); - gtt_write(0xa214, 0x00000021); - gtt_write(0xa218, 0x0817fe19); - gtt_write(0xa21c, 0x00000000); - gtt_write(0xa220, 0x00000000); - gtt_write(0xa224, 0xcc000000); - gtt_write(0xa228, 0x07000040); - gtt_write(0xa22c, 0x0000fe00); - gtt_write(0xa230, 0x00000000); - gtt_write(0xa234, 0x17000000); - gtt_write(0xa238, 0x00000021); - gtt_write(0xa23c, 0x0817fe19); - gtt_write(0xa240, 0x00000000); - gtt_write(0xa244, 0x00000000); - gtt_write(0xa248, 0x8000421e); + printk(BIOS_DEBUG, "SNB GT1 Power Meter Weights\n"); + gtt_write_powermeter(snb_pm_gt1); } else { - printk(BIOS_DEBUG, "GT2 Power Meter Weights\n"); - gtt_write(0xa200, 0x330000a6); - gtt_write(0xa204, 0x402d0031); - gtt_write(0xa208, 0x00165f83); - gtt_write(0xa20c, 0xf1000000); - gtt_write(0xa210, 0x00000000); - gtt_write(0xa214, 0x00160016); - gtt_write(0xa218, 0x002a002b); - gtt_write(0xa21c, 0x00000000); - gtt_write(0xa220, 0x00000000); - gtt_write(0xa224, 0x330000a6); - gtt_write(0xa228, 0x402d0031); - gtt_write(0xa22c, 0x00165f83); - gtt_write(0xa230, 0xf1000000); - gtt_write(0xa234, 0x00000000); - gtt_write(0xa238, 0x00160016); - gtt_write(0xa23c, 0x002a002b); - gtt_write(0xa240, 0x00000000); - gtt_write(0xa244, 0x00000000); - gtt_write(0xa248, 0x8000421e); + printk(BIOS_DEBUG, "SNB GT2 Power Meter Weights\n"); + gtt_write_powermeter(snb_pm_gt2); } } else { - printk(BIOS_DEBUG, "IVB GT Power Meter Weights\n"); - gtt_write(0xa800, 0x00000000); - gtt_write(0xa804, 0x00023800); - gtt_write(0xa808, 0x00000902); - gtt_write(0xa80c, 0x0c002f00); - gtt_write(0xa810, 0x12000500); - gtt_write(0xa814, 0x00000000); - gtt_write(0xa818, 0x00b20000); - gtt_write(0xa81c, 0x00000002); - gtt_write(0xa820, 0x03004b02); - gtt_write(0xa824, 0x00000600); - gtt_write(0xa828, 0x07000773); - gtt_write(0xa82c, 0x00000000); - gtt_write(0xa830, 0x00010000); - gtt_write(0xa834, 0x0510020d); - gtt_write(0xa838, 0x00020100); - gtt_write(0xa83c, 0x00103700); - gtt_write(0xa840, 0x0000001d); - gtt_write(0xa844, 0x00000000); - gtt_write(0xa848, 0x20001b00); - gtt_write(0xa84c, 0x0a000010); - gtt_write(0xa850, 0x00000000); - gtt_write(0xa854, 0x00000008); - gtt_write(0xa858, 0x00000000); - gtt_write(0xa85c, 0x00000000); - gtt_write(0xa860, 0x00040000); - gtt_write(0xa248, 0x0000221e); - gtt_write(0xa900, 0x00000000); - gtt_write(0xa904, 0x00003500); - gtt_write(0xa908, 0x00000000); - gtt_write(0xa90c, 0x0c000000); - gtt_write(0xa910, 0x12000500); - gtt_write(0xa914, 0x00000000); - gtt_write(0xa918, 0x00b20000); - gtt_write(0xa91c, 0x00000000); - gtt_write(0xa920, 0x08004b02); - gtt_write(0xa924, 0x00000400); - gtt_write(0xa928, 0x07000820); - gtt_write(0xa92c, 0x00000000); - gtt_write(0xa930, 0x00030000); - gtt_write(0xa934, 0x050f020d); - gtt_write(0xa938, 0x00020300); - gtt_write(0xa93c, 0x00903900); - gtt_write(0xa940, 0x00000000); - gtt_write(0xa944, 0x00000000); - gtt_write(0xa948, 0x20001b00); - gtt_write(0xa94c, 0x0a000010); - gtt_write(0xa950, 0x00000000); - gtt_write(0xa954, 0x00000008); - gtt_write(0xa960, 0x00110000); - gtt_write(0xaa3c, 0x00003900); - gtt_write(0xaa54, 0x00000008); - gtt_write(0xaa60, 0x00110000); + u32 unit = MCHBAR32(0x5938) & 0xf; + u32 tdp = MCHBAR32(0x5930) & 0x7fff; + tdp /= (1 << unit); + + if ((tdp <= 17) && !(reg32 & (1 << 13))) { + /* <=17W ULV and GT2 SKU */ + printk(BIOS_DEBUG, "IVB GT2 Power Meter Weights\n"); + gtt_write_powermeter(ivb_pm_gt2); + } else { + /* GT1 SKU */ + printk(BIOS_DEBUG, "IVB GT1 Power Meter Weights\n"); + gtt_write_powermeter(ivb_pm_gt1); + } } /* 3: Gear ratio map */ @@ -339,9 +431,18 @@ static void gma_pm_init_post_vbios(struct device *dev) printk(BIOS_DEBUG, "GT Power Management Init (post VBIOS)\n"); /* 15: Deassert Force Wake */ - gtt_write(0xa18c, gtt_read(0xa18c) & ~1); - if (!gtt_poll(0x130090, (1 << 0), (0 << 0))) - return; + if (bridge_silicon_revision() < IVB_STEP_C0) { + gtt_write(0xa18c, gtt_read(0xa18c) & ~1); + if (!gtt_poll(0x130090, (1 << 0), (0 << 0))) { + return; + } + } else { + gtt_write(0xa188, 0x1fffe); + if (!gtt_poll(0x130040, (1 << 0), (0 << 0))) { + return; + } + gtt_write(0xa188, gtt_read(0xa188) | 1); + } /* 16: SW RC Control */ gtt_write(0xa094, 0x00060000); @@ -379,6 +480,16 @@ static void gma_pm_init_post_vbios(struct device *dev) reg32 |= conf->gpu_panel_power_cycle_delay & 0xff; gtt_write(0xc7210, reg32); } + + /* Enable Backlight if needed */ + if (conf->gpu_cpu_backlight) { + gtt_write(0x48250, (1 << 31)); + gtt_write(0x48254, conf->gpu_cpu_backlight); + } + if (conf->gpu_pch_backlight) { + gtt_write(0xc8250, (1 << 31)); + gtt_write(0xc8254, conf->gpu_pch_backlight); + } } static void gma_func0_init(struct device *dev) -- cgit v1.2.3