2008-08-25 15:11:06 -07:00
/*
*
* 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 .
*/
2012-10-02 18:01:07 +01:00
# include <drm/drmP.h>
# include <drm/i915_drm.h>
2009-12-01 11:56:30 -08:00
# include "intel_drv.h"
2012-01-07 23:40:34 -02:00
# include "i915_reg.h"
2008-08-25 15:11:06 -07:00
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 ;
2013-01-25 17:53:21 +01:00
/* VGA state */
dev_priv - > regfile . saveVGA0 = I915_READ ( VGA0 ) ;
dev_priv - > regfile . saveVGA1 = I915_READ ( VGA1 ) ;
dev_priv - > regfile . saveVGA_PD = I915_READ ( VGA_PD ) ;
2013-01-25 21:44:46 +02:00
dev_priv - > regfile . saveVGACNTRL = I915_READ ( i915_vgacntrl_reg ( dev ) ) ;
2013-01-25 17:53:21 +01:00
2008-08-25 15:11:06 -07:00
/* VGA color palette registers */
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveDACMASK = I915_READ8 ( VGA_DACMASK ) ;
2008-08-25 15:11:06 -07:00
/* MSR bits */
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveMSR = I915_READ8 ( VGA_MSR_READ ) ;
if ( dev_priv - > regfile . saveMSR & VGA_MSR_CGA_MODE ) {
2008-08-25 15:11:06 -07:00
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 + + )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveCR [ i ] =
2008-08-25 15:11:06 -07:00
i915_read_indexed ( dev , cr_index , cr_data , i ) ;
/* Make sure we don't turn off CR group 0 writes */
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveCR [ 0x11 ] & = ~ 0x80 ;
2008-08-25 15:11:06 -07:00
/* Attribute controller registers */
I915_READ8 ( st01 ) ;
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveAR_INDEX = I915_READ8 ( VGA_AR_INDEX ) ;
2008-08-25 15:11:06 -07:00
for ( i = 0 ; i < = 0x14 ; i + + )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveAR [ i ] = i915_read_ar ( dev , st01 , i , 0 ) ;
2008-08-25 15:11:06 -07:00
I915_READ8 ( st01 ) ;
2012-11-02 19:55:02 +01:00
I915_WRITE8 ( VGA_AR_INDEX , dev_priv - > regfile . saveAR_INDEX ) ;
2008-08-25 15:11:06 -07:00
I915_READ8 ( st01 ) ;
/* Graphics controller registers */
for ( i = 0 ; i < 9 ; i + + )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ i ] =
2008-08-25 15:11:06 -07:00
i915_read_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , i ) ;
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x10 ] =
2008-08-25 15:11:06 -07:00
i915_read_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x10 ) ;
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x11 ] =
2008-08-25 15:11:06 -07:00
i915_read_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x11 ) ;
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x18 ] =
2008-08-25 15:11:06 -07:00
i915_read_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x18 ) ;
/* Sequencer registers */
for ( i = 0 ; i < 8 ; i + + )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveSR [ i ] =
2008-08-25 15:11:06 -07:00
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 ;
2013-01-25 17:53:21 +01:00
/* VGA state */
2013-01-25 21:44:46 +02:00
I915_WRITE ( i915_vgacntrl_reg ( dev ) , dev_priv - > regfile . saveVGACNTRL ) ;
2013-01-25 17:53:21 +01:00
I915_WRITE ( VGA0 , dev_priv - > regfile . saveVGA0 ) ;
I915_WRITE ( VGA1 , dev_priv - > regfile . saveVGA1 ) ;
I915_WRITE ( VGA_PD , dev_priv - > regfile . saveVGA_PD ) ;
POSTING_READ ( VGA_PD ) ;
udelay ( 150 ) ;
2008-08-25 15:11:06 -07:00
/* MSR bits */
2012-11-02 19:55:02 +01:00
I915_WRITE8 ( VGA_MSR_WRITE , dev_priv - > regfile . saveMSR ) ;
if ( dev_priv - > regfile . saveMSR & VGA_MSR_CGA_MODE ) {
2008-08-25 15:11:06 -07:00
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 ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveSR [ i ] ) ;
2008-08-25 15:11:06 -07:00
/* CRT controller regs */
/* Enable CR group 0 writes */
2012-11-02 19:55:02 +01:00
i915_write_indexed ( dev , cr_index , cr_data , 0x11 , dev_priv - > regfile . saveCR [ 0x11 ] ) ;
2008-08-25 15:11:06 -07:00
for ( i = 0 ; i < = 0x24 ; i + + )
2012-11-02 19:55:02 +01:00
i915_write_indexed ( dev , cr_index , cr_data , i , dev_priv - > regfile . saveCR [ i ] ) ;
2008-08-25 15:11:06 -07:00
/* Graphics controller regs */
for ( i = 0 ; i < 9 ; i + + )
i915_write_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , i ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ i ] ) ;
2008-08-25 15:11:06 -07:00
i915_write_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x10 ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x10 ] ) ;
2008-08-25 15:11:06 -07:00
i915_write_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x11 ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x11 ] ) ;
2008-08-25 15:11:06 -07:00
i915_write_indexed ( dev , VGA_GR_INDEX , VGA_GR_DATA , 0x18 ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveGR [ 0x18 ] ) ;
2008-08-25 15:11:06 -07:00
/* Attribute controller registers */
I915_READ8 ( st01 ) ; /* switch back to index mode */
for ( i = 0 ; i < = 0x14 ; i + + )
2012-11-02 19:55:02 +01:00
i915_write_ar ( dev , st01 , i , dev_priv - > regfile . saveAR [ i ] , 0 ) ;
2008-08-25 15:11:06 -07:00
I915_READ8 ( st01 ) ; /* switch back to index mode */
2012-11-02 19:55:02 +01:00
I915_WRITE8 ( VGA_AR_INDEX , dev_priv - > regfile . saveAR_INDEX | 0x20 ) ;
2008-08-25 15:11:06 -07:00
I915_READ8 ( st01 ) ;
/* VGA color palette registers */
2012-11-02 19:55:02 +01:00
I915_WRITE8 ( VGA_DACMASK , dev_priv - > regfile . saveDACMASK ) ;
2008-08-25 15:11:06 -07:00
}
2011-06-29 00:30:34 -07:00
static void i915_save_display ( struct drm_device * dev )
2009-07-08 14:13:14 +08:00
{
struct drm_i915_private * dev_priv = dev - > dev_private ;
/* Display arbitration control */
2013-01-18 18:29:03 -02:00
if ( INTEL_INFO ( dev ) - > gen < = 4 )
dev_priv - > regfile . saveDSPARB = I915_READ ( DSPARB ) ;
2009-07-08 14:13:14 +08:00
/* This is only meaningful in non-KMS mode */
2012-11-02 19:55:02 +01:00
/* Don't regfile.save them in KMS mode */
2013-01-25 17:53:19 +01:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) )
2013-01-25 17:53:20 +01:00
i915_save_display_reg ( dev ) ;
2009-09-14 17:48:42 -04:00
2008-08-25 15:11:06 -07:00
/* LVDS state */
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePP_CONTROL = I915_READ ( PCH_PP_CONTROL ) ;
dev_priv - > regfile . saveBLC_PWM_CTL = I915_READ ( BLC_PWM_PCH_CTL1 ) ;
dev_priv - > regfile . saveBLC_PWM_CTL2 = I915_READ ( BLC_PWM_PCH_CTL2 ) ;
dev_priv - > regfile . saveBLC_CPU_PWM_CTL = I915_READ ( BLC_PWM_CPU_CTL ) ;
dev_priv - > regfile . saveBLC_CPU_PWM_CTL2 = I915_READ ( BLC_PWM_CPU_CTL2 ) ;
dev_priv - > regfile . saveLVDS = I915_READ ( PCH_LVDS ) ;
2009-10-21 15:27:01 +08:00
} else {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePP_CONTROL = I915_READ ( PP_CONTROL ) ;
dev_priv - > regfile . savePFIT_PGM_RATIOS = I915_READ ( PFIT_PGM_RATIOS ) ;
dev_priv - > regfile . saveBLC_PWM_CTL = I915_READ ( BLC_PWM_CTL ) ;
dev_priv - > regfile . saveBLC_HIST_CTL = I915_READ ( BLC_HIST_CTL ) ;
2010-09-17 00:32:17 +01:00
if ( INTEL_INFO ( dev ) - > gen > = 4 )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveBLC_PWM_CTL2 = I915_READ ( BLC_PWM_CTL2 ) ;
2009-10-21 15:27:01 +08:00
if ( IS_MOBILE ( dev ) & & ! IS_I830 ( dev ) )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveLVDS = I915_READ ( LVDS ) ;
2009-10-21 15:27:01 +08:00
}
2010-08-14 14:41:23 +01:00
if ( ! IS_I830 ( dev ) & & ! IS_845G ( dev ) & & ! HAS_PCH_SPLIT ( dev ) )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePFIT_CONTROL = I915_READ ( PFIT_CONTROL ) ;
2009-10-21 15:27:01 +08:00
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePP_ON_DELAYS = I915_READ ( PCH_PP_ON_DELAYS ) ;
dev_priv - > regfile . savePP_OFF_DELAYS = I915_READ ( PCH_PP_OFF_DELAYS ) ;
dev_priv - > regfile . savePP_DIVISOR = I915_READ ( PCH_PP_DIVISOR ) ;
2009-10-21 15:27:01 +08:00
} else {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePP_ON_DELAYS = I915_READ ( PP_ON_DELAYS ) ;
dev_priv - > regfile . savePP_OFF_DELAYS = I915_READ ( PP_OFF_DELAYS ) ;
dev_priv - > regfile . savePP_DIVISOR = I915_READ ( PP_DIVISOR ) ;
2009-10-21 15:27:01 +08:00
}
2008-08-25 15:11:06 -07:00
2012-11-02 19:55:02 +01:00
/* Only regfile.save FBC state on the platform that supports FBC */
2010-03-19 17:05:10 +08:00
if ( I915_HAS_FBC ( dev ) ) {
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveDPFC_CB_BASE = I915_READ ( ILK_DPFC_CB_BASE ) ;
2010-06-12 14:32:27 +08:00
} else if ( IS_GM45 ( dev ) ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveDPFC_CB_BASE = I915_READ ( DPFC_CB_BASE ) ;
2010-03-19 17:05:10 +08:00
} else {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveFBC_CFB_BASE = I915_READ ( FBC_CFB_BASE ) ;
dev_priv - > regfile . saveFBC_LL_BASE = I915_READ ( FBC_LL_BASE ) ;
dev_priv - > regfile . saveFBC_CONTROL2 = I915_READ ( FBC_CONTROL2 ) ;
dev_priv - > regfile . saveFBC_CONTROL = I915_READ ( FBC_CONTROL ) ;
2010-03-19 17:05:10 +08:00
}
2009-10-05 13:47:26 -07:00
}
2008-08-25 15:11:06 -07:00
2013-01-25 17:53:21 +01:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) )
i915_save_vga ( dev ) ;
2008-08-25 15:11:06 -07:00
}
2011-06-29 00:30:34 -07:00
static void i915_restore_display ( struct drm_device * dev )
2008-08-25 15:11:06 -07:00
{
struct drm_i915_private * dev_priv = dev - > dev_private ;
2013-02-19 12:11:38 -08:00
u32 mask = 0xffffffff ;
2008-11-18 12:39:02 +08:00
2008-11-02 23:08:44 -08:00
/* Display arbitration */
2013-01-18 18:29:03 -02:00
if ( INTEL_INFO ( dev ) - > gen < = 4 )
I915_WRITE ( DSPARB , dev_priv - > regfile . saveDSPARB ) ;
2008-08-25 15:11:06 -07:00
2013-01-25 17:53:19 +01:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) )
2013-01-25 17:53:20 +01:00
i915_restore_display_reg ( dev ) ;
2009-09-14 17:48:42 -04:00
2008-08-25 15:11:06 -07:00
/* LVDS state */
2010-09-17 00:32:17 +01:00
if ( INTEL_INFO ( dev ) - > gen > = 4 & & ! HAS_PCH_SPLIT ( dev ) )
2012-11-02 19:55:02 +01:00
I915_WRITE ( BLC_PWM_CTL2 , dev_priv - > regfile . saveBLC_PWM_CTL2 ) ;
2009-10-21 15:27:01 +08:00
2013-02-19 12:11:38 -08:00
if ( drm_core_check_feature ( dev , DRIVER_MODESET ) )
mask = ~ LVDS_PORT_EN ;
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2013-02-19 12:11:38 -08:00
I915_WRITE ( PCH_LVDS , dev_priv - > regfile . saveLVDS & mask ) ;
2009-10-21 15:27:01 +08:00
} else if ( IS_MOBILE ( dev ) & & ! IS_I830 ( dev ) )
2013-02-19 12:11:38 -08:00
I915_WRITE ( LVDS , dev_priv - > regfile . saveLVDS & mask ) ;
2009-10-21 15:27:01 +08:00
2010-08-14 14:41:23 +01:00
if ( ! IS_I830 ( dev ) & & ! IS_845G ( dev ) & & ! HAS_PCH_SPLIT ( dev ) )
2012-11-02 19:55:02 +01:00
I915_WRITE ( PFIT_CONTROL , dev_priv - > regfile . savePFIT_CONTROL ) ;
2008-08-25 15:11:06 -07:00
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
I915_WRITE ( BLC_PWM_PCH_CTL1 , dev_priv - > regfile . saveBLC_PWM_CTL ) ;
I915_WRITE ( BLC_PWM_PCH_CTL2 , dev_priv - > regfile . saveBLC_PWM_CTL2 ) ;
2012-06-21 15:30:41 +02:00
/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
* otherwise we get blank eDP screen after S3 on some machines
*/
2012-11-02 19:55:02 +01:00
I915_WRITE ( BLC_PWM_CPU_CTL2 , dev_priv - > regfile . saveBLC_CPU_PWM_CTL2 ) ;
I915_WRITE ( BLC_PWM_CPU_CTL , dev_priv - > regfile . saveBLC_CPU_PWM_CTL ) ;
I915_WRITE ( PCH_PP_ON_DELAYS , dev_priv - > regfile . savePP_ON_DELAYS ) ;
I915_WRITE ( PCH_PP_OFF_DELAYS , dev_priv - > regfile . savePP_OFF_DELAYS ) ;
I915_WRITE ( PCH_PP_DIVISOR , dev_priv - > regfile . savePP_DIVISOR ) ;
I915_WRITE ( PCH_PP_CONTROL , dev_priv - > regfile . savePP_CONTROL ) ;
2011-01-05 12:01:24 -08:00
I915_WRITE ( RSTDBYCTL ,
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveMCHBAR_RENDER_STANDBY ) ;
2009-10-21 15:27:01 +08:00
} else {
2012-11-02 19:55:02 +01:00
I915_WRITE ( PFIT_PGM_RATIOS , dev_priv - > regfile . savePFIT_PGM_RATIOS ) ;
I915_WRITE ( BLC_PWM_CTL , dev_priv - > regfile . saveBLC_PWM_CTL ) ;
I915_WRITE ( BLC_HIST_CTL , dev_priv - > regfile . saveBLC_HIST_CTL ) ;
I915_WRITE ( PP_ON_DELAYS , dev_priv - > regfile . savePP_ON_DELAYS ) ;
I915_WRITE ( PP_OFF_DELAYS , dev_priv - > regfile . savePP_OFF_DELAYS ) ;
I915_WRITE ( PP_DIVISOR , dev_priv - > regfile . savePP_DIVISOR ) ;
I915_WRITE ( PP_CONTROL , dev_priv - > regfile . savePP_CONTROL ) ;
2009-10-21 15:27:01 +08:00
}
2008-08-25 15:11:06 -07:00
2010-03-19 17:05:10 +08:00
/* only restore FBC info on the platform that supports FBC*/
2011-07-08 12:22:36 +01:00
intel_disable_fbc ( dev ) ;
2010-03-19 17:05:10 +08:00
if ( I915_HAS_FBC ( dev ) ) {
2010-08-14 14:41:23 +01:00
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
I915_WRITE ( ILK_DPFC_CB_BASE , dev_priv - > regfile . saveDPFC_CB_BASE ) ;
2010-06-12 14:32:27 +08:00
} else if ( IS_GM45 ( dev ) ) {
2012-11-02 19:55:02 +01:00
I915_WRITE ( DPFC_CB_BASE , dev_priv - > regfile . saveDPFC_CB_BASE ) ;
2010-03-19 17:05:10 +08:00
} else {
2012-11-02 19:55:02 +01:00
I915_WRITE ( FBC_CFB_BASE , dev_priv - > regfile . saveFBC_CFB_BASE ) ;
I915_WRITE ( FBC_LL_BASE , dev_priv - > regfile . saveFBC_LL_BASE ) ;
I915_WRITE ( FBC_CONTROL2 , dev_priv - > regfile . saveFBC_CONTROL2 ) ;
I915_WRITE ( FBC_CONTROL , dev_priv - > regfile . saveFBC_CONTROL ) ;
2010-03-19 17:05:10 +08:00
}
2009-10-05 13:47:26 -07:00
}
2013-01-25 17:53:22 +01:00
2013-01-25 17:53:21 +01:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) )
i915_restore_vga ( dev ) ;
2009-10-21 15:27:01 +08:00
else
2013-01-25 17:53:21 +01:00
i915_redisable_vga ( dev ) ;
2009-09-14 17:48:42 -04:00
}
int i915_save_state ( struct drm_device * dev )
{
struct drm_i915_private * dev_priv = dev - > dev_private ;
int i ;
2012-11-02 19:55:02 +01:00
pci_read_config_byte ( dev - > pdev , LBB , & dev_priv - > regfile . saveLBB ) ;
2009-09-14 17:48:42 -04:00
2011-06-29 00:30:34 -07:00
mutex_lock ( & dev - > struct_mutex ) ;
2009-09-14 17:48:42 -04:00
i915_save_display ( dev ) ;
2012-10-17 11:32:56 +02:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) ) {
/* Interrupt state */
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveDEIER = I915_READ ( DEIER ) ;
dev_priv - > regfile . saveDEIMR = I915_READ ( DEIMR ) ;
dev_priv - > regfile . saveGTIER = I915_READ ( GTIER ) ;
dev_priv - > regfile . saveGTIMR = I915_READ ( GTIMR ) ;
dev_priv - > regfile . saveFDI_RXA_IMR = I915_READ ( _FDI_RXA_IMR ) ;
dev_priv - > regfile . saveFDI_RXB_IMR = I915_READ ( _FDI_RXB_IMR ) ;
dev_priv - > regfile . saveMCHBAR_RENDER_STANDBY =
2012-10-17 11:32:56 +02:00
I915_READ ( RSTDBYCTL ) ;
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . savePCH_PORT_HOTPLUG = I915_READ ( PCH_PORT_HOTPLUG ) ;
2012-10-17 11:32:56 +02:00
} else {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveIER = I915_READ ( IER ) ;
dev_priv - > regfile . saveIMR = I915_READ ( IMR ) ;
2012-10-17 11:32:56 +02:00
}
2009-10-21 15:27:01 +08:00
}
2009-09-14 17:48:42 -04:00
2012-06-24 16:42:32 +02:00
intel_disable_gt_powersave ( dev ) ;
2010-01-29 11:27:07 -08:00
2009-09-14 17:48:42 -04:00
/* Cache mode state */
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveCACHE_MODE_0 = I915_READ ( CACHE_MODE_0 ) ;
2009-09-14 17:48:42 -04:00
/* Memory Arbitration state */
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveMI_ARB_STATE = I915_READ ( MI_ARB_STATE ) ;
2009-09-14 17:48:42 -04:00
/* Scratch space */
for ( i = 0 ; i < 16 ; i + + ) {
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveSWF0 [ i ] = I915_READ ( SWF00 + ( i < < 2 ) ) ;
dev_priv - > regfile . saveSWF1 [ i ] = I915_READ ( SWF10 + ( i < < 2 ) ) ;
2009-09-14 17:48:42 -04:00
}
for ( i = 0 ; i < 3 ; i + + )
2012-11-02 19:55:02 +01:00
dev_priv - > regfile . saveSWF2 [ i ] = I915_READ ( SWF30 + ( i < < 2 ) ) ;
2009-09-14 17:48:42 -04:00
2011-06-29 00:30:34 -07:00
mutex_unlock ( & dev - > struct_mutex ) ;
2009-09-14 17:48:42 -04:00
return 0 ;
}
int i915_restore_state ( struct drm_device * dev )
{
struct drm_i915_private * dev_priv = dev - > dev_private ;
int i ;
2012-11-02 19:55:02 +01:00
pci_write_config_byte ( dev - > pdev , LBB , dev_priv - > regfile . saveLBB ) ;
2009-09-14 17:48:42 -04:00
2011-06-29 00:30:34 -07:00
mutex_lock ( & dev - > struct_mutex ) ;
2009-09-14 17:48:42 -04:00
i915_restore_display ( dev ) ;
2012-10-17 11:32:56 +02:00
if ( ! drm_core_check_feature ( dev , DRIVER_MODESET ) ) {
/* Interrupt state */
if ( HAS_PCH_SPLIT ( dev ) ) {
2012-11-02 19:55:02 +01:00
I915_WRITE ( DEIER , dev_priv - > regfile . saveDEIER ) ;
I915_WRITE ( DEIMR , dev_priv - > regfile . saveDEIMR ) ;
I915_WRITE ( GTIER , dev_priv - > regfile . saveGTIER ) ;
I915_WRITE ( GTIMR , dev_priv - > regfile . saveGTIMR ) ;
I915_WRITE ( _FDI_RXA_IMR , dev_priv - > regfile . saveFDI_RXA_IMR ) ;
I915_WRITE ( _FDI_RXB_IMR , dev_priv - > regfile . saveFDI_RXB_IMR ) ;
I915_WRITE ( PCH_PORT_HOTPLUG , dev_priv - > regfile . savePCH_PORT_HOTPLUG ) ;
2012-10-17 11:32:56 +02:00
} else {
2012-11-02 19:55:02 +01:00
I915_WRITE ( IER , dev_priv - > regfile . saveIER ) ;
I915_WRITE ( IMR , dev_priv - > regfile . saveIMR ) ;
2012-10-17 11:32:56 +02:00
}
2009-10-21 15:27:01 +08:00
}
2011-06-29 00:30:34 -07:00
2008-08-25 15:11:06 -07:00
/* Cache mode state */
2012-11-02 19:55:02 +01:00
I915_WRITE ( CACHE_MODE_0 , dev_priv - > regfile . saveCACHE_MODE_0 | 0xffff0000 ) ;
2008-08-25 15:11:06 -07:00
/* Memory arbitration state */
2012-11-02 19:55:02 +01:00
I915_WRITE ( MI_ARB_STATE , dev_priv - > regfile . saveMI_ARB_STATE | 0xffff0000 ) ;
2008-08-25 15:11:06 -07:00
for ( i = 0 ; i < 16 ; i + + ) {
2012-11-02 19:55:02 +01:00
I915_WRITE ( SWF00 + ( i < < 2 ) , dev_priv - > regfile . saveSWF0 [ i ] ) ;
I915_WRITE ( SWF10 + ( i < < 2 ) , dev_priv - > regfile . saveSWF1 [ i ] ) ;
2008-08-25 15:11:06 -07:00
}
for ( i = 0 ; i < 3 ; i + + )
2012-11-02 19:55:02 +01:00
I915_WRITE ( SWF30 + ( i < < 2 ) , dev_priv - > regfile . saveSWF2 [ i ] ) ;
2008-08-25 15:11:06 -07:00
2011-06-29 00:30:34 -07:00
mutex_unlock ( & dev - > struct_mutex ) ;
2010-07-20 15:44:45 -07:00
intel_i2c_reset ( dev ) ;
2009-12-01 11:56:30 -08:00
2008-08-25 15:11:06 -07:00
return 0 ;
}