diff options
| -rw-r--r-- | bsd-core/i915/Makefile | 2 | ||||
| -rw-r--r-- | bsd-core/i915_drv.c | 32 | ||||
| l--------- | bsd-core/i915_suspend.c | 1 | ||||
| -rw-r--r-- | linux-core/Makefile.kernel | 2 | ||||
| -rw-r--r-- | linux-core/i915_drv.c | 460 | ||||
| l--------- | linux-core/i915_suspend.c | 1 | ||||
| -rw-r--r-- | shared-core/i915_dma.c | 2 | ||||
| -rw-r--r-- | shared-core/i915_drv.h | 11 | ||||
| -rw-r--r-- | shared-core/i915_suspend.c | 525 | 
9 files changed, 574 insertions, 462 deletions
diff --git a/bsd-core/i915/Makefile b/bsd-core/i915/Makefile index 6fd7d728..f88155a5 100644 --- a/bsd-core/i915/Makefile +++ b/bsd-core/i915/Makefile @@ -3,7 +3,7 @@  .PATH:	${.CURDIR}/..  KMOD	= i915  NO_MAN	= YES -SRCS    = i915_dma.c i915_drv.c i915_irq.c i915_mem.c +SRCS    = i915_dma.c i915_drv.c i915_irq.c i915_mem.c i915_suspend.c  SRCS   += device_if.h bus_if.h pci_if.h opt_drm.h  CFLAGS += ${DEBUG_FLAGS} -I. -I.. diff --git a/bsd-core/i915_drv.c b/bsd-core/i915_drv.c index e6769d17..c19ef5db 100644 --- a/bsd-core/i915_drv.c +++ b/bsd-core/i915_drv.c @@ -40,10 +40,38 @@ static drm_pci_id_list_t i915_pciidlist[] = {  	i915_PCI_IDS  }; +static int i915_suspend(device_t nbdev) +{ +	struct drm_device *dev = device_get_softc(nbdev); +	struct drm_i915_private *dev_priv = dev->dev_private; + +	if (!dev || !dev_priv) { +		DRM_ERROR("dev: 0x%lx, dev_priv: 0x%lx\n", +			(unsigned long) dev, (unsigned long) dev_priv); +		DRM_ERROR("DRM not initialized, aborting suspend.\n"); +		return -ENODEV; +	} + +	i915_save_state(dev); + +	return (bus_generic_suspend(nbdev)); +} + +static int i915_resume(device_t nbdev) +{ +	struct drm_device *dev = device_get_softc(nbdev); + +	i915_restore_state(dev); + +	return (bus_generic_resume(nbdev)); +} +  static void i915_configure(struct drm_device *dev)  { -	dev->driver.buf_priv_size	= 1;	/* No dev_priv */ +	dev->driver.buf_priv_size	= sizeof(drm_i915_private_t);  	dev->driver.load		= i915_driver_load; +	dev->driver.unload		= i915_driver_unload; +	dev->driver.firstopen		= i915_driver_firstopen;  	dev->driver.preclose		= i915_driver_preclose;  	dev->driver.lastclose		= i915_driver_lastclose;  	dev->driver.device_is_agp	= i915_driver_device_is_agp; @@ -94,6 +122,8 @@ static device_method_t i915_methods[] = {  	/* Device interface */  	DEVMETHOD(device_probe,		i915_probe),  	DEVMETHOD(device_attach,	i915_attach), +	DEVMETHOD(device_suspend,	i915_suspend), +	DEVMETHOD(device_resume,	i915_resume),  	DEVMETHOD(device_detach,	drm_detach),  	{ 0, 0 } diff --git a/bsd-core/i915_suspend.c b/bsd-core/i915_suspend.c new file mode 120000 index 00000000..b55754c5 --- /dev/null +++ b/bsd-core/i915_suspend.c @@ -0,0 +1 @@ +../shared-core/i915_suspend.c
\ No newline at end of file diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 7a477a10..b9f078dd 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -20,7 +20,7 @@ r128-objs   := r128_drv.o r128_cce.o r128_state.o r128_irq.o  mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o  i810-objs   := i810_drv.o i810_dma.o  i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \ -		i915_buffer.o i915_compat.o i915_execbuf.o +		i915_buffer.o i915_compat.o i915_execbuf.o i915_suspend.o  nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \  		nouveau_object.o nouveau_irq.o nouveau_notifier.o nouveau_swmthd.o \  		nouveau_sgdma.o nouveau_dma.o nouveau_bo.o nouveau_fence.o \ diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 91c2da23..c5f806b1 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -63,211 +63,9 @@ static struct drm_bo_driver i915_bo_driver = {  };  #endif -enum pipe { -    PIPE_A = 0, -    PIPE_B, -}; - -static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; - -	if (pipe == PIPE_A) -		return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); -	else -		return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); -} - -static void i915_save_palette(struct drm_device *dev, enum pipe pipe) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; -	unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); -	u32 *array; -	int i; - -	if (!i915_pipe_enabled(dev, pipe)) -		return; - -	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)); -} - -static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; -	unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); -	u32 *array; -	int i; - -	if (!i915_pipe_enabled(dev, pipe)) -		return; - -	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]); -} - -static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) -{ -	outb(reg, index_port); -	return inb(data_port); -} - -static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) -{ -	inb(st01); -	outb(palette_enable | reg, VGA_AR_INDEX); -	return inb(VGA_AR_DATA_READ); -} - -static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) -{ -	inb(st01); -	outb(palette_enable | reg, VGA_AR_INDEX); -	outb(val, VGA_AR_DATA_WRITE); -} - -static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) -{ -	outb(reg, index_port); -	outb(val, data_port); -} - -static void i915_save_vga(struct drm_device *dev) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; -	int i; -	u16 cr_index, cr_data, st01; - -	/* VGA color palette registers */ -	dev_priv->saveDACMASK = inb(VGA_DACMASK); -	/* DACCRX automatically increments during read */ -	outb(0, VGA_DACRX); -	/* Read 3 bytes of color data from each index */ -	for (i = 0; i < 256 * 3; i++) -		dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); - -	/* MSR bits */ -	dev_priv->saveMSR = inb(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(cr_index, cr_data, 0x11, -			   i915_read_indexed(cr_index, cr_data, 0x11) & -			   (~0x80)); -	for (i = 0; i <= 0x24; i++) -		dev_priv->saveCR[i] = -			i915_read_indexed(cr_index, cr_data, i); -	/* Make sure we don't turn off CR group 0 writes */ -	dev_priv->saveCR[0x11] &= ~0x80; - -	/* Attribute controller registers */ -	inb(st01); -	dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); -	for (i = 0; i <= 0x14; i++) -		dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); -	inb(st01); -	outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); -	inb(st01); - -	/* Graphics controller registers */ -	for (i = 0; i < 9; i++) -		dev_priv->saveGR[i] = -			i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); - -	dev_priv->saveGR[0x10] = -		i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); -	dev_priv->saveGR[0x11] = -		i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); -	dev_priv->saveGR[0x18] = -		i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); - -	/* Sequencer registers */ -	for (i = 0; i < 8; i++) -		dev_priv->saveSR[i] = -			i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); -} - -static void i915_restore_vga(struct drm_device *dev) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; -	int i; -	u16 cr_index, cr_data, st01; - -	/* MSR bits */ -	outb(dev_priv->saveMSR, VGA_MSR_WRITE); -	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(VGA_SR_INDEX, VGA_SR_DATA, i, -				   dev_priv->saveSR[i]); - -	/* CRT controller regs */ -	/* Enable CR group 0 writes */ -	i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); -	for (i = 0; i <= 0x24; i++) -		i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); - -	/* Graphics controller regs */ -	for (i = 0; i < 9; i++) -		i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, -				   dev_priv->saveGR[i]); - -	i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, -			   dev_priv->saveGR[0x10]); -	i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, -			   dev_priv->saveGR[0x11]); -	i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, -			   dev_priv->saveGR[0x18]); - -	/* Attribute controller registers */ -	inb(st01); /* switch back to index mode */ -	for (i = 0; i <= 0x14; i++) -		i915_write_ar(st01, i, dev_priv->saveAR[i], 0); -	inb(st01); /* switch back to index mode */ -	outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); -	inb(st01); - -	/* VGA color palette registers */ -	outb(dev_priv->saveDACMASK, VGA_DACMASK); -	/* DACCRX automatically increments during read */ -	outb(0, VGA_DACWX); -	/* Read 3 bytes of color data from each index */ -	for (i = 0; i < 256 * 3; i++) -		outb(dev_priv->saveDACDATA[i], VGA_DACDATA); - -} -  static int i915_suspend(struct drm_device *dev, pm_message_t state)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	int i;  	if (!dev || !dev_priv) {  		printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); @@ -279,122 +77,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)  		return 0;  	pci_save_state(dev->pdev); -	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); - -	/* Display arbitration control */ -	dev_priv->saveDSPARB = I915_READ(DSPARB); - -	/* Pipe & plane A info */ -	dev_priv->savePIPEACONF = I915_READ(PIPEACONF); -	dev_priv->savePIPEASRC = I915_READ(PIPEASRC); -	dev_priv->saveFPA0 = I915_READ(FPA0); -	dev_priv->saveFPA1 = I915_READ(FPA1); -	dev_priv->saveDPLL_A = I915_READ(DPLL_A); -	if (IS_I965G(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); -	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->saveDSPABASE = I915_READ(DSPABASE); -	if (IS_I965G(dev)) { -		dev_priv->saveDSPASURF = I915_READ(DSPASURF); -		dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); -	} -	i915_save_palette(dev, PIPE_A); -	dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); - -	/* Pipe & plane B info */ -	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); -	dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); -	dev_priv->saveFPB0 = I915_READ(FPB0); -	dev_priv->saveFPB1 = I915_READ(FPB1); -	dev_priv->saveDPLL_B = I915_READ(DPLL_B); -	if (IS_I965G(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); -	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->saveDSPBBASE = I915_READ(DSPBBASE); -	if (IS_I965GM(dev) || IS_IGD_GM(dev)) { -		dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); -		dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); -	} -	i915_save_palette(dev, PIPE_B); -	dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); -	/* CRT state */ -	dev_priv->saveADPA = I915_READ(ADPA); - -	/* LVDS state */ -	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); -	if (IS_I965G(dev)) -		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)) -		dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); -	dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); -	dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); -	dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); - -	/* FIXME: save TV & SDVO state */ - -	/* FBC state */ -	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); - -	/* Interrupt state */ -	dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); -	dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); -	dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); - -	/* VGA state */ -	dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); -	dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); -	dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); -	dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); - -	/* Clock gating state */ -	dev_priv->saveD_STATE = I915_READ(D_STATE); -	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); - -	/* Cache mode state */ -	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); - -	/* Memory Arbitration state */ -	dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); - -	/* Scratch space */ -	for (i = 0; i < 16; i++) { -		dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); -		dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); -	} -	for (i = 0; i < 3; i++) -		dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); - -	i915_save_vga(dev); +	i915_save_state(dev);  	if (state.event == PM_EVENT_SUSPEND) {  		/* Shut down the device */ @@ -408,153 +92,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)  static int i915_resume(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	int i;  	pci_set_power_state(dev->pdev, PCI_D0);  	pci_restore_state(dev->pdev);  	if (pci_enable_device(dev->pdev))  		return -1; -	pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); - -	I915_WRITE(DSPARB, dev_priv->saveDSPARB); - -	/* 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); -		udelay(150); -	} -	I915_WRITE(FPA0, dev_priv->saveFPA0); -	I915_WRITE(FPA1, dev_priv->saveFPA1); -	/* Actually enable it */ -	I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); -	udelay(150); -	if (IS_I965G(dev)) -		I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); -	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); -	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(DSPABASE, dev_priv->saveDSPABASE); -	I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); -	if (IS_I965G(dev)) { -		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(DSPABASE, I915_READ(DSPABASE)); - -	/* Pipe & plane B info */ -	if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { -		I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & -			   ~DPLL_VCO_ENABLE); -		udelay(150); -	} -	I915_WRITE(FPB0, dev_priv->saveFPB0); -	I915_WRITE(FPB1, dev_priv->saveFPB1); -	/* Actually enable it */ -	I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); -	udelay(150); -	if (IS_I965G(dev)) -		I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); -	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); -	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(DSPBBASE, dev_priv->saveDSPBBASE); -	I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); -	if (IS_I965G(dev)) { -		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(DSPBBASE, I915_READ(DSPBBASE)); - -	/* CRT state */ -	I915_WRITE(ADPA, dev_priv->saveADPA); - -	/* LVDS state */ -	if (IS_I965G(dev)) -		I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); -	if (IS_MOBILE(dev) && !IS_I830(dev)) -		I915_WRITE(LVDS, dev_priv->saveLVDS); -	if (!IS_I830(dev) && !IS_845G(dev)) -		I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); - -	I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); -	I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); -	I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); -	I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); -	I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); -	I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - -	/* FIXME: restore TV & SDVO state */ - -	/* FBC info */ -	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 */ -	I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); -	I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); -	I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); -	I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); -	udelay(150); - -	/* Clock gating state */ -	I915_WRITE (D_STATE, dev_priv->saveD_STATE); -	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); - -	/* Cache mode state */ -	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); - -	/* Memory arbitration state */ -	I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); - -	for (i = 0; i < 16; i++) { -		I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); -		I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); -	} -	for (i = 0; i < 3; i++) -		I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); - -	i915_restore_vga(dev); +	i915_restore_state(dev);  	return 0;  } diff --git a/linux-core/i915_suspend.c b/linux-core/i915_suspend.c new file mode 120000 index 00000000..b55754c5 --- /dev/null +++ b/linux-core/i915_suspend.c @@ -0,0 +1 @@ +../shared-core/i915_suspend.c
\ No newline at end of file diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 60b405d4..3f4fd1b2 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1008,7 +1008,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,  int i915_driver_load(struct drm_device *dev, unsigned long flags)  { -	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv;  	unsigned long base, size;  	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 6421f689..427c49fe 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -307,6 +307,11 @@ extern void i915_mem_takedown(struct mem_block **heap);  extern void i915_mem_release(struct drm_device * dev,  			     struct drm_file *file_priv,  			     struct mem_block *heap); + +/* i915_suspend.c */ +extern int i915_save_state(struct drm_device *dev); +extern int i915_restore_state(struct drm_device *dev); +  #ifdef I915_HAVE_FENCE  /* i915_fence.c */  extern void i915_fence_handler(struct drm_device *dev); @@ -343,6 +348,12 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev);  #define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, (reg), (val))  #define I915_READ16(reg)	DRM_READ16(dev_priv->mmio_map, (reg))  #define I915_WRITE16(reg,val)	DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) +#define I915_READ8(reg)		DRM_READ8(dev_priv->mmio_map, (reg)) +#define I915_WRITE8(reg,val)	DRM_WRITE8(dev_priv->mmio_map, (reg), (val)) + +#if defined(__FreeBSD__) +typedef boolean_t bool; +#endif  #define I915_VERBOSE 0 diff --git a/shared-core/i915_suspend.c b/shared-core/i915_suspend.c new file mode 100644 index 00000000..27c82b48 --- /dev/null +++ b/shared-core/i915_suspend.c @@ -0,0 +1,525 @@ +/* i915_suspend.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- + */ +/* + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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" + +enum pipe { +    PIPE_A = 0, +    PIPE_B, +}; + +static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	if (pipe == PIPE_A) +		return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); +	else +		return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); +} + +static void i915_save_palette(struct drm_device *dev, enum pipe pipe) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); +	u32 *array; +	int i; + +	if (!i915_pipe_enabled(dev, pipe)) +		return; + +	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)); +} + +static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); +	u32 *array; +	int i; + +	if (!i915_pipe_enabled(dev, pipe)) +		return; + +	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]); +} + +static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	I915_WRITE8(index_port, reg); +	return I915_READ8(data_port); +} + +static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	I915_READ8(st01); +	I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); +	return I915_READ8(VGA_AR_DATA_READ); +} + +static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	I915_READ8(st01); +	I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); +	I915_WRITE8(VGA_AR_DATA_WRITE, val); +} + +static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	I915_WRITE8(index_port, reg); +	I915_WRITE8(data_port, val); +} + +static void i915_save_vga(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	int i; +	u16 cr_index, cr_data, st01; + +	/* VGA color palette registers */ +	dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); +	/* DACCRX automatically increments during read */ +	I915_WRITE8(VGA_DACRX, 0); +	/* Read 3 bytes of color data from each index */ +	for (i = 0; i < 256 * 3; i++) +		dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); + +	/* 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); +} + +static void i915_restore_vga(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	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); +	/* DACCRX automatically increments during read */ +	I915_WRITE8(VGA_DACWX, 0); +	/* Read 3 bytes of color data from each index */ +	for (i = 0; i < 256 * 3; i++) +		I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); + +} + +int i915_save_state(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	int i; + +#if defined(__FreeBSD__) +	dev_priv->saveLBB = (u8) pci_read_config(dev->device, LBB, 1); +#else +	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); +#endif + +	/* Display arbitration control */ +	dev_priv->saveDSPARB = I915_READ(DSPARB); + +	/* Pipe & plane A info */ +	dev_priv->savePIPEACONF = I915_READ(PIPEACONF); +	dev_priv->savePIPEASRC = I915_READ(PIPEASRC); +	dev_priv->saveFPA0 = I915_READ(FPA0); +	dev_priv->saveFPA1 = I915_READ(FPA1); +	dev_priv->saveDPLL_A = I915_READ(DPLL_A); +	if (IS_I965G(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); +	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->saveDSPABASE = I915_READ(DSPABASE); +	if (IS_I965G(dev)) { +		dev_priv->saveDSPASURF = I915_READ(DSPASURF); +		dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); +	} +	i915_save_palette(dev, PIPE_A); +	dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT); + +	/* Pipe & plane B info */ +	dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); +	dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); +	dev_priv->saveFPB0 = I915_READ(FPB0); +	dev_priv->saveFPB1 = I915_READ(FPB1); +	dev_priv->saveDPLL_B = I915_READ(DPLL_B); +	if (IS_I965G(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); +	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->saveDSPBBASE = I915_READ(DSPBBASE); +	if (IS_I965GM(dev) || IS_IGD_GM(dev)) { +		dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); +		dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); +	} +	i915_save_palette(dev, PIPE_B); +	dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT); + +	/* CRT state */ +	dev_priv->saveADPA = I915_READ(ADPA); + +	/* LVDS state */ +	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); +	if (IS_I965G(dev)) +		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)) +		dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); +	dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON); +	dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF); +	dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); + +	/* FIXME: save TV & SDVO state */ + +	/* FBC state */ +	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); + +	/* Interrupt state */ +	dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R); +	dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R); +	dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R); + +	/* VGA state */ +	dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0); +	dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1); +	dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV); +	dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + +	/* Clock gating state */ +	dev_priv->saveD_STATE = I915_READ(D_STATE); +	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); + +	/* Cache mode state */ +	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); + +	/* Memory Arbitration state */ +	dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); + +	/* Scratch space */ +	for (i = 0; i < 16; i++) { +		dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2)); +		dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); +	} +	for (i = 0; i < 3; i++) +		dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); + +	i915_save_vga(dev); + +	return 0; +} + +int i915_restore_state(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	int i; + +#if defined(__FreeBSD__) +	pci_write_config(dev->device, LBB, dev_priv->saveLBB, 1); +#else +	pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); +#endif + +	I915_WRITE(DSPARB, dev_priv->saveDSPARB); + +	/* 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, dev_priv->saveFPA0); +	I915_WRITE(FPA1, dev_priv->saveFPA1); +	/* Actually enable it */ +	I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); +	DRM_UDELAY(150); +	if (IS_I965G(dev)) +		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); +	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(DSPABASE, dev_priv->saveDSPABASE); +	I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); +	if (IS_I965G(dev)) { +		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(DSPABASE, I915_READ(DSPABASE)); + +	/* 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, dev_priv->saveFPB0); +	I915_WRITE(FPB1, dev_priv->saveFPB1); +	/* Actually enable it */ +	I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); +	DRM_UDELAY(150); +	if (IS_I965G(dev)) +		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); +	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(DSPBBASE, dev_priv->saveDSPBBASE); +	I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); +	if (IS_I965G(dev)) { +		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(DSPBBASE, I915_READ(DSPBBASE)); + +	/* CRT state */ +	I915_WRITE(ADPA, dev_priv->saveADPA); + +	/* LVDS state */ +	if (IS_I965G(dev)) +		I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); +	if (IS_MOBILE(dev) && !IS_I830(dev)) +		I915_WRITE(LVDS, dev_priv->saveLVDS); +	if (!IS_I830(dev) && !IS_845G(dev)) +		I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); + +	I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); +	I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); +	I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON); +	I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF); +	I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); +	I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); + +	/* FIXME: restore TV & SDVO state */ + +	/* FBC info */ +	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 */ +	I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); +	I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0); +	I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1); +	I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV); +	DRM_UDELAY(150); + +	/* Clock gating state */ +	I915_WRITE (D_STATE, dev_priv->saveD_STATE); +	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); + +	/* Cache mode state */ +	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + +	/* Memory arbitration state */ +	I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); + +	for (i = 0; i < 16; i++) { +		I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]); +		I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); +	} +	for (i = 0; i < 3; i++) +		I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); + +	i915_restore_vga(dev); + +	return 0; +} +  | 
