diff options
author | Jesse Barnes <jbarnes@hobbes.lan> | 2008-05-26 09:34:34 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-05-26 09:34:34 -0700 |
commit | 89bb53cc7a853d88fc34a0ca65ae2b6227a8dd24 (patch) | |
tree | 6e14e27533cbee5cec5ecccecdca2fdf75b8d6b0 | |
parent | 165c0865d849b7d280a3a119fe9ae0ad34637df0 (diff) |
Fixup power saving registers
Update clock gating disable bits to match docs and allocate a power context
memory area so that newer chips can save state and power down the render unit.
-rw-r--r-- | src/i810_reg.h | 3 | ||||
-rw-r--r-- | src/i830.h | 3 | ||||
-rw-r--r-- | src/i830_driver.c | 63 | ||||
-rw-r--r-- | src/i830_memory.c | 18 |
4 files changed, 70 insertions, 17 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h index 860d1dbe..a357d190 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -490,6 +490,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - new bits for i810 * - new register hwstam (mask) */ +#define PWRCTXA 0x2088 /* 965GM+ only */ +#define PWRCTX_EN (1<<0) #define HWSTAM 0x2098 /* p290 */ #define IER 0x20a0 /* p291 */ #define IIR 0x20a4 /* p292 */ @@ -1150,6 +1152,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RENCLK_GATE_D2 0x6208 #define RAMCLK_GATE_D 0x6210 /* CRL only */ +#define DEUC 0x6214 /* CRL only */ /* * This is a PCI config space register to manipulate backlight brightness @@ -426,6 +426,8 @@ typedef struct _I830Rec { i830_memory *logical_context; + i830_memory *power_context; + #ifdef XF86DRI i830_memory *back_buffer; i830_memory *third_buffer; @@ -773,6 +775,7 @@ void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); +Bool i830_allocate_pwrctx(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); #ifdef INTEL_XVMC Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, diff --git a/src/i830_driver.c b/src/i830_driver.c index 8d993bac..df9d7299 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -934,6 +934,40 @@ I830SetupOutputs(ScrnInfoPtr pScrn) } } +static void +i830_init_clock_gating(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Disable clock gating reported to work incorrectly according to the specs. + */ + if (IS_IGD_GM(pI830)) { + OUTREG(RENCLK_GATE_D1, 0); + OUTREG(RENCLK_GATE_D2, 0); + OUTREG(RAMCLK_GATE_D, 0); + OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE); + } else if (IS_I965GM(pI830)) { + OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); + OUTREG(RENCLK_GATE_D2, 0); + OUTREG(DSPCLK_GATE_D, 0); + OUTREG(RAMCLK_GATE_D, 0); + OUTREG16(DEUC, 0); + } else if (IS_I965G(pI830)) { + OUTREG(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + I965_RCC_CLOCK_GATE_DISABLE | + I965_RCPB_CLOCK_GATE_DISABLE | + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + OUTREG(RENCLK_GATE_D2, 0); + } else if (IS_I855(pI830) || IS_I865G(pI830)) { + OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + } else if (IS_I830(pI830)) { + OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); + } +} + static int I830LVDSPresent(ScrnInfoPtr pScrn) { @@ -1461,6 +1495,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) i830TakeRegSnapshot(pScrn); + i830_init_clock_gating(pScrn); + #if 1 pI830->saveSWF0 = INREG(SWF0); pI830->saveSWF4 = INREG(SWF4); @@ -1901,23 +1937,6 @@ SetHWOperatingState(ScrnInfoPtr pScrn) DPRINTF(PFX, "SetHWOperatingState\n"); - /* Disable clock gating reported to work incorrectly according to the specs. - */ - if (IS_IGD_GM(pI830)) { - OUTREG(RENCLK_GATE_D1, 0); - OUTREG(RENCLK_GATE_D2, 0); - OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); - } else if (IS_I965GM(pI830)) { - OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - } else if (IS_I965G(pI830)) { - OUTREG(RENCLK_GATE_D1, - I965_RCC_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE); - } else if (IS_I855(pI830) || IS_I865G(pI830)) { - OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); - } else if (IS_I830(pI830)) { - OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); - } - i830_start_ring(pScrn); if (!pI830->SWCursor) I830InitHWCursor(pScrn); @@ -2504,6 +2523,10 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn) if (!i830_allocate_2d_memory(pScrn)) goto failed; + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + if (!i830_allocate_pwrctx(pScrn)) + goto failed; + if (dri && !i830_allocate_3d_memory(pScrn)) goto failed; @@ -2824,6 +2847,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } + if (pI830->power_context) + OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + I830UnmapMMIO(pScrn); i830_fixup_mtrrs(pScrn); @@ -3453,6 +3479,9 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif + if (IS_I965GM(pI830) || IS_IGD_GM(pI830)) + OUTREG(PWRCTXA, 0); + if (I830IsPrimary(pScrn)) { xf86GARTCloseScreen(scrnIndex); diff --git a/src/i830_memory.c b/src/i830_memory.c index 84db0ef1..02b16794 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -112,6 +112,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Our hardware status area is just a single page */ #define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE +#define PWRCTX_SIZE GTT_PAGE_SIZE static i830_memory * i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, @@ -337,6 +338,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->gen4_render_state_mem = NULL; pI830->overlay_regs = NULL; pI830->logical_context = NULL; + pI830->power_context = NULL; #ifdef XF86DRI pI830->back_buffer = NULL; pI830->third_buffer = NULL; @@ -1657,6 +1659,22 @@ i830_allocate_hwstatus(ScrnInfoPtr pScrn) } Bool +i830_allocate_pwrctx(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + pI830->power_context = i830_allocate_memory(pScrn, "power context", + PWRCTX_SIZE, GTT_PAGE_SIZE, + NEED_LIFETIME_FIXED); + if (!pI830->power_context) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate power context.\n"); + return FALSE; + } + return TRUE; +} + +Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); |