diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-05-19 18:02:54 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-05-19 18:02:54 +0000 |
commit | b56c6bcb0aa01b1c0e3fbc554c6bc99c9149a5df (patch) | |
tree | e5a53ec64d9de572aed393760c8a2a6186397221 | |
parent | 055e2beb42f9e960d08a4ce26cb5eedd5d78b252 (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.drm | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 903 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.h | 690 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_irq.c | 46 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_suspend.c | 927 |
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; +} |