Fixes to enable RC6 on IvyBridge

- The unneeded poll on non-MT force-wake bit was timing out
and causing the gma_pm_init_pre_vbios() function to exit
early so it was not preparing PM registers properly.
I changed the gtt_poll() calls to not return on timeout
unless it can't proceed so we don't see half-initialized
registers.

- RC6+ (Deep Render Standby) is not working reliably so we
can just enable RC6 in the BIOS and let the kernel decide
if it wants to enable RC6+ later.

This Kernel message is new in kernel 3.4:
[drm] Enabling RC6 states: RC6 on, RC6p off, RC6pp off

Change-Id: I69d005ba56be8c7684a4ea1133a1d761f7c07acc
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: http://review.coreboot.org/1268
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Duncan Laurie 2012-05-25 10:04:17 -07:00 committed by Ronald G. Minnich
parent ac2ec34fd2
commit da83a5f18e
1 changed files with 21 additions and 38 deletions

View File

@ -374,19 +374,11 @@ static void gma_pm_init_pre_vbios(struct device *dev)
if (bridge_silicon_revision() < IVB_STEP_C0) { if (bridge_silicon_revision() < IVB_STEP_C0) {
/* 1: Enable force wake */ /* 1: Enable force wake */
gtt_write(0xa18c, 0x00000001); gtt_write(0xa18c, 0x00000001);
if (!gtt_poll(0x130090, (1 << 0), (1 << 0))) gtt_poll(0x130090, (1 << 0), (1 << 0));
return;
} else { } else {
gtt_write(0xa180, 1 << 5); gtt_write(0xa180, 1 << 5);
gtt_write(0xa188, 0xffff0001); gtt_write(0xa188, 0xffff0001);
if (!gtt_poll(0x130040, (1 << 0), (1 << 0))) gtt_poll(0x130040, (1 << 0), (1 << 0));
return;
/*
* HACK: also poll on 0x130090, for some reason graphics does
* not work on all SKUs unless this register is polled at boot.
*/
if (!gtt_poll(0x130090, (1 << 0), (1 << 0)))
return;
} }
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
@ -432,7 +424,7 @@ static void gma_pm_init_pre_vbios(struct device *dev)
gtt_write_powermeter(ivb_pm_gt2_17w); gtt_write_powermeter(ivb_pm_gt2_17w);
} else if ((tdp >= 25) && (tdp <= 35)) { } else if ((tdp >= 25) && (tdp <= 35)) {
/* 25W-35W */ /* 25W-35W */
printk(BIOS_DEBUG, "IVB GT2 35W " printk(BIOS_DEBUG, "IVB GT2 25W-35W "
"Power Meter Weights\n"); "Power Meter Weights\n");
gtt_write_powermeter(ivb_pm_gt2_35w); gtt_write_powermeter(ivb_pm_gt2_35w);
} else { } else {
@ -472,8 +464,7 @@ static void gma_pm_init_pre_vbios(struct device *dev)
reg32 &= 0xf; reg32 &= 0xf;
reg32 |= (1 << 1); reg32 |= (1 << 1);
gtt_write(0x941c, reg32); gtt_write(0x941c, reg32);
if (!gtt_poll(0x941c, (1 << 1), (0 << 1))) gtt_poll(0x941c, (1 << 1), (0 << 1));
return;
} }
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
@ -489,15 +480,13 @@ static void gma_pm_init_pre_vbios(struct device *dev)
} }
/* 7 */ /* 7 */
if (!gtt_poll(0x138124, (1 << 31), (0 << 31))) if (gtt_poll(0x138124, (1 << 31), (0 << 31))) {
return; gtt_write(0x138128, 0x00000029); /* Mailbox Data */
gtt_write(0x138128, 0x00000029); /* Mailbox Data */ gtt_write(0x138124, 0x80000004); /* Mailbox Cmd for RC6 VID */
gtt_write(0x138124, 0x80000004); /* Mailbox Cmd for RC6 VID */ if (gtt_poll(0x138124, (1 << 31), (0 << 31)))
if (!gtt_poll(0x138124, (1 << 31), (0 << 31))) gtt_write(0x138124, 0x8000000a);
return; gtt_poll(0x138124, (1 << 31), (0 << 31));
gtt_write(0x138124, 0x8000000a); /* Mailbox Cmd to clear RC6 count */ }
if (!gtt_poll(0x138124, (1 << 31), (0 << 31)))
return;
/* 8 */ /* 8 */
gtt_write(0xa090, 0x00000000); /* RC Control */ gtt_write(0xa090, 0x00000000); /* RC Control */
@ -530,8 +519,13 @@ static void gma_pm_init_pre_vbios(struct device *dev)
/* 11a: Enable Render Standby (RC6) */ /* 11a: Enable Render Standby (RC6) */
if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
/* on IVB: also enable DeepRenderStandby */ /*
gtt_write(0xa090, 0x88060000); /* HW RC Control */ * IvyBridge should also support DeepRenderStandby.
*
* Unfortunately it does not work reliably on all SKUs so
* disable it here and it can be enabled by the kernel.
*/
gtt_write(0xa090, 0x88040000); /* HW RC Control */
} else { } else {
gtt_write(0xa090, 0x88040000); /* HW RC Control */ gtt_write(0xa090, 0x88040000); /* HW RC Control */
} }
@ -566,22 +560,11 @@ static void gma_pm_init_post_vbios(struct device *dev)
/* 15: Deassert Force Wake */ /* 15: Deassert Force Wake */
if (bridge_silicon_revision() < IVB_STEP_C0) { if (bridge_silicon_revision() < IVB_STEP_C0) {
gtt_write(0xa18c, gtt_read(0xa18c) & ~1); gtt_write(0xa18c, gtt_read(0xa18c) & ~1);
if (!gtt_poll(0x130090, (1 << 0), (0 << 0))) { gtt_poll(0x130090, (1 << 0), (0 << 0));
return;
}
} else { } else {
gtt_write(0xa188, 0x1fffe); gtt_write(0xa188, 0x1fffe);
if (!gtt_poll(0x130040, (1 << 0), (0 << 0))) { if (gtt_poll(0x130040, (1 << 0), (0 << 0)))
return; gtt_write(0xa188, gtt_read(0xa188) | 1);
}
/*
* HACK: also poll on 0x130090, for some reason graphics does
* not work on all SKUs unless this register is polled at boot.
*/
if (!gtt_poll(0x130090, (1 << 0), (0 << 0))) {
return;
}
gtt_write(0xa188, gtt_read(0xa188) | 1);
} }
/* 16: SW RC Control */ /* 16: SW RC Control */