summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-05-19 18:02:54 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-05-19 18:02:54 +0000
commitb56c6bcb0aa01b1c0e3fbc554c6bc99c9149a5df (patch)
treee5a53ec64d9de572aed393760c8a2a6186397221
parent055e2beb42f9e960d08a4ce26cb5eedd5d78b252 (diff)
Split out the suspend/resume code into its own file to make it possible to
diff it against the Linux kernel sources. Fix a few bugs revealed by doing such a diff. Tested by myself and a few others on 915, 945, 965 and 6-series.
-rw-r--r--sys/dev/pci/drm/files.drm3
-rw-r--r--sys/dev/pci/drm/i915_drv.c903
-rw-r--r--sys/dev/pci/drm/i915_drv.h690
-rw-r--r--sys/dev/pci/drm/i915_irq.c46
-rw-r--r--sys/dev/pci/drm/i915_suspend.c927
5 files changed, 1505 insertions, 1064 deletions
diff --git a/sys/dev/pci/drm/files.drm b/sys/dev/pci/drm/files.drm
index d4761ef9aed..68aa4f4dc19 100644
--- a/sys/dev/pci/drm/files.drm
+++ b/sys/dev/pci/drm/files.drm
@@ -1,5 +1,5 @@
# $NetBSD: files.drm,v 1.2 2007/03/28 11:29:37 jmcneill Exp $
-# $OpenBSD: files.drm,v 1.22 2011/09/22 12:24:19 matthieu Exp $
+# $OpenBSD: files.drm,v 1.23 2012/05/19 18:02:53 kettenis Exp $
# direct rendering modules
define drmbase {}
@@ -18,6 +18,7 @@ device inteldrm: drmbase
attach inteldrm at drmdev
file dev/pci/drm/i915_drv.c inteldrm
file dev/pci/drm/i915_irq.c inteldrm
+file dev/pci/drm/i915_suspend.c inteldrm
device radeondrm: drmbase
attach radeondrm at drmdev
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 602bac7a77e..524bfcdfa66 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_drv.c,v 1.119 2012/03/09 13:01:28 ariane Exp $ */
+/* $OpenBSD: i915_drv.c,v 1.120 2012/05/19 18:02:53 kettenis Exp $ */
/*
* Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
*
@@ -87,24 +87,6 @@ void inteldrm_set_max_obj_size(struct inteldrm_softc *);
void inteldrm_quiesce(struct inteldrm_softc *);
/* For reset and suspend */
-int inteldrm_save_state(struct inteldrm_softc *);
-int inteldrm_restore_state(struct inteldrm_softc *);
-int inteldrm_save_display(struct inteldrm_softc *);
-int inteldrm_restore_display(struct inteldrm_softc *);
-void i915_save_vga(struct inteldrm_softc *);
-void i915_restore_vga(struct inteldrm_softc *);
-void i915_save_modeset_reg(struct inteldrm_softc *);
-void i915_restore_modeset_reg(struct inteldrm_softc *);
-u_int8_t i915_read_indexed(struct inteldrm_softc *, u_int16_t,
- u_int16_t, u_int8_t);
-void i915_write_indexed(struct inteldrm_softc *, u_int16_t,
- u_int16_t, u_int8_t, u_int8_t);
-void i915_write_ar(struct inteldrm_softc *, u_int16_t, u_int8_t,
- u_int8_t, u_int16_t);
-u_int8_t i915_read_ar(struct inteldrm_softc *, u_int16_t,
- u_int8_t, u_int16_t);
-void i915_save_palette(struct inteldrm_softc *, enum pipe);
-void i915_restore_palette(struct inteldrm_softc *, enum pipe);
void i915_alloc_ifp(struct inteldrm_softc *, struct pci_attach_args *);
void i965_alloc_ifp(struct inteldrm_softc *, struct pci_attach_args *);
@@ -248,7 +230,7 @@ const static struct drm_pcidev inteldrm_pciidlist[] = {
{PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82GM965_IGD_1,
CHIP_I965GM|CHIP_I965|CHIP_I9XX|CHIP_M|CHIP_GEN4},
{PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82GME965_IGD_1,
- CHIP_I965|CHIP_I9XX|CHIP_GEN4},
+ CHIP_I965GM|CHIP_I965|CHIP_I9XX|CHIP_M|CHIP_GEN4},
{PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82G33_IGD_1,
CHIP_G33|CHIP_I9XX|CHIP_HWS|CHIP_GEN3},
{PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82Q35_IGD_1,
@@ -352,6 +334,17 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux)
PCI_PRODUCT(pa->pa_id), inteldrm_pciidlist);
dev_priv->flags = id_entry->driver_private;
dev_priv->pci_device = PCI_PRODUCT(pa->pa_id);
+ if (dev_priv->flags & CHIP_GEN2)
+ dev_priv->gen = 2;
+ else if (dev_priv->flags & CHIP_GEN3)
+ dev_priv->gen = 3;
+ else if (dev_priv->flags & CHIP_GEN4)
+ dev_priv->gen = 4;
+ else if (dev_priv->flags & CHIP_IRONLAKE)
+ dev_priv->gen = 5;
+ else if (dev_priv->flags & CHIP_GEN6)
+ dev_priv->gen = 6;
+ KASSERT(dev_priv->gen != 0);
dev_priv->pc = pa->pa_pc;
dev_priv->tag = pa->pa_tag;
@@ -581,10 +574,10 @@ inteldrm_activate(struct device *arg, int act)
inteldrm_quiesce(dev_priv);
break;
case DVACT_SUSPEND:
- inteldrm_save_state(dev_priv);
+ i915_save_state(dev_priv);
break;
case DVACT_RESUME:
- inteldrm_restore_state(dev_priv);
+ i915_restore_state(dev_priv);
/* entrypoints can stop sleeping now */
atomic_clearbits_int(&dev_priv->sc_flags, INTELDRM_QUIET);
wakeup(&dev_priv->flags);
@@ -755,12 +748,12 @@ inteldrm_intr(void *arg)
* Clear the PIPE(A|B)STAT regs before the IIR
*/
if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
- pipea_stats = I915_READ(PIPEASTAT);
- I915_WRITE(PIPEASTAT, pipea_stats);
+ pipea_stats = I915_READ(_PIPEASTAT);
+ I915_WRITE(_PIPEASTAT, pipea_stats);
}
if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
- pipeb_stats = I915_READ(PIPEBSTAT);
- I915_WRITE(PIPEBSTAT, pipeb_stats);
+ pipeb_stats = I915_READ(_PIPEBSTAT);
+ I915_WRITE(_PIPEBSTAT, pipeb_stats);
}
if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
inteldrm_error(dev_priv);
@@ -4342,9 +4335,9 @@ inteldrm_error(struct inteldrm_softc *dev_priv)
}
if (eir & I915_ERROR_MEMORY_REFRESH) {
printf("PIPEASTAT: 0x%08x\n",
- I915_READ(PIPEASTAT));
+ I915_READ(_PIPEASTAT));
printf("PIPEBSTAT: 0x%08x\n",
- I915_READ(PIPEBSTAT));
+ I915_READ(_PIPEBSTAT));
}
if (eir & I915_ERROR_INSTRUCTION) {
printf(" INSTPM: 0x%08x\n",
@@ -5126,852 +5119,6 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
}
-/**
- * inteldrm_pipe_enabled - check if a pipe is enabled
- * @dev: DRM device
- * @pipe: pipe to check
- *
- * Reading certain registers when the pipe is disabled can hang the chip.
- * Use this routine to make sure the PLL is running and the pipe is active
- * before reading such registers if unsure.
- */
-int
-inteldrm_pipe_enabled(struct inteldrm_softc *dev_priv, int pipe)
-{
- bus_size_t pipeconf;
-
- if (IS_IRONLAKE(dev_priv) || IS_GEN6(dev_priv)) {
- pipeconf = (pipe ? PCH_DPLL_A : PCH_DPLL_B);
- } else {
- pipeconf = (pipe ? PIPEBCONF : PIPEACONF);
- }
- return ((I915_READ(pipeconf) & PIPEACONF_ENABLE) == PIPEACONF_ENABLE);
-}
-
-/*
- * Register save/restore for various instances
- */
-void
-i915_save_palette(struct inteldrm_softc *dev_priv, enum pipe pipe)
-{
- u_int32_t *array;
- bus_size_t reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
- int i;
-
- if (!inteldrm_pipe_enabled(dev_priv, pipe))
- return;
-
- if (HAS_PCH_SPLIT(dev_priv))
- reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
-
- if (pipe == PIPE_A)
- array = dev_priv->save_palette_a;
- else
- array = dev_priv->save_palette_b;
-
- for (i = 0; i < 256; i++)
- array[i] = I915_READ(reg + (i << 2));
-}
-
-void
-i915_restore_palette(struct inteldrm_softc *dev_priv, enum pipe pipe)
-{
- u_int32_t *array;
- bus_size_t reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
- int i;
-
- if (!inteldrm_pipe_enabled(dev_priv, pipe))
- return;
-
- if (HAS_PCH_SPLIT(dev_priv))
- reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
-
- if (pipe == PIPE_A)
- array = dev_priv->save_palette_a;
- else
- array = dev_priv->save_palette_b;
-
- for(i = 0; i < 256; i++)
- I915_WRITE(reg + (i << 2), array[i]);
-}
-
-u_int8_t
-i915_read_ar(struct inteldrm_softc *dev_priv, u_int16_t st01,
- u_int8_t reg, u_int16_t palette_enable)
-{
- I915_READ8(st01);
- I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
- return I915_READ8(VGA_AR_DATA_READ);
-}
-
-void
-i915_write_ar(struct inteldrm_softc *dev_priv, u_int16_t st01, u_int8_t reg,
- u_int8_t val, u_int16_t palette_enable)
-{
- I915_READ8(st01);
- I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
- I915_WRITE8(VGA_AR_DATA_WRITE, val);
-}
-
-u_int8_t
-i915_read_indexed(struct inteldrm_softc *dev_priv, u_int16_t index_port,
- u_int16_t data_port, u_int8_t reg)
-{
- I915_WRITE8(index_port, reg);
- return I915_READ8(data_port);
-}
-
-void
-i915_write_indexed(struct inteldrm_softc *dev_priv, u_int16_t index_port,
- u_int16_t data_port, u_int8_t reg, u_int8_t val)
-{
- I915_WRITE8(index_port, reg);
- I915_WRITE8(data_port, val);
-}
-
-void
-i915_save_vga(struct inteldrm_softc *dev_priv)
-{
- int i;
- u16 cr_index, cr_data, st01;
-
- /* VGA color palette registers */
- dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
-
- /* MSR bits */
- dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
- cr_index = VGA_CR_INDEX_CGA;
- cr_data = VGA_CR_DATA_CGA;
- st01 = VGA_ST01_CGA;
- } else {
- cr_index = VGA_CR_INDEX_MDA;
- cr_data = VGA_CR_DATA_MDA;
- st01 = VGA_ST01_MDA;
- }
-
- /* CRT controller regs */
- i915_write_indexed(dev_priv, cr_index, cr_data, 0x11,
- i915_read_indexed(dev_priv, cr_index, cr_data, 0x11) & (~0x80));
- for (i = 0; i <= 0x24; i++)
- dev_priv->saveCR[i] = i915_read_indexed(dev_priv,
- cr_index, cr_data, i);
- /* Make sure we don't turn off CR group 0 writes */
- dev_priv->saveCR[0x11] &= ~0x80;
-
- /* Attribute controller registers */
- I915_READ8(st01);
- dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
- for (i = 0; i <= 0x14; i++)
- dev_priv->saveAR[i] = i915_read_ar(dev_priv, st01, i, 0);
- I915_READ8(st01);
- I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
- I915_READ8(st01);
-
- /* Graphics controller registers */
- for (i = 0; i < 9; i++)
- dev_priv->saveGR[i] = i915_read_indexed(dev_priv,
- VGA_GR_INDEX, VGA_GR_DATA, i);
-
- dev_priv->saveGR[0x10] = i915_read_indexed(dev_priv,
- VGA_GR_INDEX, VGA_GR_DATA, 0x10);
- dev_priv->saveGR[0x11] = i915_read_indexed(dev_priv,
- VGA_GR_INDEX, VGA_GR_DATA, 0x11);
- dev_priv->saveGR[0x18] = i915_read_indexed(dev_priv,
- VGA_GR_INDEX, VGA_GR_DATA, 0x18);
-
- /* Sequencer registers */
- for (i = 0; i < 8; i++)
- dev_priv->saveSR[i] = i915_read_indexed(dev_priv,
- VGA_SR_INDEX, VGA_SR_DATA, i);
-}
-
-void
-i915_restore_vga(struct inteldrm_softc *dev_priv)
-{
- u_int16_t cr_index, cr_data, st01;
- int i;
-
- /* MSR bits */
- I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
- cr_index = VGA_CR_INDEX_CGA;
- cr_data = VGA_CR_DATA_CGA;
- st01 = VGA_ST01_CGA;
- } else {
- cr_index = VGA_CR_INDEX_MDA;
- cr_data = VGA_CR_DATA_MDA;
- st01 = VGA_ST01_MDA;
- }
-
- /* Sequencer registers, don't write SR07 */
- for (i = 0; i < 7; i++)
- i915_write_indexed(dev_priv, VGA_SR_INDEX, VGA_SR_DATA, i,
- dev_priv->saveSR[i]);
-
- /* CRT controller regs */
- /* Enable CR group 0 writes */
- i915_write_indexed(dev_priv, cr_index, cr_data, 0x11,
- dev_priv->saveCR[0x11]);
- for (i = 0; i <= 0x24; i++)
- i915_write_indexed(dev_priv, cr_index, cr_data,
- i, dev_priv->saveCR[i]);
-
- /* Graphics controller regs */
- for (i = 0; i < 9; i++)
- i915_write_indexed(dev_priv, VGA_GR_INDEX, VGA_GR_DATA, i,
- dev_priv->saveGR[i]);
-
- i915_write_indexed(dev_priv, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
- dev_priv->saveGR[0x10]);
- i915_write_indexed(dev_priv, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
- dev_priv->saveGR[0x11]);
- i915_write_indexed(dev_priv, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
- dev_priv->saveGR[0x18]);
-
- /* Attribute controller registers */
- I915_READ8(st01); /* switch back to index mode */
- for (i = 0; i <= 0x14; i++)
- i915_write_ar(dev_priv, st01, i, dev_priv->saveAR[i], 0);
- I915_READ8(st01); /* switch back to index mode */
- I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
- I915_READ8(st01);
-
- /* VGA color palette registers */
- I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
-}
-
-void
-i915_save_modeset_reg(struct inteldrm_softc *dev_priv)
-{
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
- dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
- }
-
- /* Pipe & plane A info */
- dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
- dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
- dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
- dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
- } else {
- dev_priv->saveFPA0 = I915_READ(FPA0);
- dev_priv->saveFPA1 = I915_READ(FPA1);
- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
- }
- if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
- dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
- dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
- dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
- dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
- dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
- dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
- dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
- dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
- dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
-
- dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
- dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
-
- dev_priv->savePFA_CTL_1 = I915_READ(PFA_CTL_1);
- dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
- dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
-
- dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
- dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
- dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
- dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
- dev_priv->saveTRANS_VTOTAL_A = I915_READ(TRANS_VTOTAL_A);
- dev_priv->saveTRANS_VBLANK_A = I915_READ(TRANS_VBLANK_A);
- dev_priv->saveTRANS_VSYNC_A = I915_READ(TRANS_VSYNC_A);
- } else {
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
- }
-
- dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
- dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
- dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
- dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
- dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
- if (IS_I965G(dev_priv)) {
- dev_priv->saveDSPASURF = I915_READ(DSPASURF);
- dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
- }
- i915_save_palette(dev_priv, PIPE_A);
- dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
-
- /* Pipe & plane B info */
- dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
- dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->saveFPA0 = I915_READ(PCH_FPB0);
- dev_priv->saveFPA1 = I915_READ(PCH_FPB1);
- dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_B);
- } else {
- dev_priv->saveFPB0 = I915_READ(FPB0);
- dev_priv->saveFPB1 = I915_READ(FPB1);
- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
- }
- if (IS_I965G(dev_priv) && (!IS_IRONLAKE(dev_priv) && !IS_GEN6(dev_priv)))
- dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
- dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
- dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
- dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
- dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
- dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
- dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
- dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
- dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
- dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
-
- dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
- dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
-
- dev_priv->savePFB_CTL_1 = I915_READ(PFB_CTL_1);
- dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
- dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
-
- dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
- dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
- dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
- dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
- dev_priv->saveTRANS_VTOTAL_B = I915_READ(TRANS_VTOTAL_B);
- dev_priv->saveTRANS_VBLANK_B = I915_READ(TRANS_VBLANK_B);
- dev_priv->saveTRANS_VSYNC_B = I915_READ(TRANS_VSYNC_B);
- } else {
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
- }
-
- dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
- dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
- dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
- dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
- dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
- if (IS_I965GM(dev_priv) || IS_GM45(dev_priv)) { /* XXX: IS_MOBILE ? */
- dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
- dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
- }
- i915_save_palette(dev_priv, PIPE_B);
- dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
-}
-
-void
-i915_restore_modeset_reg(struct inteldrm_softc *dev_priv)
-{
- bus_size_t dpll_a_reg, fpa0_reg, fpa1_reg;
- bus_size_t dpll_b_reg, fpb0_reg, fpb1_reg;
-
- /* XXX until we have FDI link training */
- if (IS_GEN6(dev_priv))
- return;
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- dpll_a_reg = PCH_DPLL_A;
- dpll_b_reg = PCH_DPLL_B;
- fpa0_reg = PCH_FPA0;
- fpb0_reg = PCH_FPB0;
- fpa1_reg = PCH_FPA1;
- fpb1_reg = PCH_FPB1;
- } else {
- dpll_a_reg = DPLL_A;
- dpll_b_reg = DPLL_B;
- fpa0_reg = FPA0;
- fpb0_reg = FPB0;
- fpa1_reg = FPA1;
- fpb1_reg = FPB1;
- }
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
- I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
- }
-
- /* Pipe & plane A info */
- /* Prime the clock */
- if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
- ~DPLL_VCO_ENABLE);
- DRM_UDELAY(150);
- }
- I915_WRITE(fpa0_reg, dev_priv->saveFPA0);
- I915_WRITE(fpa1_reg, dev_priv->saveFPA1);
- /* Actually enable it */
- I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
- DRM_UDELAY(150);
- if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
- DRM_UDELAY(150);
-
- /* Restore mode */
- I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
- I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
- I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
- I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
- I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
- I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
- I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
- I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
- I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
-
- I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
- I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
-
- I915_WRITE(PFA_CTL_1, dev_priv->savePFA_CTL_1);
- I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
- I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
-
- I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
- I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
- I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
- I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
- I915_WRITE(TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A);
- I915_WRITE(TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A);
- I915_WRITE(TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A);
- } else {
- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
- }
-
- /* Restore plane info */
- I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
- I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
- I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
- I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
- I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
- if (IS_I965G(dev_priv)) {
- I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
- I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
- }
-
- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
-
- i915_restore_palette(dev_priv, PIPE_A);
- /* Enable the plane */
- I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
- I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
-
- /* Pipe & plane B info */
- if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
- ~DPLL_VCO_ENABLE);
- DRM_UDELAY(150);
- }
- I915_WRITE(fpb0_reg, dev_priv->saveFPB0);
- I915_WRITE(fpb1_reg, dev_priv->saveFPB1);
- /* Actually enable it */
- I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
- DRM_UDELAY(150);
- if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
- DRM_UDELAY(150);
-
- /* Restore mode */
- I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
- I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
- I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
- I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
- I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
- I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
- I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
- I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
- I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
-
- I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
- I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
-
- I915_WRITE(PFB_CTL_1, dev_priv->savePFB_CTL_1);
- I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
- I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
-
- I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
- I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
- I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
- I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
- I915_WRITE(TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B);
- I915_WRITE(TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B);
- I915_WRITE(TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B);
- } else {
- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
- }
-
- /* Restore plane info */
- I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
- I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
- I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
- I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
- I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
- if (IS_I965G(dev_priv)) {
- I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
- I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
- }
-
- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
-
- i915_restore_palette(dev_priv, PIPE_B);
- /* Enable the plane */
- I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
- I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
-}
-
-int
-inteldrm_save_display(struct inteldrm_softc *dev_priv)
-{
- /* Display arbitration control */
- dev_priv->saveDSPARB = I915_READ(DSPARB);
-
- /* This is only meaningful in non-KMS mode */
- /* Don't save them in KMS mode */
- i915_save_modeset_reg(dev_priv);
- /* Cursor state */
- dev_priv->saveCURACNTR = I915_READ(CURACNTR);
- dev_priv->saveCURAPOS = I915_READ(CURAPOS);
- dev_priv->saveCURABASE = I915_READ(CURABASE);
- dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
- dev_priv->saveCURBPOS = I915_READ(CURBPOS);
- dev_priv->saveCURBBASE = I915_READ(CURBBASE);
- if (!IS_I9XX(dev_priv))
- dev_priv->saveCURSIZE = I915_READ(CURSIZE);
-
- /* CRT state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->saveADPA = I915_READ(PCH_ADPA);
- } else {
- dev_priv->saveADPA = I915_READ(ADPA);
- }
-
- /* LVDS state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
- dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
- dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
- dev_priv->saveLVDS = I915_READ(PCH_LVDS);
- } else {
- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
- dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
- if (IS_I965G(dev_priv))
- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
- if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
- dev_priv->saveLVDS = I915_READ(LVDS);
- }
-
- if (!IS_I830(dev_priv) && !IS_845G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
- dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
- dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
- } else {
- dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
- dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
- }
-
- /* FIXME: save TV & SDVO state */
-
- /* FBC state XXX only if supported */
- if (IS_GM45(dev_priv)) {
- dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
- } else {
- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
- }
-
- /* VGA state */
- dev_priv->saveVGA0 = I915_READ(VGA0);
- dev_priv->saveVGA1 = I915_READ(VGA1);
- dev_priv->saveVGA_PD = I915_READ(VGA_PD);
- if (HAS_PCH_SPLIT(dev_priv))
- dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
- else
- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
-
- i915_save_vga(dev_priv);
-
- return 0;
-}
-
-int
-inteldrm_restore_display(struct inteldrm_softc *dev_priv)
-{
- /* Display arbitration */
- I915_WRITE(DSPARB, dev_priv->saveDSPARB);
-
- /* This is only meaningful in non-KMS mode */
- /* Don't restore them in KMS mode */
- i915_restore_modeset_reg(dev_priv);
- /* Cursor state */
- I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
- I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
- I915_WRITE(CURABASE, dev_priv->saveCURABASE);
- I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
- I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
- I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
- if (!IS_I9XX(dev_priv))
- I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
-
- /* CRT state */
- if (HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
- else
- I915_WRITE(ADPA, dev_priv->saveADPA);
-
- /* LVDS state */
- if (IS_I965G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
- } else if (IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
- I915_WRITE(LVDS, dev_priv->saveLVDS);
-
- if (!IS_I830(dev_priv) && !IS_845G(dev_priv) && !HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
-
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
- I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
- I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
- I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2);
- I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
- I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
- I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
- I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL);
- I915_WRITE(MCHBAR_RENDER_STANDBY,
- dev_priv->saveMCHBAR_RENDER_STANDBY);
- } else {
- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
- I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL);
- I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
- I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
- }
-
- /* FIXME: restore TV & SDVO state */
-
- /* FBC info */
- if (IS_GM45(dev_priv)) {
- I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
- } else {
- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
- }
-
- /* VGA state */
- if (HAS_PCH_SPLIT(dev_priv))
- I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
- else
- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
- I915_WRITE(VGA0, dev_priv->saveVGA0);
- I915_WRITE(VGA1, dev_priv->saveVGA1);
- I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
- DRM_UDELAY(150);
-
- i915_restore_vga(dev_priv);
-
- return 0;
-}
-
-int
-inteldrm_save_state(struct inteldrm_softc *dev_priv)
-{
- int i;
-
- dev_priv->saveLBB = pci_conf_read(dev_priv->pc, dev_priv->tag, LBB);
-
- /* Hardware status page */
- if (IS_GEN6(dev_priv)) {
- dev_priv->saveHWS = I915_READ(HWS_PGA_GEN6);
- } else {
- dev_priv->saveHWS = I915_READ(HWS_PGA);
- }
-
- inteldrm_save_display(dev_priv);
-
- /* Interrupt state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->saveDEIER = I915_READ(DEIER);
- dev_priv->saveDEIMR = I915_READ(DEIMR);
- dev_priv->saveGTIER = I915_READ(GTIER);
- dev_priv->saveGTIMR = I915_READ(GTIMR);
- dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR);
- dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR);
- dev_priv->saveMCHBAR_RENDER_STANDBY =
- I915_READ(MCHBAR_RENDER_STANDBY);
- } else {
- dev_priv->saveIER = I915_READ(IER);
- dev_priv->saveIMR = I915_READ(IMR);
- }
-
- /* Clock gating state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- dev_priv->saveDSPCLK_GATE_D = I915_READ(PCH_DSPCLK_GATE_D);
- dev_priv->saveDSPCLK_GATE = I915_READ(ILK_DSPCLK_GATE);
- } else if (IS_G4X(dev_priv)) {
- dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
- dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
- dev_priv->saveRAMCLK_GATE_D = I915_READ(RAMCLK_GATE_D);
- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
- } else if (IS_I965GM(dev_priv)) {
- dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
- dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
- dev_priv->saveRAMCLK_GATE_D = I915_READ(RAMCLK_GATE_D);
- dev_priv->saveDEUC = I915_READ16(DEUC);
- } else if (IS_I965G(dev_priv)) {
- dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
- dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
- } else if (IS_I9XX(dev_priv)) {
- dev_priv->saveD_STATE = I915_READ(D_STATE);
- } else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) {
- dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
- } else if (IS_I830(dev_priv)) {
- 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(SWF00 + (i << 2));
- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
- }
- for (i = 0; i < 3; i++)
- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
-
- /* Fences */
- if (IS_GEN6(dev_priv)) {
- for (i = 0; i < 16; i++)
- dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 +
- (i * 8));
- } else if (IS_I965G(dev_priv)) {
- for (i = 0; i < 16; i++)
- dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 +
- (i * 8));
- } else {
- for (i = 0; i < 8; i++)
- dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
-
- if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
- IS_G33(dev_priv))
- for (i = 0; i < 8; i++)
- dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
- }
-
- return 0;
-}
-
-int
-inteldrm_restore_state(struct inteldrm_softc *dev_priv)
-{
- int i;
-
- pci_conf_write(dev_priv->pc, dev_priv->tag, LBB, dev_priv->saveLBB);
-
- /* Hardware status page */
- if (IS_GEN6(dev_priv))
- I915_WRITE(HWS_PGA_GEN6, dev_priv->saveHWS);
- else
- I915_WRITE(HWS_PGA, dev_priv->saveHWS);
-
- /* Fences */
- if (IS_GEN6(dev_priv)) {
- for (i = 0; i < 16; i++)
- I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
- } else if (IS_I965G(dev_priv)) {
- for (i = 0; i < 16; i++)
- I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
- } else {
- for (i = 0; i < 8; i++)
- I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
- if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
- IS_G33(dev_priv))
- for (i = 0; i < 8; i++)
- I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
- }
-
- inteldrm_restore_display(dev_priv);
-
- /* Interrupt state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(DEIER, dev_priv->saveDEIER);
- I915_WRITE(DEIMR, dev_priv->saveDEIMR);
- I915_WRITE(GTIER, dev_priv->saveGTIER);
- I915_WRITE(GTIMR, dev_priv->saveGTIMR);
- I915_WRITE(FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR);
- I915_WRITE(FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR);
- } else {
- I915_WRITE (IER, dev_priv->saveIER);
- I915_WRITE (IMR, dev_priv->saveIMR);
- }
-
- /* Clock gating state */
- if (HAS_PCH_SPLIT(dev_priv)) {
- I915_WRITE(PCH_DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
- I915_WRITE(ILK_DSPCLK_GATE, dev_priv->saveDSPCLK_GATE);
- } if (IS_G4X(dev_priv)) {
- I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
- I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
- I915_WRITE(RAMCLK_GATE_D, dev_priv->saveRAMCLK_GATE_D);
- I915_WRITE(DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
- } else if (IS_I965GM(dev_priv)) {
- I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
- I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
- I915_WRITE(DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
- I915_WRITE(RAMCLK_GATE_D, dev_priv->saveRAMCLK_GATE_D);
- I915_WRITE16(DEUC, dev_priv->saveDEUC);
- } else if (IS_I965G(dev_priv)) {
- I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
- I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
- } else if (IS_I9XX(dev_priv)) {
- I915_WRITE(D_STATE, dev_priv->saveD_STATE);
- } else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) {
- I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
- } else if (IS_I830(dev_priv)) {
- 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(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
- I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]);
- }
- for (i = 0; i < 3; i++)
- I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
-
- return 0;
-}
-
/*
* Reset the chip after a hang (965 only)
*
@@ -5996,7 +5143,7 @@ inteldrm_965_reset(struct inteldrm_softc *dev_priv, u_int8_t flags)
flags = GDRST_FULL;
if (flags == GDRST_FULL)
- inteldrm_save_display(dev_priv);
+ i915_save_display(dev_priv);
reg = pci_conf_read(dev_priv->pc, dev_priv->tag, GDRST);
/*
@@ -6062,7 +5209,7 @@ inteldrm_965_reset(struct inteldrm_softc *dev_priv, u_int8_t flags)
if (flags == GDRST_FULL)
- inteldrm_restore_display(dev_priv);
+ i915_restore_display(dev_priv);
}
/*
@@ -6134,9 +5281,9 @@ i915_interrupt_info(int kdev)
printf("Interrupt mask: %08x\n",
I915_READ(IMR));
printf("Pipe A stat: %08x\n",
- I915_READ(PIPEASTAT));
+ I915_READ(_PIPEASTAT));
printf("Pipe B stat: %08x\n",
- I915_READ(PIPEBSTAT));
+ I915_READ(_PIPEBSTAT));
printf("Interrupts received: 0\n");
if (dev_priv->hw_status_page != NULL) {
printf("Current sequence: %d\n",
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 18db31b15cc..900c8622f50 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_drv.h,v 1.70 2011/09/14 10:26:16 oga Exp $ */
+/* $OpenBSD: i915_drv.h,v 1.71 2012/05/19 18:02:53 kettenis Exp $ */
/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
*/
/*
@@ -95,6 +95,7 @@ struct inteldrm_softc {
u_long flags;
u_int16_t pci_device;
+ int gen;
pci_chipset_tag_t pc;
pcitag_t tag;
@@ -311,6 +312,7 @@ struct inteldrm_softc {
u32 savePIPEB_LINK_M1;
u32 savePIPEB_LINK_N1;
u32 saveMCHBAR_RENDER_STANDBY;
+ u32 savePCH_PORT_HOTPLUG;
struct {
/**
@@ -519,6 +521,13 @@ extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern void i915_user_irq_get(struct inteldrm_softc *);
extern void i915_user_irq_put(struct inteldrm_softc *);
+/* i915_suspend.c */
+
+extern void i915_save_display(struct inteldrm_softc *);
+extern void i915_restore_display(struct inteldrm_softc *);
+extern int i915_save_state(struct inteldrm_softc *);
+extern int i915_restore_state(struct inteldrm_softc *);
+
/* XXX need bus_space_write_8, this evaluated arguments twice */
static __inline void
write64(struct inteldrm_softc *dev_priv, bus_size_t off, u_int64_t reg)
@@ -558,6 +567,10 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
dev_priv->regs->bsh, (reg))
#define I915_WRITE8(reg,val) bus_space_write_1(dev_priv->regs->bst, \
dev_priv->regs->bsh, (reg), (val))
+
+#define POSTING_READ(reg) (void)I915_READ(reg)
+#define POSTING_READ16(reg) (void)I915_READ16(reg)
+
#define INTELDRM_VERBOSE 0
#if INTELDRM_VERBOSE > 0
#define INTELDRM_VPRINTF(fmt, args...) DRM_INFO(fmt, ##args)
@@ -573,6 +586,8 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define I915_IFPADDR 0x60
#define I965_IFPADDR 0x70
+#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a)))
+
/*
* The Bridge device's PCI config space has information about the
* fb aperture size and the amount of pre-reserved memory.
@@ -974,6 +989,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define DPFC_CTL_PLANEA (0<<30)
#define DPFC_CTL_PLANEB (1<<30)
#define DPFC_CTL_FENCE_EN (1<<29)
+#define DPFC_CTL_PERSISTENT_MODE (1<<25)
#define DPFC_SR_EN (1<<10)
#define DPFC_CTL_LIMIT_1X (0<<6)
#define DPFC_CTL_LIMIT_2X (1<<6)
@@ -994,6 +1010,33 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define DPFC_CHICKEN 0x3224
#define DPFC_HT_MODIFY (1<<31)
+/* Framebuffer compression for Ironlake */
+#define ILK_DPFC_CB_BASE 0x43200
+#define ILK_DPFC_CONTROL 0x43208
+/* The bit 28-8 is reserved */
+#define DPFC_RESERVED (0x1FFFFF00)
+#define ILK_DPFC_RECOMP_CTL 0x4320c
+#define ILK_DPFC_STATUS 0x43210
+#define ILK_DPFC_FENCE_YOFF 0x43218
+#define ILK_DPFC_CHICKEN 0x43224
+#define ILK_FBC_RT_BASE 0x2128
+#define ILK_FBC_RT_VALID (1<<0)
+
+#define ILK_DISPLAY_CHICKEN1 0x42000
+#define ILK_FBCQ_DIS (1<<22)
+#define ILK_PABSTRETCH_DIS (1<<21)
+
+
+/*
+ * Framebuffer compression for Sandybridge
+ *
+ * The following two registers are of type GTTMMADR
+ */
+#define SNB_DPFC_CTL_SA 0x100100
+#define SNB_CPU_FENCE_ENABLE (1<<29)
+#define DPFC_CPU_FENCE_OFFSET 0x100104
+
+
/*
* GPIO regs
*/
@@ -1035,8 +1078,9 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define VGA1_PD_P1_DIV_2 (1 << 13)
#define VGA1_PD_P1_SHIFT 8
#define VGA1_PD_P1_MASK (0x1f << 8)
-#define DPLL_A 0x06014
-#define DPLL_B 0x06018
+#define _DPLL_A 0x06014
+#define _DPLL_B 0x06018
+#define DPLL(pipe) _PIPE(pipe, _DPLL_A, _DPLL_B)
#define DPLL_VCO_ENABLE (1 << 31)
#define DPLL_DVO_HIGH_SPEED (1 << 30)
#define DPLL_SYNCLOCK_ENABLE (1 << 29)
@@ -1157,7 +1201,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define SDVO_MULTIPLIER_MASK 0x000000ff
#define SDVO_MULTIPLIER_SHIFT_HIRES 4
#define SDVO_MULTIPLIER_SHIFT_VGA 0
-#define DPLL_A_MD 0x0601c /* 965+ only */
+#define _DPLL_A_MD 0x0601c /* 965+ only */
/*
* UDI pixel divider, controlling how many pixels are stuffed into a packet.
*
@@ -1194,11 +1238,14 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
*/
#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
-#define DPLL_B_MD 0x06020 /* 965+ only */
-#define FPA0 0x06040
-#define FPA1 0x06044
-#define FPB0 0x06048
-#define FPB1 0x0604c
+#define _DPLL_B_MD 0x06020 /* 965+ only */
+#define DPLL_MD(pipe) _PIPE(pipe, _DPLL_A_MD, _DPLL_B_MD)
+#define _FPA0 0x06040
+#define _FPA1 0x06044
+#define _FPB0 0x06048
+#define _FPB1 0x0604c
+#define FP0(pipe) _PIPE(pipe, _FPA0, _FPB0)
+#define FP1(pipe) _PIPE(pipe, _FPA1, _FPB1)
#define FP_N_DIV_MASK 0x003f0000
#define FP_N_IGD_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16
@@ -1336,8 +1383,9 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
* Palette regs
*/
-#define PALETTE_A 0x0a000
-#define PALETTE_B 0x0a800
+#define _PALETTE_A 0x0a000
+#define _PALETTE_B 0x0a800
+#define PALETTE(pipe) _PIPE(pipe, _PALETTE_A, _PALETTE_B)
/* MCH MMIO space */
@@ -1381,8 +1429,7 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define CLKCFG_MEM_800 (3 << 4)
#define CLKCFG_MEM_MASK (7 << 4)
-/** GM965 GM45 render standby register */
-#define MCHBAR_RENDER_STANDBY 0x111B8
+#define RSTDBYCTL 0x111b8
#define PEG_BAND_GAP_DATA 0x14d68
@@ -1405,24 +1452,36 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
*/
/* Pipe A timing regs */
-#define HTOTAL_A 0x60000
-#define HBLANK_A 0x60004
-#define HSYNC_A 0x60008
-#define VTOTAL_A 0x6000c
-#define VBLANK_A 0x60010
-#define VSYNC_A 0x60014
-#define PIPEASRC 0x6001c
-#define BCLRPAT_A 0x60020
+#define _HTOTAL_A 0x60000
+#define _HBLANK_A 0x60004
+#define _HSYNC_A 0x60008
+#define _VTOTAL_A 0x6000c
+#define _VBLANK_A 0x60010
+#define _VSYNC_A 0x60014
+#define _PIPEASRC 0x6001c
+#define _BCLRPAT_A 0x60020
+#define _VSYNCSHIFT_A 0x60028
/* Pipe B timing regs */
-#define HTOTAL_B 0x61000
-#define HBLANK_B 0x61004
-#define HSYNC_B 0x61008
-#define VTOTAL_B 0x6100c
-#define VBLANK_B 0x61010
-#define VSYNC_B 0x61014
-#define PIPEBSRC 0x6101c
-#define BCLRPAT_B 0x61020
+#define _HTOTAL_B 0x61000
+#define _HBLANK_B 0x61004
+#define _HSYNC_B 0x61008
+#define _VTOTAL_B 0x6100c
+#define _VBLANK_B 0x61010
+#define _VSYNC_B 0x61014
+#define _PIPEBSRC 0x6101c
+#define _BCLRPAT_B 0x61020
+#define _VSYNCSHIFT_B 0x61028
+
+
+#define HTOTAL(pipe) _PIPE(pipe, _HTOTAL_A, _HTOTAL_B)
+#define HBLANK(pipe) _PIPE(pipe, _HBLANK_A, _HBLANK_B)
+#define HSYNC(pipe) _PIPE(pipe, _HSYNC_A, _HSYNC_B)
+#define VTOTAL(pipe) _PIPE(pipe, _VTOTAL_A, _VTOTAL_B)
+#define VBLANK(pipe) _PIPE(pipe, _VBLANK_A, _VBLANK_B)
+#define VSYNC(pipe) _PIPE(pipe, _VSYNC_A, _VSYNC_B)
+#define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B)
+#define VSYNCSHIFT(pipe) _PIPE(pipe, _VSYNCSHIFT_A, _VSYNCSHIFT_B)
/* VGA port control */
#define ADPA 0x61100
@@ -2286,22 +2345,48 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
/* Display & cursor control */
/* Pipe A */
-#define PIPEADSL 0x70000
-#define PIPEACONF 0x70008
-#define PIPEACONF_ENABLE (1<<31)
-#define PIPEACONF_DISABLE 0
-#define PIPEACONF_DOUBLE_WIDE (1<<30)
+#define _PIPEADSL 0x70000
+#define DSL_LINEMASK 0x00000fff
+#define _PIPEACONF 0x70008
+#define PIPECONF_ENABLE (1<<31)
+#define PIPECONF_DISABLE 0
+#define PIPECONF_DOUBLE_WIDE (1<<30)
#define I965_PIPECONF_ACTIVE (1<<30)
-#define PIPEACONF_SINGLE_WIDE 0
-#define PIPEACONF_PIPE_UNLOCKED 0
-#define PIPEACONF_PIPE_LOCKED (1<<25)
-#define PIPEACONF_PALETTE 0
-#define PIPEACONF_GAMMA (1<<24)
+#define PIPECONF_FRAME_START_DELAY_MASK (3<<27)
+#define PIPECONF_SINGLE_WIDE 0
+#define PIPECONF_PIPE_UNLOCKED 0
+#define PIPECONF_PIPE_LOCKED (1<<25)
+#define PIPECONF_PALETTE 0
+#define PIPECONF_GAMMA (1<<24)
#define PIPECONF_FORCE_BORDER (1<<25)
-#define PIPECONF_PROGRESSIVE (0 << 21)
+#define PIPECONF_INTERLACE_MASK (7 << 21)
+/* Note that pre-gen3 does not support interlaced display directly. Panel
+ * fitting must be disabled on pre-ilk for interlaced. */
+#define PIPECONF_PROGRESSIVE (0 << 21)
+#define PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL (4 << 21) /* gen4 only */
+#define PIPECONF_INTERLACE_W_SYNC_SHIFT (5 << 21) /* gen4 only */
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
-#define PIPEASTAT 0x70024
+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* gen3 only */
+/* Ironlake and later have a complete new set of values for interlaced. PFIT
+ * means panel fitter required, PF means progressive fetch, DBL means power
+ * saving pixel doubling. */
+#define PIPECONF_PFIT_PF_INTERLACED_ILK (1 << 21)
+#define PIPECONF_INTERLACED_ILK (3 << 21)
+#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */
+#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */
+#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
+#define PIPECONF_BPP_MASK (0x000000e0)
+#define PIPECONF_BPP_8 (0<<5)
+#define PIPECONF_BPP_10 (1<<5)
+#define PIPECONF_BPP_6 (2<<5)
+#define PIPECONF_BPP_12 (3<<5)
+#define PIPECONF_DITHER_EN (1<<4)
+#define PIPECONF_DITHER_TYPE_MASK (0x0000000c)
+#define PIPECONF_DITHER_TYPE_SP (0<<2)
+#define PIPECONF_DITHER_TYPE_ST1 (1<<2)
+#define PIPECONF_DITHER_TYPE_ST2 (2<<2)
+#define PIPECONF_DITHER_TYPE_TEMP (3<<2)
+#define _PIPEASTAT 0x70024
#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
#define PIPE_CRC_DONE_ENABLE (1UL<<28)
@@ -2331,6 +2416,18 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
+#define PIPE_BPC_MASK (7 << 5) /* Ironlake */
+#define PIPE_8BPC (0 << 5)
+#define PIPE_10BPC (1 << 5)
+#define PIPE_6BPC (2 << 5)
+#define PIPE_12BPC (3 << 5)
+
+#define PIPESRC(pipe) _PIPE(pipe, _PIPEASRC, _PIPEBSRC)
+#define PIPECONF(pipe) _PIPE(pipe, _PIPEACONF, _PIPEBCONF)
+#define PIPEDSL(pipe) _PIPE(pipe, _PIPEADSL, _PIPEBDSL)
+#define PIPEFRAME(pipe) _PIPE(pipe, _PIPEAFRAMEHIGH, _PIPEBFRAMEHIGH)
+#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL)
+#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT)
#define DSPARB 0x70030
#define DSPARB_CSTART_MASK (0x7f << 7)
@@ -2352,37 +2449,66 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
* } while (high1 != high2);
* frame = (high1 << 8) | low1;
*/
-#define PIPEAFRAMEHIGH 0x70040
+#define _PIPEAFRAMEHIGH 0x70040
#define PIPE_FRAME_HIGH_MASK 0x0000ffff
#define PIPE_FRAME_HIGH_SHIFT 0
-#define PIPEAFRAMEPIXEL 0x70044
+#define _PIPEAFRAMEPIXEL 0x70044
#define PIPE_FRAME_LOW_MASK 0xff000000
#define PIPE_FRAME_LOW_SHIFT 24
#define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0
/* GM45+ just has to be different */
-#define PIPEA_FRMCOUNT_GM45 0x70040
-#define PIPEA_FLIPCOUNT_GM45 0x70044
+#define _PIPEA_FRMCOUNT_GM45 0x70040
+#define _PIPEA_FLIPCOUNT_GM45 0x70044
+#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45)
/* Cursor A & B regs */
-#define CURACNTR 0x70080
+#define _CURACNTR 0x70080
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define CURSOR_ENABLE 0x80000000
+#define CURSOR_GAMMA_ENABLE 0x40000000
+#define CURSOR_STRIDE_MASK 0x30000000
+#define CURSOR_FORMAT_SHIFT 24
+#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT)
+#define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT)
+/* New style CUR*CNTR flags */
+#define CURSOR_MODE 0x27
#define CURSOR_MODE_DISABLE 0x00
#define CURSOR_MODE_64_32B_AX 0x07
#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define MCURSOR_PIPE_SELECT (1 << 28)
+#define MCURSOR_PIPE_A 0x00
+#define MCURSOR_PIPE_B (1 << 28)
#define MCURSOR_GAMMA_ENABLE (1 << 26)
-#define CURABASE 0x70084
-#define CURAPOS 0x70088
+#define _CURABASE 0x70084
+#define _CURAPOS 0x70088
#define CURSOR_POS_MASK 0x007FF
#define CURSOR_POS_SIGN 0x8000
#define CURSOR_X_SHIFT 0
#define CURSOR_Y_SHIFT 16
#define CURSIZE 0x700a0
-#define CURBCNTR 0x700c0
-#define CURBBASE 0x700c4
-#define CURBPOS 0x700c8
+#define _CURBCNTR 0x700c0
+#define _CURBBASE 0x700c4
+#define _CURBPOS 0x700c8
+
+#define _CURBCNTR_IVB 0x71080
+#define _CURBBASE_IVB 0x71084
+#define _CURBPOS_IVB 0x71088
+
+#define CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR)
+#define CURBASE(pipe) _PIPE(pipe, _CURABASE, _CURBBASE)
+#define CURPOS(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS)
+
+#define CURCNTR_IVB(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB)
+#define CURBASE_IVB(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB)
+#define CURPOS_IVB(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS_IVB)
/* Display A control */
-#define DSPACNTR 0x70180
+#define _DSPACNTR 0x70180
#define DISPLAY_PLANE_ENABLE (1<<31)
#define DISPLAY_PLANE_DISABLE 0
#define DISPPLANE_GAMMA_ENABLE (1<<30)
@@ -2393,24 +2519,35 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define DISPPLANE_16BPP (0x5<<26)
#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
#define DISPPLANE_32BPP (0x7<<26)
+#define DISPPLANE_32BPP_30BIT_NO_ALPHA (0xa<<26)
#define DISPPLANE_STEREO_ENABLE (1<<25)
#define DISPPLANE_STEREO_DISABLE 0
-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
+#define DISPPLANE_SEL_PIPE_SHIFT 24
+#define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT)
#define DISPPLANE_SEL_PIPE_A 0
-#define DISPPLANE_SEL_PIPE_B (1<<24)
+#define DISPPLANE_SEL_PIPE_B (1<<DISPPLANE_SEL_PIPE_SHIFT)
#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
#define DISPPLANE_SRC_KEY_DISABLE 0
#define DISPPLANE_LINE_DOUBLE (1<<20)
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
-#define DSPAADDR 0x70184
-#define DSPASTRIDE 0x70188
-#define DSPAPOS 0x7018C /* reserved */
-#define DSPASIZE 0x70190
-#define DSPASURF 0x7019C /* 965+ only */
-#define DSPATILEOFF 0x701A4 /* 965+ only */
-
+#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
+#define DISPPLANE_TILED (1<<10)
+#define _DSPAADDR 0x70184
+#define _DSPASTRIDE 0x70188
+#define _DSPAPOS 0x7018C /* reserved */
+#define _DSPASIZE 0x70190
+#define _DSPASURF 0x7019C /* 965+ only */
+#define _DSPATILEOFF 0x701A4 /* 965+ only */
+
+#define DSPCNTR(plane) _PIPE(plane, _DSPACNTR, _DSPBCNTR)
+#define DSPADDR(plane) _PIPE(plane, _DSPAADDR, _DSPBADDR)
+#define DSPSTRIDE(plane) _PIPE(plane, _DSPASTRIDE, _DSPBSTRIDE)
+#define DSPPOS(plane) _PIPE(plane, _DSPAPOS, _DSPBPOS)
+#define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE)
+#define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF)
+#define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF)
/* VBIOS flags */
#define SWF00 0x71410
#define SWF01 0x71414
@@ -2427,26 +2564,161 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define SWF32 0x7241c
/* Pipe B */
-#define PIPEBDSL 0x71000
-#define PIPEBCONF 0x71008
-#define PIPEBSTAT 0x71024
-#define PIPEBFRAMEHIGH 0x71040
-#define PIPEBFRAMEPIXEL 0x71044
-#define PIPEB_FRMCOUNT_GM45 0x71040
-#define PIPEB_FLIPCOUNT_GM45 0x71044
+#define _PIPEBDSL 0x71000
+#define _PIPEBCONF 0x71008
+#define _PIPEBSTAT 0x71024
+#define _PIPEBFRAMEHIGH 0x71040
+#define _PIPEBFRAMEPIXEL 0x71044
+#define _PIPEB_FRMCOUNT_GM45 0x71040
+#define _PIPEB_FLIPCOUNT_GM45 0x71044
+
/* Display B control */
-#define DSPBCNTR 0x71180
+#define _DSPBCNTR 0x71180
#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
#define DISPPLANE_ALPHA_TRANS_DISABLE 0
#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
-#define DSPBADDR 0x71184
-#define DSPBSTRIDE 0x71188
-#define DSPBPOS 0x7118C
-#define DSPBSIZE 0x71190
-#define DSPBSURF 0x7119C
-#define DSPBTILEOFF 0x711A4
+#define _DSPBADDR 0x71184
+#define _DSPBSTRIDE 0x71188
+#define _DSPBPOS 0x7118C
+#define _DSPBSIZE 0x71190
+#define _DSPBSURF 0x7119C
+#define _DSPBTILEOFF 0x711A4
+
+/* Sprite A control */
+#define _DVSACNTR 0x72180
+#define DVS_ENABLE (1<<31)
+#define DVS_GAMMA_ENABLE (1<<30)
+#define DVS_PIXFORMAT_MASK (3<<25)
+#define DVS_FORMAT_YUV422 (0<<25)
+#define DVS_FORMAT_RGBX101010 (1<<25)
+#define DVS_FORMAT_RGBX888 (2<<25)
+#define DVS_FORMAT_RGBX161616 (3<<25)
+#define DVS_SOURCE_KEY (1<<22)
+#define DVS_RGB_ORDER_XBGR (1<<20)
+#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define DVS_YUV_ORDER_YUYV (0<<16)
+#define DVS_YUV_ORDER_UYVY (1<<16)
+#define DVS_YUV_ORDER_YVYU (2<<16)
+#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_DEST_KEY (1<<2)
+#define DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define DVS_TILED (1<<10)
+#define _DVSALINOFF 0x72184
+#define _DVSASTRIDE 0x72188
+#define _DVSAPOS 0x7218c
+#define _DVSASIZE 0x72190
+#define _DVSAKEYVAL 0x72194
+#define _DVSAKEYMSK 0x72198
+#define _DVSASURF 0x7219c
+#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSATILEOFF 0x721a4
+#define _DVSASURFLIVE 0x721ac
+#define _DVSASCALE 0x72204
+#define DVS_SCALE_ENABLE (1<<31)
+#define DVS_FILTER_MASK (3<<29)
+#define DVS_FILTER_MEDIUM (0<<29)
+#define DVS_FILTER_ENHANCING (1<<29)
+#define DVS_FILTER_SOFTENING (2<<29)
+#define DVS_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */
+#define DVS_VERTICAL_OFFSET_ENABLE (1<<27)
+#define _DVSAGAMC 0x72300
+
+#define _DVSBCNTR 0x73180
+#define _DVSBLINOFF 0x73184
+#define _DVSBSTRIDE 0x73188
+#define _DVSBPOS 0x7318c
+#define _DVSBSIZE 0x73190
+#define _DVSBKEYVAL 0x73194
+#define _DVSBKEYMSK 0x73198
+#define _DVSBSURF 0x7319c
+#define _DVSBKEYMAXVAL 0x731a0
+#define _DVSBTILEOFF 0x731a4
+#define _DVSBSURFLIVE 0x731ac
+#define _DVSBSCALE 0x73204
+#define _DVSBGAMC 0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSLINOFF(pipe) _PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSKEYMAX(pipe) _PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
+
+#define _SPRA_CTL 0x70280
+#define SPRITE_ENABLE (1<<31)
+#define SPRITE_GAMMA_ENABLE (1<<30)
+#define SPRITE_PIXFORMAT_MASK (7<<25)
+#define SPRITE_FORMAT_YUV422 (0<<25)
+#define SPRITE_FORMAT_RGBX101010 (1<<25)
+#define SPRITE_FORMAT_RGBX888 (2<<25)
+#define SPRITE_FORMAT_RGBX161616 (3<<25)
+#define SPRITE_FORMAT_YUV444 (4<<25)
+#define SPRITE_FORMAT_XR_BGR101010 (5<<25) /* Extended range */
+#define SPRITE_CSC_ENABLE (1<<24)
+#define SPRITE_SOURCE_KEY (1<<22)
+#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
+#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
+#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
+#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
+#define SPRITE_YUV_ORDER_YUYV (0<<16)
+#define SPRITE_YUV_ORDER_UYVY (1<<16)
+#define SPRITE_YUV_ORDER_YVYU (2<<16)
+#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
+#define SPRITE_INT_GAMMA_ENABLE (1<<13)
+#define SPRITE_TILED (1<<10)
+#define SPRITE_DEST_KEY (1<<2)
+#define _SPRA_LINOFF 0x70284
+#define _SPRA_STRIDE 0x70288
+#define _SPRA_POS 0x7028c
+#define _SPRA_SIZE 0x70290
+#define _SPRA_KEYVAL 0x70294
+#define _SPRA_KEYMSK 0x70298
+#define _SPRA_SURF 0x7029c
+#define _SPRA_KEYMAX 0x702a0
+#define _SPRA_TILEOFF 0x702a4
+#define _SPRA_SCALE 0x70304
+#define SPRITE_SCALE_ENABLE (1<<31)
+#define SPRITE_FILTER_MASK (3<<29)
+#define SPRITE_FILTER_MEDIUM (0<<29)
+#define SPRITE_FILTER_ENHANCING (1<<29)
+#define SPRITE_FILTER_SOFTENING (2<<29)
+#define SPRITE_VERTICAL_OFFSET_HALF (1<<28) /* must be enabled below */
+#define SPRITE_VERTICAL_OFFSET_ENABLE (1<<27)
+#define _SPRA_GAMC 0x70400
+
+#define _SPRB_CTL 0x71280
+#define _SPRB_LINOFF 0x71284
+#define _SPRB_STRIDE 0x71288
+#define _SPRB_POS 0x7128c
+#define _SPRB_SIZE 0x71290
+#define _SPRB_KEYVAL 0x71294
+#define _SPRB_KEYMSK 0x71298
+#define _SPRB_SURF 0x7129c
+#define _SPRB_KEYMAX 0x712a0
+#define _SPRB_TILEOFF 0x712a4
+#define _SPRB_SCALE 0x71304
+#define _SPRB_GAMC 0x71400
+
+#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRLINOFF(pipe) _PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
+#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
/* VBIOS regs */
#define VGACNTRL 0x71400
@@ -2494,67 +2766,80 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff
-#define PIPEA_DATA_M1 0x60030
+#define _PIPEA_DATA_M1 0x60030
#define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */
#define TU_SIZE_MASK 0x7e000000
-#define PIPEA_DATA_M1_OFFSET 0
-#define PIPEA_DATA_N1 0x60034
-#define PIPEA_DATA_N1_OFFSET 0
+#define PIPE_DATA_M1_OFFSET 0
+#define _PIPEA_DATA_N1 0x60034
+#define PIPE_DATA_N1_OFFSET 0
-#define PIPEA_DATA_M2 0x60038
-#define PIPEA_DATA_M2_OFFSET 0
-#define PIPEA_DATA_N2 0x6003c
-#define PIPEA_DATA_N2_OFFSET 0
+#define _PIPEA_DATA_M2 0x60038
+#define PIPE_DATA_M2_OFFSET 0
+#define _PIPEA_DATA_N2 0x6003c
+#define PIPE_DATA_N2_OFFSET 0
-#define PIPEA_LINK_M1 0x60040
-#define PIPEA_LINK_M1_OFFSET 0
-#define PIPEA_LINK_N1 0x60044
-#define PIPEA_LINK_N1_OFFSET 0
+#define _PIPEA_LINK_M1 0x60040
+#define PIPE_LINK_M1_OFFSET 0
+#define _PIPEA_LINK_N1 0x60044
+#define PIPE_LINK_N1_OFFSET 0
-#define PIPEA_LINK_M2 0x60048
-#define PIPEA_LINK_M2_OFFSET 0
-#define PIPEA_LINK_N2 0x6004c
-#define PIPEA_LINK_N2_OFFSET 0
+#define _PIPEA_LINK_M2 0x60048
+#define PIPE_LINK_M2_OFFSET 0
+#define _PIPEA_LINK_N2 0x6004c
+#define PIPE_LINK_N2_OFFSET 0
/* PIPEB timing regs are same start from 0x61000 */
-#define PIPEB_DATA_M1 0x61030
-#define PIPEB_DATA_M1_OFFSET 0
-#define PIPEB_DATA_N1 0x61034
-#define PIPEB_DATA_N1_OFFSET 0
+#define _PIPEB_DATA_M1 0x61030
+#define _PIPEB_DATA_N1 0x61034
+
+#define _PIPEB_DATA_M2 0x61038
+#define _PIPEB_DATA_N2 0x6103c
-#define PIPEB_DATA_M2 0x61038
-#define PIPEB_DATA_M2_OFFSET 0
-#define PIPEB_DATA_N2 0x6103c
-#define PIPEB_DATA_N2_OFFSET 0
+#define _PIPEB_LINK_M1 0x61040
+#define _PIPEB_LINK_N1 0x61044
-#define PIPEB_LINK_M1 0x61040
-#define PIPEB_LINK_M1_OFFSET 0
-#define PIPEB_LINK_N1 0x61044
-#define PIPEB_LINK_N1_OFFSET 0
+#define _PIPEB_LINK_M2 0x61048
+#define _PIPEB_LINK_N2 0x6104c
-#define PIPEB_LINK_M2 0x61048
-#define PIPEB_LINK_M2_OFFSET 0
-#define PIPEB_LINK_N2 0x6104c
-#define PIPEB_LINK_N2_OFFSET 0
+#define PIPE_DATA_M1(pipe) _PIPE(pipe, _PIPEA_DATA_M1, _PIPEB_DATA_M1)
+#define PIPE_DATA_N1(pipe) _PIPE(pipe, _PIPEA_DATA_N1, _PIPEB_DATA_N1)
+#define PIPE_DATA_M2(pipe) _PIPE(pipe, _PIPEA_DATA_M2, _PIPEB_DATA_M2)
+#define PIPE_DATA_N2(pipe) _PIPE(pipe, _PIPEA_DATA_N2, _PIPEB_DATA_N2)
+#define PIPE_LINK_M1(pipe) _PIPE(pipe, _PIPEA_LINK_M1, _PIPEB_LINK_M1)
+#define PIPE_LINK_N1(pipe) _PIPE(pipe, _PIPEA_LINK_N1, _PIPEB_LINK_N1)
+#define PIPE_LINK_M2(pipe) _PIPE(pipe, _PIPEA_LINK_M2, _PIPEB_LINK_M2)
+#define PIPE_LINK_N2(pipe) _PIPE(pipe, _PIPEA_LINK_N2, _PIPEB_LINK_N2)
/* CPU panel fitter */
-#define PFA_CTL_1 0x68080
-#define PFB_CTL_1 0x68880
+/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */
+#define _PFA_CTL_1 0x68080
+#define _PFB_CTL_1 0x68880
#define PF_ENABLE (1<<31)
#define PF_FILTER_MASK (3<<23)
#define PF_FILTER_PROGRAMMED (0<<23)
#define PF_FILTER_MED_3x3 (1<<23)
#define PF_FILTER_EDGE_ENHANCE (2<<23)
#define PF_FILTER_EDGE_SOFTEN (3<<23)
-#define PFA_WIN_SZ 0x68074
-#define PFB_WIN_SZ 0x68874
-#define PFA_WIN_POS 0x68070
-#define PFB_WIN_POS 0x68870
+#define _PFA_WIN_SZ 0x68074
+#define _PFB_WIN_SZ 0x68874
+#define _PFA_WIN_POS 0x68070
+#define _PFB_WIN_POS 0x68870
+#define _PFA_VSCALE 0x68084
+#define _PFB_VSCALE 0x68884
+#define _PFA_HSCALE 0x68090
+#define _PFB_HSCALE 0x68890
+
+#define PF_CTL(pipe) _PIPE(pipe, _PFA_CTL_1, _PFB_CTL_1)
+#define PF_WIN_SZ(pipe) _PIPE(pipe, _PFA_WIN_SZ, _PFB_WIN_SZ)
+#define PF_WIN_POS(pipe) _PIPE(pipe, _PFA_WIN_POS, _PFB_WIN_POS)
+#define PF_VSCALE(pipe) _PIPE(pipe, _PFA_VSCALE, _PFB_VSCALE)
+#define PF_HSCALE(pipe) _PIPE(pipe, _PFA_HSCALE, _PFB_HSCALE)
/* legacy palette */
-#define LGC_PALETTE_A 0x4a000
-#define LGC_PALETTE_B 0x4a800
+#define _LGC_PALETTE_A 0x4a000
+#define _LGC_PALETTE_B 0x4a800
+#define LGC_PALETTE(pipe) _PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B)
/* interrupts */
#define DE_MASTER_IRQ_CONTROL (1 << 31)
@@ -2669,13 +2954,17 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define PCH_GMBUS4 0xc5110
#define PCH_GMBUS5 0xc5120
-#define PCH_DPLL_A 0xc6014
-#define PCH_DPLL_B 0xc6018
+#define _PCH_DPLL_A 0xc6014
+#define _PCH_DPLL_B 0xc6018
+#define PCH_DPLL(pipe) (pipe == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
-#define PCH_FPA0 0xc6040
-#define PCH_FPA1 0xc6044
-#define PCH_FPB0 0xc6048
-#define PCH_FPB1 0xc604c
+#define _PCH_FPA0 0xc6040
+#define FP_CB_TUNE (0x3<<22)
+#define _PCH_FPA1 0xc6044
+#define _PCH_FPB0 0xc6048
+#define _PCH_FPB1 0xc604c
+#define PCH_FP0(pipe) (pipe == 0 ? _PCH_FPA0 : _PCH_FPB0)
+#define PCH_FP1(pipe) (pipe == 0 ? _PCH_FPA1 : _PCH_FPB1)
#define PCH_DPLL_TEST 0xc606c
@@ -2726,52 +3015,87 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
/* transcoder */
-#define TRANS_HTOTAL_A 0xe0000
+#define _TRANS_HTOTAL_A 0xe0000
#define TRANS_HTOTAL_SHIFT 16
#define TRANS_HACTIVE_SHIFT 0
-#define TRANS_HBLANK_A 0xe0004
+#define _TRANS_HBLANK_A 0xe0004
#define TRANS_HBLANK_END_SHIFT 16
#define TRANS_HBLANK_START_SHIFT 0
-#define TRANS_HSYNC_A 0xe0008
+#define _TRANS_HSYNC_A 0xe0008
#define TRANS_HSYNC_END_SHIFT 16
#define TRANS_HSYNC_START_SHIFT 0
-#define TRANS_VTOTAL_A 0xe000c
+#define _TRANS_VTOTAL_A 0xe000c
#define TRANS_VTOTAL_SHIFT 16
#define TRANS_VACTIVE_SHIFT 0
-#define TRANS_VBLANK_A 0xe0010
+#define _TRANS_VBLANK_A 0xe0010
#define TRANS_VBLANK_END_SHIFT 16
#define TRANS_VBLANK_START_SHIFT 0
-#define TRANS_VSYNC_A 0xe0014
+#define _TRANS_VSYNC_A 0xe0014
#define TRANS_VSYNC_END_SHIFT 16
#define TRANS_VSYNC_START_SHIFT 0
-
-#define TRANSA_DATA_M1 0xe0030
-#define TRANSA_DATA_N1 0xe0034
-#define TRANSA_DATA_M2 0xe0038
-#define TRANSA_DATA_N2 0xe003c
-#define TRANSA_DP_LINK_M1 0xe0040
-#define TRANSA_DP_LINK_N1 0xe0044
-#define TRANSA_DP_LINK_M2 0xe0048
-#define TRANSA_DP_LINK_N2 0xe004c
-
-#define TRANS_HTOTAL_B 0xe1000
-#define TRANS_HBLANK_B 0xe1004
-#define TRANS_HSYNC_B 0xe1008
-#define TRANS_VTOTAL_B 0xe100c
-#define TRANS_VBLANK_B 0xe1010
-#define TRANS_VSYNC_B 0xe1014
-
-#define TRANSB_DATA_M1 0xe1030
-#define TRANSB_DATA_N1 0xe1034
-#define TRANSB_DATA_M2 0xe1038
-#define TRANSB_DATA_N2 0xe103c
-#define TRANSB_DP_LINK_M1 0xe1040
-#define TRANSB_DP_LINK_N1 0xe1044
-#define TRANSB_DP_LINK_M2 0xe1048
-#define TRANSB_DP_LINK_N2 0xe104c
-
-#define TRANSACONF 0xf0008
-#define TRANSBCONF 0xf1008
+#define _TRANS_VSYNCSHIFT_A 0xe0028
+
+#define _TRANSA_DATA_M1 0xe0030
+#define _TRANSA_DATA_N1 0xe0034
+#define _TRANSA_DATA_M2 0xe0038
+#define _TRANSA_DATA_N2 0xe003c
+#define _TRANSA_DP_LINK_M1 0xe0040
+#define _TRANSA_DP_LINK_N1 0xe0044
+#define _TRANSA_DP_LINK_M2 0xe0048
+#define _TRANSA_DP_LINK_N2 0xe004c
+
+/* Per-transcoder DIP controls */
+
+#define _VIDEO_DIP_CTL_A 0xe0200
+#define _VIDEO_DIP_DATA_A 0xe0208
+#define _VIDEO_DIP_GCP_A 0xe0210
+
+#define _VIDEO_DIP_CTL_B 0xe1200
+#define _VIDEO_DIP_DATA_B 0xe1208
+#define _VIDEO_DIP_GCP_B 0xe1210
+
+#define TVIDEO_DIP_CTL(pipe) _PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B)
+#define TVIDEO_DIP_DATA(pipe) _PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
+#define TVIDEO_DIP_GCP(pipe) _PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
+
+#define _TRANS_HTOTAL_B 0xe1000
+#define _TRANS_HBLANK_B 0xe1004
+#define _TRANS_HSYNC_B 0xe1008
+#define _TRANS_VTOTAL_B 0xe100c
+#define _TRANS_VBLANK_B 0xe1010
+#define _TRANS_VSYNC_B 0xe1014
+#define _TRANS_VSYNCSHIFT_B 0xe1028
+
+#define TRANS_HTOTAL(pipe) _PIPE(pipe, _TRANS_HTOTAL_A, _TRANS_HTOTAL_B)
+#define TRANS_HBLANK(pipe) _PIPE(pipe, _TRANS_HBLANK_A, _TRANS_HBLANK_B)
+#define TRANS_HSYNC(pipe) _PIPE(pipe, _TRANS_HSYNC_A, _TRANS_HSYNC_B)
+#define TRANS_VTOTAL(pipe) _PIPE(pipe, _TRANS_VTOTAL_A, _TRANS_VTOTAL_B)
+#define TRANS_VBLANK(pipe) _PIPE(pipe, _TRANS_VBLANK_A, _TRANS_VBLANK_B)
+#define TRANS_VSYNC(pipe) _PIPE(pipe, _TRANS_VSYNC_A, _TRANS_VSYNC_B)
+#define TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _TRANS_VSYNCSHIFT_A, \
+ _TRANS_VSYNCSHIFT_B)
+
+#define _TRANSB_DATA_M1 0xe1030
+#define _TRANSB_DATA_N1 0xe1034
+#define _TRANSB_DATA_M2 0xe1038
+#define _TRANSB_DATA_N2 0xe103c
+#define _TRANSB_DP_LINK_M1 0xe1040
+#define _TRANSB_DP_LINK_N1 0xe1044
+#define _TRANSB_DP_LINK_M2 0xe1048
+#define _TRANSB_DP_LINK_N2 0xe104c
+
+#define TRANSDATA_M1(pipe) _PIPE(pipe, _TRANSA_DATA_M1, _TRANSB_DATA_M1)
+#define TRANSDATA_N1(pipe) _PIPE(pipe, _TRANSA_DATA_N1, _TRANSB_DATA_N1)
+#define TRANSDATA_M2(pipe) _PIPE(pipe, _TRANSA_DATA_M2, _TRANSB_DATA_M2)
+#define TRANSDATA_N2(pipe) _PIPE(pipe, _TRANSA_DATA_N2, _TRANSB_DATA_N2)
+#define TRANSDPLINK_M1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M1, _TRANSB_DP_LINK_M1)
+#define TRANSDPLINK_N1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N1, _TRANSB_DP_LINK_N1)
+#define TRANSDPLINK_M2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M2, _TRANSB_DP_LINK_M2)
+#define TRANSDPLINK_N2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N2, _TRANSB_DP_LINK_N2)
+
+#define _TRANSACONF 0xf0008
+#define _TRANSBCONF 0xf1008
+#define TRANSCONF(plane) _PIPE(plane, _TRANSACONF, _TRANSBCONF)
#define TRANS_DISABLE (0<<31)
#define TRANS_ENABLE (1<<31)
#define TRANS_STATE_MASK (1<<30)
@@ -2783,19 +3107,41 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define TRANS_FSYNC_DELAY_HB4 (3<<27)
#define TRANS_DP_AUDIO_ONLY (1<<26)
#define TRANS_DP_VIDEO_AUDIO (0<<26)
+#define TRANS_INTERLACE_MASK (7<<21)
#define TRANS_PROGRESSIVE (0<<21)
+#define TRANS_INTERLACED (3<<21)
+#define TRANS_LEGACY_INTERLACED_ILK (2<<21)
#define TRANS_8BPC (0<<5)
#define TRANS_10BPC (1<<5)
#define TRANS_6BPC (2<<5)
#define TRANS_12BPC (3<<5)
-#define FDI_RXA_CHICKEN 0xc200c
-#define FDI_RXB_CHICKEN 0xc2010
-#define FDI_RX_PHASE_SYNC_POINTER_ENABLE (1)
+#define _TRANSA_CHICKEN2 0xf0064
+#define _TRANSB_CHICKEN2 0xf1064
+#define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2)
+#define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31)
+
+#define SOUTH_CHICKEN1 0xc2000
+#define FDIA_PHASE_SYNC_SHIFT_OVR 19
+#define FDIA_PHASE_SYNC_SHIFT_EN 18
+#define FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2)))
+#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2)))
+#define SOUTH_CHICKEN2 0xc2004
+#define DPLS_EDP_PPS_FIX_DIS (1<<0)
+
+#define _FDI_RXA_CHICKEN 0xc200c
+#define _FDI_RXB_CHICKEN 0xc2010
+#define FDI_RX_PHASE_SYNC_POINTER_OVR (1<<1)
+#define FDI_RX_PHASE_SYNC_POINTER_EN (1<<0)
+#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
+
+#define SOUTH_DSPCLK_GATE_D 0xc2020
+#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
/* CPU: FDI_TX */
-#define FDI_TXA_CTL 0x60100
-#define FDI_TXB_CTL 0x61100
+#define _FDI_TXA_CTL 0x60100
+#define _FDI_TXB_CTL 0x61100
+#define FDI_TX_CTL(pipe) _PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL)
#define FDI_TX_DISABLE (0<<31)
#define FDI_TX_ENABLE (1<<31)
#define FDI_LINK_TRAIN_PATTERN_1 (0<<28)
@@ -2835,8 +3181,9 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define FDI_SCRAMBLING_DISABLE (1<<7)
/* FDI_RX, FDI_X is hard-wired to Transcoder_X */
-#define FDI_RXA_CTL 0xf000c
-#define FDI_RXB_CTL 0xf100c
+#define _FDI_RXA_CTL 0xf000c
+#define _FDI_RXB_CTL 0xf100c
+#define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
#define FDI_RX_ENABLE (1<<31)
#define FDI_RX_DISABLE (0<<31)
/* train, dp width same as FDI_TX */
@@ -2883,10 +3230,12 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define FDI_RX_CROSS_CLOCK_OVERFLOW (1<<1)
#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1<<0)
-#define FDI_RXA_IIR 0xf0014
-#define FDI_RXA_IMR 0xf0018
-#define FDI_RXB_IIR 0xf1014
-#define FDI_RXB_IMR 0xf1018
+#define _FDI_RXA_IIR 0xf0014
+#define _FDI_RXA_IMR 0xf0018
+#define _FDI_RXB_IIR 0xf1014
+#define _FDI_RXB_IMR 0xf1018
+#define FDI_RX_IIR(pipe) _PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR)
+#define FDI_RX_IMR(pipe) _PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR)
#define FDI_PLL_CTL_1 0xfe000
#define FDI_PLL_CTL_2 0xfe004
@@ -3072,8 +3421,11 @@ read64(struct inteldrm_softc *dev_priv, bus_size_t off)
#define IS_GEN4(dev_priv) (dev_priv->flags & CHIP_GEN4)
#define IS_GEN6(dev_priv) (dev_priv->flags & CHIP_GEN6)
-#define HAS_PCH_SPLIT(dev_priv) (IS_IRONLAKE(dev_priv) || \
- IS_GEN6(dev_priv))
+#define I915_HAS_FBC(dev) (IS_I965GM(dev) || IS_GM45(dev))
+
+#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
+
+#define INTEL_INFO(dev) (dev)
/*
* Interrupts that are always left unmasked.
diff --git a/sys/dev/pci/drm/i915_irq.c b/sys/dev/pci/drm/i915_irq.c
index 71e921fcfbb..a61eea60a9c 100644
--- a/sys/dev/pci/drm/i915_irq.c
+++ b/sys/dev/pci/drm/i915_irq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_irq.c,v 1.52 2011/09/14 10:26:16 oga Exp $ */
+/* $OpenBSD: i915_irq.c,v 1.53 2012/05/19 18:02:53 kettenis Exp $ */
/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
*/
/*
@@ -118,7 +118,7 @@ void
i915_enable_pipestat(struct inteldrm_softc *dev_priv, int pipe, u_int32_t mask)
{
if ((dev_priv->pipestat[pipe] & mask) != mask) {
- bus_size_t reg = pipe == 0 ? PIPEASTAT : PIPEBSTAT;
+ bus_size_t reg = pipe == 0 ? _PIPEASTAT : _PIPEBSTAT;
dev_priv->pipestat[pipe] |= mask;
/* Enable the interrupt, clear and pending status */
@@ -131,7 +131,7 @@ void
i915_disable_pipestat(struct inteldrm_softc *dev_priv, int pipe, u_int32_t mask)
{
if ((dev_priv->pipestat[pipe] & mask) != 0) {
- bus_size_t reg = pipe == 0 ? PIPEASTAT : PIPEBSTAT;
+ bus_size_t reg = pipe == 0 ? _PIPEASTAT : _PIPEBSTAT;
dev_priv->pipestat[pipe] &= ~mask;
I915_WRITE(reg, dev_priv->pipestat[pipe]);
@@ -139,6 +139,21 @@ i915_disable_pipestat(struct inteldrm_softc *dev_priv, int pipe, u_int32_t mask)
}
}
+/**
+ * inteldrm_pipe_enabled - check if a pipe is enabled
+ * @dev: DRM device
+ * @pipe: pipe to check
+ *
+ * Reading certain registers when the pipe is disabled can hang the chip.
+ * Use this routine to make sure the PLL is running and the pipe is active
+ * before reading such registers if unsure.
+ */
+int
+inteldrm_pipe_enabled(struct inteldrm_softc *dev_priv, int pipe)
+{
+ return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE;
+}
+
u_int32_t
i915_get_vblank_counter(struct drm_device *dev, int pipe)
{
@@ -146,20 +161,19 @@ i915_get_vblank_counter(struct drm_device *dev, int pipe)
bus_size_t high_frame, low_frame;
u_int32_t high1, high2, low;
- high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
- low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
-
if (inteldrm_pipe_enabled(dev_priv, pipe) == 0) {
DRM_DEBUG("trying to get vblank count for disabled pipe %d\n",
pipe);
return (0);
}
+ high_frame = PIPEFRAME(pipe);
+ low_frame = PIPEFRAMEPIXEL(pipe);
+
/* GM45 just had to be different... */
if (IS_GM45(dev_priv) || IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
IS_GEN6(dev_priv)) {
- return (I915_READ(pipe ? PIPEB_FRMCOUNT_GM45 :
- PIPEA_FRMCOUNT_GM45));
+ return (I915_READ(PIPE_FRMCOUNT_GM45(pipe)));
}
/*
@@ -256,8 +270,8 @@ i915_driver_irq_install(struct drm_device *dev)
if (HAS_PCH_SPLIT(dev_priv))
return (ironlake_irq_install(dev_priv));
- I915_WRITE(PIPEASTAT, 0);
- I915_WRITE(PIPEBSTAT, 0);
+ I915_WRITE(_PIPEASTAT, 0);
+ I915_WRITE(_PIPEBSTAT, 0);
I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0);
(void)I915_READ(IER);
@@ -278,9 +292,9 @@ i915_driver_irq_install(struct drm_device *dev)
* (say in the reset case where we want vblank interrupts etc to be
* switched back on if they were running
*/
- I915_WRITE(PIPEASTAT, (I915_READ(PIPEASTAT) & 0x8000ffff) |
+ I915_WRITE(_PIPEASTAT, (I915_READ(_PIPEASTAT) & 0x8000ffff) |
dev_priv->pipestat[0]);
- I915_WRITE(PIPEBSTAT, (I915_READ(PIPEBSTAT) & 0x8000ffff) |
+ I915_WRITE(_PIPEBSTAT, (I915_READ(_PIPEBSTAT) & 0x8000ffff) |
dev_priv->pipestat[1]);
/* Clear pending interrupt status */
I915_WRITE(IIR, I915_READ(IIR));
@@ -347,13 +361,13 @@ i915_driver_irq_uninstall(struct drm_device *dev)
I915_WRITE(GTIER, 0x0);
I915_WRITE(GTIIR, I915_READ(GTIIR));
} else {
- I915_WRITE(PIPEASTAT, 0);
- I915_WRITE(PIPEBSTAT, 0);
+ I915_WRITE(_PIPEASTAT, 0);
+ I915_WRITE(_PIPEBSTAT, 0);
I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0);
- I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
- I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
+ I915_WRITE(_PIPEASTAT, I915_READ(_PIPEASTAT) & 0x8000ffff);
+ I915_WRITE(_PIPEBSTAT, I915_READ(_PIPEBSTAT) & 0x8000ffff);
I915_WRITE(IIR, I915_READ(IIR));
}
}
diff --git a/sys/dev/pci/drm/i915_suspend.c b/sys/dev/pci/drm/i915_suspend.c
new file mode 100644
index 00000000000..7bd1257e94b
--- /dev/null
+++ b/sys/dev/pci/drm/i915_suspend.c
@@ -0,0 +1,927 @@
+/*
+ *
+ * Copyright 2008 (c) Intel Corporation
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+int i915_pipe_enabled(struct inteldrm_softc *, enum pipe);
+void i915_save_palette(struct inteldrm_softc *, enum pipe);
+void i915_restore_palette(struct inteldrm_softc *, enum pipe);
+u_int8_t i915_read_indexed(struct inteldrm_softc *, u_int16_t,
+ u_int16_t, u_int8_t);
+void i915_write_indexed(struct inteldrm_softc *, u_int16_t,
+ u_int16_t, u_int8_t, u_int8_t);
+void i915_write_ar(struct inteldrm_softc *, u_int16_t, u_int8_t,
+ u_int8_t, u_int16_t);
+u_int8_t i915_read_ar(struct inteldrm_softc *, u_int16_t,
+ u_int8_t, u_int16_t);
+void i915_save_vga(struct inteldrm_softc *);
+void i915_restore_vga(struct inteldrm_softc *);
+void i915_save_modeset_reg(struct inteldrm_softc *);
+void i915_restore_modeset_reg(struct inteldrm_softc *);
+
+int
+i915_pipe_enabled(struct inteldrm_softc *dev, enum pipe pipe)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ u32 dpll_reg;
+
+ /* On IVB, 3rd pipe shares PLL with another one */
+ if (pipe > 1)
+ return 0;
+
+ if (HAS_PCH_SPLIT(dev))
+ dpll_reg = PCH_DPLL(pipe);
+ else
+ dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B;
+
+ return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE);
+}
+
+void
+i915_save_palette(struct inteldrm_softc *dev, enum pipe pipe)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (HAS_PCH_SPLIT(dev))
+ reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for (i = 0; i < 256; i++)
+ array[i] = I915_READ(reg + (i << 2));
+}
+
+void
+i915_restore_palette(struct inteldrm_softc *dev, enum pipe pipe)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (HAS_PCH_SPLIT(dev))
+ reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for (i = 0; i < 256; i++)
+ I915_WRITE(reg + (i << 2), array[i]);
+}
+
+u_int8_t
+i915_read_indexed(struct inteldrm_softc *dev_priv, u_int16_t index_port,
+ u_int16_t data_port, u_int8_t reg)
+{
+ I915_WRITE8(index_port, reg);
+ return I915_READ8(data_port);
+}
+
+u_int8_t
+i915_read_ar(struct inteldrm_softc *dev_priv, u_int16_t st01,
+ u_int8_t reg, u_int16_t palette_enable)
+{
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ return I915_READ8(VGA_AR_DATA_READ);
+}
+
+void
+i915_write_ar(struct inteldrm_softc *dev_priv, u_int16_t st01, u_int8_t reg,
+ u_int8_t val, u_int16_t palette_enable)
+{
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
+}
+
+void
+i915_write_indexed(struct inteldrm_softc *dev_priv, u_int16_t index_port,
+ u_int16_t data_port, u_int8_t reg, u_int8_t val)
+{
+ I915_WRITE8(index_port, reg);
+ I915_WRITE8(data_port, val);
+}
+
+void
+i915_save_vga(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* VGA color palette registers */
+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
+
+ /* MSR bits */
+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* CRT controller regs */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
+ (~0x80));
+ for (i = 0; i <= 0x24; i++)
+ dev_priv->saveCR[i] =
+ i915_read_indexed(dev, cr_index, cr_data, i);
+ /* Make sure we don't turn off CR group 0 writes */
+ dev_priv->saveCR[0x11] &= ~0x80;
+
+ /* Attribute controller registers */
+ I915_READ8(st01);
+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
+ for (i = 0; i <= 0x14; i++)
+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
+ I915_READ8(st01);
+
+ /* Graphics controller registers */
+ for (i = 0; i < 9; i++)
+ dev_priv->saveGR[i] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
+
+ dev_priv->saveGR[0x10] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
+ dev_priv->saveGR[0x11] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
+ dev_priv->saveGR[0x18] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
+
+ /* Sequencer registers */
+ for (i = 0; i < 8; i++)
+ dev_priv->saveSR[i] =
+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
+}
+
+void
+i915_restore_vga(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* MSR bits */
+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* Sequencer registers, don't write SR07 */
+ for (i = 0; i < 7; i++)
+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
+ dev_priv->saveSR[i]);
+
+ /* CRT controller regs */
+ /* Enable CR group 0 writes */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
+ for (i = 0; i <= 0x24; i++)
+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
+
+ /* Graphics controller regs */
+ for (i = 0; i < 9; i++)
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
+ dev_priv->saveGR[i]);
+
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
+ dev_priv->saveGR[0x10]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
+ dev_priv->saveGR[0x11]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
+ dev_priv->saveGR[0x18]);
+
+ /* Attribute controller registers */
+ I915_READ8(st01); /* switch back to index mode */
+ for (i = 0; i <= 0x14; i++)
+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
+ I915_READ8(st01); /* switch back to index mode */
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
+ I915_READ8(st01);
+
+ /* VGA color palette registers */
+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
+}
+
+void
+i915_save_modeset_reg(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int i;
+
+ /* Cursor state */
+ dev_priv->saveCURACNTR = I915_READ(_CURACNTR);
+ dev_priv->saveCURAPOS = I915_READ(_CURAPOS);
+ dev_priv->saveCURABASE = I915_READ(_CURABASE);
+ dev_priv->saveCURBCNTR = I915_READ(_CURBCNTR);
+ dev_priv->saveCURBPOS = I915_READ(_CURBPOS);
+ dev_priv->saveCURBBASE = I915_READ(_CURBBASE);
+ if (IS_GEN2(dev))
+ dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
+ dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
+ }
+
+ /* Pipe & plane A info */
+ dev_priv->savePIPEACONF = I915_READ(_PIPEACONF);
+ dev_priv->savePIPEASRC = I915_READ(_PIPEASRC);
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->saveFPA0 = I915_READ(_PCH_FPA0);
+ dev_priv->saveFPA1 = I915_READ(_PCH_FPA1);
+ dev_priv->saveDPLL_A = I915_READ(_PCH_DPLL_A);
+ } else {
+ dev_priv->saveFPA0 = I915_READ(_FPA0);
+ dev_priv->saveFPA1 = I915_READ(_FPA1);
+ dev_priv->saveDPLL_A = I915_READ(_DPLL_A);
+ }
+ if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
+ dev_priv->saveDPLL_A_MD = I915_READ(_DPLL_A_MD);
+ dev_priv->saveHTOTAL_A = I915_READ(_HTOTAL_A);
+ dev_priv->saveHBLANK_A = I915_READ(_HBLANK_A);
+ dev_priv->saveHSYNC_A = I915_READ(_HSYNC_A);
+ dev_priv->saveVTOTAL_A = I915_READ(_VTOTAL_A);
+ dev_priv->saveVBLANK_A = I915_READ(_VBLANK_A);
+ dev_priv->saveVSYNC_A = I915_READ(_VSYNC_A);
+ if (!HAS_PCH_SPLIT(dev))
+ dev_priv->saveBCLRPAT_A = I915_READ(_BCLRPAT_A);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1);
+ dev_priv->savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1);
+ dev_priv->savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1);
+ dev_priv->savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1);
+
+ dev_priv->saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL);
+ dev_priv->saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL);
+
+ dev_priv->savePFA_CTL_1 = I915_READ(_PFA_CTL_1);
+ dev_priv->savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ);
+ dev_priv->savePFA_WIN_POS = I915_READ(_PFA_WIN_POS);
+
+ dev_priv->saveTRANSACONF = I915_READ(_TRANSACONF);
+ dev_priv->saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A);
+ dev_priv->saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A);
+ dev_priv->saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A);
+ dev_priv->saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A);
+ dev_priv->saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A);
+ dev_priv->saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A);
+ }
+
+ dev_priv->saveDSPACNTR = I915_READ(_DSPACNTR);
+ dev_priv->saveDSPASTRIDE = I915_READ(_DSPASTRIDE);
+ dev_priv->saveDSPASIZE = I915_READ(_DSPASIZE);
+ dev_priv->saveDSPAPOS = I915_READ(_DSPAPOS);
+ dev_priv->saveDSPAADDR = I915_READ(_DSPAADDR);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ dev_priv->saveDSPASURF = I915_READ(_DSPASURF);
+ dev_priv->saveDSPATILEOFF = I915_READ(_DSPATILEOFF);
+ }
+ i915_save_palette(dev, PIPE_A);
+ dev_priv->savePIPEASTAT = I915_READ(_PIPEASTAT);
+
+ /* Pipe & plane B info */
+ dev_priv->savePIPEBCONF = I915_READ(_PIPEBCONF);
+ dev_priv->savePIPEBSRC = I915_READ(_PIPEBSRC);
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->saveFPB0 = I915_READ(_PCH_FPB0);
+ dev_priv->saveFPB1 = I915_READ(_PCH_FPB1);
+ dev_priv->saveDPLL_B = I915_READ(_PCH_DPLL_B);
+ } else {
+ dev_priv->saveFPB0 = I915_READ(_FPB0);
+ dev_priv->saveFPB1 = I915_READ(_FPB1);
+ dev_priv->saveDPLL_B = I915_READ(_DPLL_B);
+ }
+ if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
+ dev_priv->saveDPLL_B_MD = I915_READ(_DPLL_B_MD);
+ dev_priv->saveHTOTAL_B = I915_READ(_HTOTAL_B);
+ dev_priv->saveHBLANK_B = I915_READ(_HBLANK_B);
+ dev_priv->saveHSYNC_B = I915_READ(_HSYNC_B);
+ dev_priv->saveVTOTAL_B = I915_READ(_VTOTAL_B);
+ dev_priv->saveVBLANK_B = I915_READ(_VBLANK_B);
+ dev_priv->saveVSYNC_B = I915_READ(_VSYNC_B);
+ if (!HAS_PCH_SPLIT(dev))
+ dev_priv->saveBCLRPAT_B = I915_READ(_BCLRPAT_B);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1);
+ dev_priv->savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1);
+ dev_priv->savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1);
+ dev_priv->savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1);
+
+ dev_priv->saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL);
+ dev_priv->saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL);
+
+ dev_priv->savePFB_CTL_1 = I915_READ(_PFB_CTL_1);
+ dev_priv->savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ);
+ dev_priv->savePFB_WIN_POS = I915_READ(_PFB_WIN_POS);
+
+ dev_priv->saveTRANSBCONF = I915_READ(_TRANSBCONF);
+ dev_priv->saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B);
+ dev_priv->saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B);
+ dev_priv->saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B);
+ dev_priv->saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B);
+ dev_priv->saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B);
+ dev_priv->saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B);
+ }
+
+ dev_priv->saveDSPBCNTR = I915_READ(_DSPBCNTR);
+ dev_priv->saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE);
+ dev_priv->saveDSPBSIZE = I915_READ(_DSPBSIZE);
+ dev_priv->saveDSPBPOS = I915_READ(_DSPBPOS);
+ dev_priv->saveDSPBADDR = I915_READ(_DSPBADDR);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ dev_priv->saveDSPBSURF = I915_READ(_DSPBSURF);
+ dev_priv->saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF);
+ }
+ i915_save_palette(dev, PIPE_B);
+ dev_priv->savePIPEBSTAT = I915_READ(_PIPEBSTAT);
+
+ /* Fences */
+ switch (INTEL_INFO(dev)->gen) {
+ case 7:
+ case 6:
+ for (i = 0; i < 16; i++)
+ dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
+ break;
+ case 5:
+ case 4:
+ for (i = 0; i < 16; i++)
+ dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
+ break;
+ case 3:
+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+ for (i = 0; i < 8; i++)
+ dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
+ case 2:
+ for (i = 0; i < 8; i++)
+ dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
+ break;
+ }
+
+ return;
+}
+
+void
+i915_restore_modeset_reg(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int dpll_a_reg, fpa0_reg, fpa1_reg;
+ int dpll_b_reg, fpb0_reg, fpb1_reg;
+ int i;
+
+ /* XXX until we have FDI link training */
+ if (IS_GEN6(dev_priv))
+ return;
+
+ /* Fences */
+ switch (INTEL_INFO(dev)->gen) {
+ case 7:
+ case 6:
+ for (i = 0; i < 16; i++)
+ I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
+ break;
+ case 5:
+ case 4:
+ for (i = 0; i < 16; i++)
+ I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
+ break;
+ case 3:
+ case 2:
+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+ for (i = 0; i < 8; i++)
+ I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
+ for (i = 0; i < 8; i++)
+ I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
+ break;
+ }
+
+
+ if (HAS_PCH_SPLIT(dev)) {
+ dpll_a_reg = _PCH_DPLL_A;
+ dpll_b_reg = _PCH_DPLL_B;
+ fpa0_reg = _PCH_FPA0;
+ fpb0_reg = _PCH_FPB0;
+ fpa1_reg = _PCH_FPA1;
+ fpb1_reg = _PCH_FPB1;
+ } else {
+ dpll_a_reg = _DPLL_A;
+ dpll_b_reg = _DPLL_B;
+ fpa0_reg = _FPA0;
+ fpb0_reg = _FPB0;
+ fpa1_reg = _FPA1;
+ fpb1_reg = _FPB1;
+ }
+
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
+ I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
+ }
+
+ /* Pipe & plane A info */
+ /* Prime the clock */
+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
+ I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A &
+ ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_a_reg);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(fpa0_reg, dev_priv->saveFPA0);
+ I915_WRITE(fpa1_reg, dev_priv->saveFPA1);
+ /* Actually enable it */
+ I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
+ POSTING_READ(dpll_a_reg);
+ DRM_UDELAY(150);
+ if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(_DPLL_A_MD, dev_priv->saveDPLL_A_MD);
+ POSTING_READ(_DPLL_A_MD);
+ }
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(_HTOTAL_A, dev_priv->saveHTOTAL_A);
+ I915_WRITE(_HBLANK_A, dev_priv->saveHBLANK_A);
+ I915_WRITE(_HSYNC_A, dev_priv->saveHSYNC_A);
+ I915_WRITE(_VTOTAL_A, dev_priv->saveVTOTAL_A);
+ I915_WRITE(_VBLANK_A, dev_priv->saveVBLANK_A);
+ I915_WRITE(_VSYNC_A, dev_priv->saveVSYNC_A);
+ if (!HAS_PCH_SPLIT(dev))
+ I915_WRITE(_BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(_PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
+ I915_WRITE(_PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
+ I915_WRITE(_PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
+ I915_WRITE(_PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
+
+ I915_WRITE(_FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
+ I915_WRITE(_FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
+
+ I915_WRITE(_PFA_CTL_1, dev_priv->savePFA_CTL_1);
+ I915_WRITE(_PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
+ I915_WRITE(_PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
+
+ I915_WRITE(_TRANSACONF, dev_priv->saveTRANSACONF);
+ I915_WRITE(_TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
+ I915_WRITE(_TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
+ I915_WRITE(_TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
+ I915_WRITE(_TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A);
+ I915_WRITE(_TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A);
+ I915_WRITE(_TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A);
+ }
+
+ /* Restore plane info */
+ I915_WRITE(_DSPASIZE, dev_priv->saveDSPASIZE);
+ I915_WRITE(_DSPAPOS, dev_priv->saveDSPAPOS);
+ I915_WRITE(_PIPEASRC, dev_priv->savePIPEASRC);
+ I915_WRITE(_DSPAADDR, dev_priv->saveDSPAADDR);
+ I915_WRITE(_DSPASTRIDE, dev_priv->saveDSPASTRIDE);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ I915_WRITE(_DSPASURF, dev_priv->saveDSPASURF);
+ I915_WRITE(_DSPATILEOFF, dev_priv->saveDSPATILEOFF);
+ }
+
+ I915_WRITE(_PIPEACONF, dev_priv->savePIPEACONF);
+
+ i915_restore_palette(dev, PIPE_A);
+ /* Enable the plane */
+ I915_WRITE(_DSPACNTR, dev_priv->saveDSPACNTR);
+ I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR));
+
+ /* Pipe & plane B info */
+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
+ I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B &
+ ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_b_reg);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(fpb0_reg, dev_priv->saveFPB0);
+ I915_WRITE(fpb1_reg, dev_priv->saveFPB1);
+ /* Actually enable it */
+ I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
+ POSTING_READ(dpll_b_reg);
+ DRM_UDELAY(150);
+ if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(_DPLL_B_MD, dev_priv->saveDPLL_B_MD);
+ POSTING_READ(_DPLL_B_MD);
+ }
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(_HTOTAL_B, dev_priv->saveHTOTAL_B);
+ I915_WRITE(_HBLANK_B, dev_priv->saveHBLANK_B);
+ I915_WRITE(_HSYNC_B, dev_priv->saveHSYNC_B);
+ I915_WRITE(_VTOTAL_B, dev_priv->saveVTOTAL_B);
+ I915_WRITE(_VBLANK_B, dev_priv->saveVBLANK_B);
+ I915_WRITE(_VSYNC_B, dev_priv->saveVSYNC_B);
+ if (!HAS_PCH_SPLIT(dev))
+ I915_WRITE(_BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(_PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
+ I915_WRITE(_PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
+ I915_WRITE(_PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
+ I915_WRITE(_PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
+
+ I915_WRITE(_FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
+ I915_WRITE(_FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
+
+ I915_WRITE(_PFB_CTL_1, dev_priv->savePFB_CTL_1);
+ I915_WRITE(_PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
+ I915_WRITE(_PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
+
+ I915_WRITE(_TRANSBCONF, dev_priv->saveTRANSBCONF);
+ I915_WRITE(_TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
+ I915_WRITE(_TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
+ I915_WRITE(_TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
+ I915_WRITE(_TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B);
+ I915_WRITE(_TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B);
+ I915_WRITE(_TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B);
+ }
+
+ /* Restore plane info */
+ I915_WRITE(_DSPBSIZE, dev_priv->saveDSPBSIZE);
+ I915_WRITE(_DSPBPOS, dev_priv->saveDSPBPOS);
+ I915_WRITE(_PIPEBSRC, dev_priv->savePIPEBSRC);
+ I915_WRITE(_DSPBADDR, dev_priv->saveDSPBADDR);
+ I915_WRITE(_DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
+ if (INTEL_INFO(dev)->gen >= 4) {
+ I915_WRITE(_DSPBSURF, dev_priv->saveDSPBSURF);
+ I915_WRITE(_DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
+ }
+
+ I915_WRITE(_PIPEBCONF, dev_priv->savePIPEBCONF);
+
+ i915_restore_palette(dev, PIPE_B);
+ /* Enable the plane */
+ I915_WRITE(_DSPBCNTR, dev_priv->saveDSPBCNTR);
+ I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR));
+
+ /* Cursor state */
+ I915_WRITE(_CURAPOS, dev_priv->saveCURAPOS);
+ I915_WRITE(_CURACNTR, dev_priv->saveCURACNTR);
+ I915_WRITE(_CURABASE, dev_priv->saveCURABASE);
+ I915_WRITE(_CURBPOS, dev_priv->saveCURBPOS);
+ I915_WRITE(_CURBCNTR, dev_priv->saveCURBCNTR);
+ I915_WRITE(_CURBBASE, dev_priv->saveCURBBASE);
+ if (IS_GEN2(dev))
+ I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
+ return;
+}
+
+void
+i915_save_display(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+
+ /* Display arbitration control */
+ dev_priv->saveDSPARB = I915_READ(DSPARB);
+
+ /* This is only meaningful in non-KMS mode */
+ /* Don't save them in KMS mode */
+ i915_save_modeset_reg(dev);
+
+ /* CRT state */
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->saveADPA = I915_READ(PCH_ADPA);
+ } else {
+ dev_priv->saveADPA = I915_READ(ADPA);
+ }
+
+ /* LVDS state */
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
+ dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
+ dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
+ dev_priv->saveLVDS = I915_READ(PCH_LVDS);
+ } else {
+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+ dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
+ if (INTEL_INFO(dev)->gen >= 4)
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ dev_priv->saveLVDS = I915_READ(LVDS);
+ }
+
+ if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
+ } else {
+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
+ }
+
+ /* FIXME: save TV & SDVO state */
+
+ /* Only save FBC state on the platform that supports FBC */
+ if (I915_HAS_FBC(dev)) {
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
+ } else if (IS_GM45(dev)) {
+ dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
+ } else {
+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+ }
+ }
+
+ /* VGA state */
+ dev_priv->saveVGA0 = I915_READ(VGA0);
+ dev_priv->saveVGA1 = I915_READ(VGA1);
+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
+ if (HAS_PCH_SPLIT(dev))
+ dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
+ else
+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+
+ i915_save_vga(dev);
+}
+
+void
+i915_restore_display(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+
+ /* Display arbitration */
+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
+
+ /* This is only meaningful in non-KMS mode */
+ /* Don't restore them in KMS mode */
+ i915_restore_modeset_reg(dev);
+
+ /* CRT state */
+ if (HAS_PCH_SPLIT(dev))
+ I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
+ else
+ I915_WRITE(ADPA, dev_priv->saveADPA);
+
+ /* LVDS state */
+ if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
+ } else if (IS_MOBILE(dev) && !IS_I830(dev))
+ I915_WRITE(LVDS, dev_priv->saveLVDS);
+
+ if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
+
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
+ I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
+ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2);
+ I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL);
+ I915_WRITE(RSTDBYCTL,
+ dev_priv->saveMCHBAR_RENDER_STANDBY);
+ } else {
+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL);
+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+ }
+ /* FIXME: restore TV & SDVO state */
+
+ /* only restore FBC info on the platform that supports FBC*/
+ if (I915_HAS_FBC(dev)) {
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
+ } else if (IS_GM45(dev)) {
+ I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
+ } else {
+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+ }
+ }
+ /* VGA state */
+ if (HAS_PCH_SPLIT(dev))
+ I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
+ else
+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+
+ I915_WRITE(VGA0, dev_priv->saveVGA0);
+ I915_WRITE(VGA1, dev_priv->saveVGA1);
+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
+ POSTING_READ(VGA_PD);
+ DRM_UDELAY(150);
+
+ i915_restore_vga(dev);
+}
+
+int
+i915_save_state(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int i;
+
+ dev_priv->saveLBB = pci_conf_read(dev_priv->pc, dev_priv->tag, LBB);
+
+ /* Hardware status page */
+ dev_priv->saveHWS = I915_READ(HWS_PGA);
+
+ i915_save_display(dev);
+
+ /* Interrupt state */
+ if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->saveDEIER = I915_READ(DEIER);
+ dev_priv->saveDEIMR = I915_READ(DEIMR);
+ dev_priv->saveGTIER = I915_READ(GTIER);
+ dev_priv->saveGTIMR = I915_READ(GTIMR);
+ dev_priv->saveFDI_RXA_IMR = I915_READ(_FDI_RXA_IMR);
+ dev_priv->saveFDI_RXB_IMR = I915_READ(_FDI_RXB_IMR);
+ dev_priv->saveMCHBAR_RENDER_STANDBY =
+ I915_READ(RSTDBYCTL);
+ dev_priv->savePCH_PORT_HOTPLUG = I915_READ(PCH_PORT_HOTPLUG);
+ } else {
+ dev_priv->saveIER = I915_READ(IER);
+ dev_priv->saveIMR = I915_READ(IMR);
+ }
+
+ /* XXX gen6_disable_rps(dev) */
+
+ /* Clock gating state */
+ if (HAS_PCH_SPLIT(dev_priv)) {
+ dev_priv->saveDSPCLK_GATE_D = I915_READ(PCH_DSPCLK_GATE_D);
+ dev_priv->saveDSPCLK_GATE = I915_READ(ILK_DSPCLK_GATE);
+ } else if (IS_G4X(dev_priv)) {
+ dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
+ dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
+ dev_priv->saveRAMCLK_GATE_D = I915_READ(RAMCLK_GATE_D);
+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
+ } else if (IS_I965GM(dev_priv)) {
+ dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
+ dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
+ dev_priv->saveRAMCLK_GATE_D = I915_READ(RAMCLK_GATE_D);
+ dev_priv->saveDEUC = I915_READ16(DEUC);
+ } else if (IS_I965G(dev_priv)) {
+ dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
+ dev_priv->saveRENCLK_GATE_D2 = I915_READ(RENCLK_GATE_D2);
+ } else if (IS_I9XX(dev_priv)) {
+ dev_priv->saveD_STATE = I915_READ(D_STATE);
+ } else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) {
+ dev_priv->saveRENCLK_GATE_D1 = I915_READ(RENCLK_GATE_D1);
+ } else if (IS_I830(dev_priv)) {
+ 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(SWF00 + (i << 2));
+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
+ }
+ for (i = 0; i < 3; i++)
+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
+
+ return 0;
+}
+
+int
+i915_restore_state(struct inteldrm_softc *dev)
+{
+ struct inteldrm_softc *dev_priv = dev;
+ int i;
+
+ pci_conf_write(dev_priv->pc, dev_priv->tag, LBB, dev_priv->saveLBB);
+
+ /* Hardware status page */
+ I915_WRITE(HWS_PGA, dev_priv->saveHWS);
+
+ i915_restore_display(dev);
+
+ /* Interrupt state */
+ if (HAS_PCH_SPLIT(dev)) {
+ I915_WRITE(DEIER, dev_priv->saveDEIER);
+ I915_WRITE(DEIMR, dev_priv->saveDEIMR);
+ I915_WRITE(GTIER, dev_priv->saveGTIER);
+ I915_WRITE(GTIMR, dev_priv->saveGTIMR);
+ I915_WRITE(_FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR);
+ I915_WRITE(_FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR);
+ I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->savePCH_PORT_HOTPLUG);
+ } else {
+ I915_WRITE (IER, dev_priv->saveIER);
+ I915_WRITE (IMR, dev_priv->saveIMR);
+ }
+
+ /* Clock gating state */
+ if (HAS_PCH_SPLIT(dev_priv)) {
+ I915_WRITE(PCH_DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+ I915_WRITE(ILK_DSPCLK_GATE, dev_priv->saveDSPCLK_GATE);
+ } if (IS_G4X(dev_priv)) {
+ I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
+ I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
+ I915_WRITE(RAMCLK_GATE_D, dev_priv->saveRAMCLK_GATE_D);
+ I915_WRITE(DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+ } else if (IS_I965GM(dev_priv)) {
+ I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
+ I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
+ I915_WRITE(DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
+ I915_WRITE(RAMCLK_GATE_D, dev_priv->saveRAMCLK_GATE_D);
+ I915_WRITE16(DEUC, dev_priv->saveDEUC);
+ } else if (IS_I965G(dev_priv)) {
+ I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
+ I915_WRITE(RENCLK_GATE_D2, dev_priv->saveRENCLK_GATE_D2);
+ } else if (IS_I9XX(dev_priv)) {
+ I915_WRITE(D_STATE, dev_priv->saveD_STATE);
+ } else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) {
+ I915_WRITE(RENCLK_GATE_D1, dev_priv->saveRENCLK_GATE_D1);
+ } else if (IS_I830(dev_priv)) {
+ 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(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]);
+ }
+ for (i = 0; i < 3; i++)
+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+
+ return 0;
+}