Home | History | Annotate | Line # | Download | only in i915
i915_suspend.c revision 1.1.1.2.28.1
      1 /*	$NetBSD: i915_suspend.c,v 1.1.1.2.28.1 2018/09/06 06:56:17 pgoyette Exp $	*/
      2 
      3 /*
      4  *
      5  * Copyright 2008 (c) Intel Corporation
      6  *   Jesse Barnes <jbarnes (at) virtuousgeek.org>
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining a
      9  * copy of this software and associated documentation files (the
     10  * "Software"), to deal in the Software without restriction, including
     11  * without limitation the rights to use, copy, modify, merge, publish,
     12  * distribute, sub license, and/or sell copies of the Software, and to
     13  * permit persons to whom the Software is furnished to do so, subject to
     14  * the following conditions:
     15  *
     16  * The above copyright notice and this permission notice (including the
     17  * next paragraph) shall be included in all copies or substantial portions
     18  * of the Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     23  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     24  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     25  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     26  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: i915_suspend.c,v 1.1.1.2.28.1 2018/09/06 06:56:17 pgoyette Exp $");
     31 
     32 #include <drm/drmP.h>
     33 #include <drm/i915_drm.h>
     34 #include "intel_drv.h"
     35 #include "i915_reg.h"
     36 
     37 static void i915_save_display(struct drm_device *dev)
     38 {
     39 	struct drm_i915_private *dev_priv = dev->dev_private;
     40 
     41 	/* Display arbitration control */
     42 	if (INTEL_INFO(dev)->gen <= 4)
     43 		dev_priv->regfile.saveDSPARB = I915_READ(DSPARB);
     44 
     45 	/* LVDS state */
     46 	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
     47 		dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
     48 	else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
     49 		dev_priv->regfile.saveLVDS = I915_READ(LVDS);
     50 
     51 	/* Panel power sequencer */
     52 	if (HAS_PCH_SPLIT(dev)) {
     53 		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
     54 		dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
     55 		dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
     56 		dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
     57 	} else if (!IS_VALLEYVIEW(dev)) {
     58 		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
     59 		dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
     60 		dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
     61 		dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR);
     62 	}
     63 
     64 	/* save FBC interval */
     65 	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
     66 		dev_priv->regfile.saveFBC_CONTROL = I915_READ(FBC_CONTROL);
     67 }
     68 
     69 static void i915_restore_display(struct drm_device *dev)
     70 {
     71 	struct drm_i915_private *dev_priv = dev->dev_private;
     72 	u32 mask = 0xffffffff;
     73 
     74 	/* Display arbitration */
     75 	if (INTEL_INFO(dev)->gen <= 4)
     76 		I915_WRITE(DSPARB, dev_priv->regfile.saveDSPARB);
     77 
     78 	mask = ~LVDS_PORT_EN;
     79 
     80 	/* LVDS state */
     81 	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
     82 		I915_WRITE(PCH_LVDS, dev_priv->regfile.saveLVDS & mask);
     83 	else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
     84 		I915_WRITE(LVDS, dev_priv->regfile.saveLVDS & mask);
     85 
     86 	/* Panel power sequencer */
     87 	if (HAS_PCH_SPLIT(dev)) {
     88 		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
     89 		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
     90 		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
     91 		I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
     92 	} else if (!IS_VALLEYVIEW(dev)) {
     93 		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
     94 		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
     95 		I915_WRITE(PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
     96 		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
     97 	}
     98 
     99 	/* only restore FBC info on the platform that supports FBC*/
    100 	intel_fbc_disable(dev_priv);
    101 
    102 	/* restore FBC interval */
    103 	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev))
    104 		I915_WRITE(FBC_CONTROL, dev_priv->regfile.saveFBC_CONTROL);
    105 
    106 	i915_redisable_vga(dev);
    107 }
    108 
    109 int i915_save_state(struct drm_device *dev)
    110 {
    111 	struct drm_i915_private *dev_priv = dev->dev_private;
    112 	int i;
    113 
    114 	mutex_lock(&dev->struct_mutex);
    115 
    116 	i915_save_display(dev);
    117 
    118 	if (IS_GEN4(dev))
    119 		pci_read_config_word(dev->pdev, GCDGMBUS,
    120 				     &dev_priv->regfile.saveGCDGMBUS);
    121 
    122 	/* Cache mode state */
    123 	if (INTEL_INFO(dev)->gen < 7)
    124 		dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
    125 
    126 	/* Memory Arbitration state */
    127 	dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
    128 
    129 	/* Scratch space */
    130 	if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
    131 		for (i = 0; i < 7; i++) {
    132 			dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
    133 			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
    134 		}
    135 		for (i = 0; i < 3; i++)
    136 			dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
    137 	} else if (IS_GEN2(dev_priv)) {
    138 		for (i = 0; i < 7; i++)
    139 			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
    140 	} else if (HAS_GMCH_DISPLAY(dev_priv)) {
    141 		for (i = 0; i < 16; i++) {
    142 			dev_priv->regfile.saveSWF0[i] = I915_READ(SWF0(i));
    143 			dev_priv->regfile.saveSWF1[i] = I915_READ(SWF1(i));
    144 		}
    145 		for (i = 0; i < 3; i++)
    146 			dev_priv->regfile.saveSWF3[i] = I915_READ(SWF3(i));
    147 	}
    148 
    149 	mutex_unlock(&dev->struct_mutex);
    150 
    151 	return 0;
    152 }
    153 
    154 int i915_restore_state(struct drm_device *dev)
    155 {
    156 	struct drm_i915_private *dev_priv = dev->dev_private;
    157 	int i;
    158 
    159 	mutex_lock(&dev->struct_mutex);
    160 
    161 	i915_gem_restore_fences(dev);
    162 
    163 	if (IS_GEN4(dev))
    164 		pci_write_config_word(dev->pdev, GCDGMBUS,
    165 				      dev_priv->regfile.saveGCDGMBUS);
    166 	i915_restore_display(dev);
    167 
    168 	/* Cache mode state */
    169 	if (INTEL_INFO(dev)->gen < 7)
    170 		I915_WRITE(CACHE_MODE_0, dev_priv->regfile.saveCACHE_MODE_0 |
    171 			   0xffff0000);
    172 
    173 	/* Memory arbitration state */
    174 	I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000);
    175 
    176 	/* Scratch space */
    177 	if (IS_GEN2(dev_priv) && IS_MOBILE(dev_priv)) {
    178 		for (i = 0; i < 7; i++) {
    179 			I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
    180 			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
    181 		}
    182 		for (i = 0; i < 3; i++)
    183 			I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
    184 	} else if (IS_GEN2(dev_priv)) {
    185 		for (i = 0; i < 7; i++)
    186 			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
    187 	} else if (HAS_GMCH_DISPLAY(dev_priv)) {
    188 		for (i = 0; i < 16; i++) {
    189 			I915_WRITE(SWF0(i), dev_priv->regfile.saveSWF0[i]);
    190 			I915_WRITE(SWF1(i), dev_priv->regfile.saveSWF1[i]);
    191 		}
    192 		for (i = 0; i < 3; i++)
    193 			I915_WRITE(SWF3(i), dev_priv->regfile.saveSWF3[i]);
    194 	}
    195 
    196 	mutex_unlock(&dev->struct_mutex);
    197 
    198 	intel_i2c_reset(dev);
    199 
    200 	return 0;
    201 }
    202