drm/i915: Add more registers save/restore for Ironlake suspend
authorZhenyu Wang <zhenyuw@linux.intel.com>
Fri, 6 Nov 2009 02:13:02 +0000 (02:13 +0000)
committerEric Anholt <eric@anholt.net>
Thu, 12 Nov 2009 19:21:14 +0000 (11:21 -0800)
Add more display registers save/restore to fix unstable issues
during S4 testing on Ironlake. And DPLL_B_MD should not be restored
on Ironlake.

Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_suspend.c

index 57204e298975b4b9516f5be83734e442806bb76c..a725f6591192e2216798fc4dcf04108125795b3e 100644 (file)
@@ -296,6 +296,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_A;
        u32 saveVSYNC_A;
        u32 saveBCLRPAT_A;
+       u32 saveTRANSACONF;
        u32 saveTRANS_HTOTAL_A;
        u32 saveTRANS_HBLANK_A;
        u32 saveTRANS_HSYNC_A;
@@ -326,6 +327,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_B;
        u32 saveVSYNC_B;
        u32 saveBCLRPAT_B;
+       u32 saveTRANSBCONF;
        u32 saveTRANS_HTOTAL_B;
        u32 saveTRANS_HBLANK_B;
        u32 saveTRANS_HSYNC_B;
@@ -414,6 +416,16 @@ typedef struct drm_i915_private {
        u32 savePFB_WIN_SZ;
        u32 savePFA_WIN_POS;
        u32 savePFB_WIN_POS;
+       u32 savePCH_DREF_CONTROL;
+       u32 saveDISP_ARB_CTL;
+       u32 savePIPEA_DATA_M1;
+       u32 savePIPEA_DATA_N1;
+       u32 savePIPEA_LINK_M1;
+       u32 savePIPEA_LINK_N1;
+       u32 savePIPEB_DATA_M1;
+       u32 savePIPEB_DATA_N1;
+       u32 savePIPEB_LINK_M1;
+       u32 savePIPEB_LINK_N1;
 
        struct {
                struct drm_mm gtt_space;
index 992d5617e79829d4a7586d81f4e4579a0de8c251..6eec8171a44e55f6000ec5545b8f4733c4cbe86a 100644 (file)
@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return;
 
+       if (IS_IGDNG(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);
@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
 
        if (IS_IGDNG(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);
 
@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                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);
@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
 
        if (IS_IGDNG(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);
 
@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                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);
@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                fpb1_reg = FPB1;
        }
 
+       if (IS_IGDNG(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) {
@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
 
        if (IS_IGDNG(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);
 
@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                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);
@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        /* Actually enable it */
        I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
        DRM_UDELAY(150);
-       if (IS_I965G(dev))
+       if (IS_I965G(dev) && !IS_IGDNG(dev))
                I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
        DRM_UDELAY(150);
 
@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
 
        if (IS_IGDNG(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);
 
@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                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);