From 01f6afcfea9d315ad1473045da141bfc95bcb7e6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 28 Jan 2008 21:05:22 -0800 Subject: Fix hibernate save/restore of VGA attribute regs In hibernate, we may end up calling the VGA save regs function twice, so we need to make sure it's idempotent. That means leaving ARX in index mode after the first save operation. Fixes hibernate on 965. --- linux-core/i915_drv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/i915_drv.c') diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index a5f60ee1..5f2e6adc 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -192,6 +192,7 @@ static void i915_save_vga(struct drm_device *dev) dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); inb(st01); outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); + inb(st01); /* Graphics controller registers */ for (i = 0; i < 9; i++) @@ -257,6 +258,7 @@ static void i915_restore_vga(struct drm_device *dev) i915_write_ar(st01, i, dev_priv->saveAR[i], 0); inb(st01); /* switch back to index mode */ outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); + inb(st01); /* VGA color palette registers */ outb(dev_priv->saveDACMASK, VGA_DACMASK); -- cgit v1.2.3 From f1edb7ad91d8b92057ffa02eb162e3740d05a147 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 30 Jan 2008 22:06:02 +0100 Subject: Simplify the fencing code and differentiate between flushes and waiting types. Add a "command_stream_barrier" method to the bo driver. --- linux-core/i915_drv.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'linux-core/i915_drv.c') diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 5f2e6adc..ccc061d3 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -39,17 +39,9 @@ static struct pci_device_id pciidlist[] = { }; #ifdef I915_HAVE_FENCE -static struct drm_fence_driver i915_fence_driver = { - .num_classes = 1, - .wrap_diff = (1U << (BREADCRUMB_BITS - 1)), - .flush_diff = (1U << (BREADCRUMB_BITS - 2)), - .sequence_mask = BREADCRUMB_MASK, - .lazy_capable = 1, - .emit = i915_fence_emit_sequence, - .poke_flush = i915_poke_flush, - .has_irq = i915_fence_has_irq, -}; +extern struct drm_fence_driver i915_fence_driver; #endif + #ifdef I915_HAVE_BUFFER static uint32_t i915_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; @@ -67,6 +59,7 @@ static struct drm_bo_driver i915_bo_driver = { .evict_flags = i915_evict_flags, .move = i915_move, .ttm_cache_flush = i915_flush_ttm, + .command_stream_barrier = NULL, }; #endif -- cgit v1.2.3 From 8b6c96dedd4ba5dfbfec6a7c831d566e31d28781 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 7 Feb 2008 10:48:08 -0800 Subject: i915: save/restore interrupt state On resume, if the interrupt state isn't restored correctly, we may end up with a flood of unexpected or ill-timed interrupts, which could cause the kernel to disable the interrupt or vblank events to happen at the wrong time. So save/restore them properly. --- linux-core/i915_drv.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux-core/i915_drv.c') diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index ccc061d3..c771ab3e 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -303,6 +303,7 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); } i915_save_palette(dev, PIPE_A); + dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); /* Pipe & plane B info */ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); @@ -330,6 +331,7 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); } i915_save_palette(dev, PIPE_B); + dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); /* CRT state */ dev_priv->saveADPA = I915_READ(ADPA); @@ -356,6 +358,11 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); + /* Interrupt state */ + dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); + dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); + dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); + /* VGA state */ dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); -- cgit v1.2.3 From d63b57749f097b36df04c6beff9b35a1dd859523 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 7 Feb 2008 17:33:28 -0800 Subject: Restore pipeconf regs unconditionally On many chipsets, the checks for DPLL enable or VGA mode will prevent the pipeconf regs from being restored, which could result in a blank display or X failing to come back after resume. So restore them unconditionally along with actually restoring pipe B's palette correctly. --- linux-core/i915_drv.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'linux-core/i915_drv.c') diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index c771ab3e..3e2bfc94 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -434,9 +434,7 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); } - if ((dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) && - (dev_priv->saveDPLL_A & DPLL_VGA_MODE_DIS)) - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); i915_restore_palette(dev, PIPE_A); /* Enable the plane */ @@ -478,10 +476,9 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); } - if ((dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) && - (dev_priv->saveDPLL_B & DPLL_VGA_MODE_DIS)) - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); - i915_restore_palette(dev, PIPE_A); + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); + + i915_restore_palette(dev, PIPE_B); /* Enable the plane */ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); I915_WRITE(DSPBBASE, I915_READ(DSPBBASE)); -- cgit v1.2.3 From 5d8c754bc2c720d70bbdeca6b294660105717a62 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Feb 2008 19:19:29 -0800 Subject: [915]: more registers for S3 (DSPCLK_GATE_D, CACHE_MODE_0, MI_ARB_STATE) Failing to preserve the MI_ARB_STATE register was causing FIFO underruns on the VGA output on my HP 2510p after resume. --- linux-core/i915_drv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'linux-core/i915_drv.c') diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 3e2bfc94..9d8b4685 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -369,6 +369,15 @@ static int i915_suspend(struct drm_device *dev) dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + /* Clock gating state */ + dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); + + /* Cache mode state */ + dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); + + /* Memory Arbitration state */ + dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); + /* Scratch space */ for (i = 0; i < 16; i++) { dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); @@ -516,6 +525,15 @@ static int i915_resume(struct drm_device *dev) I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); udelay(150); + /* Clock gating state */ + I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + + /* Cache mode state */ + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + + /* Memory arbitration state */ + I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); + for (i = 0; i < 16; i++) { I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); -- cgit v1.2.3