1e555d299SFrançois Tigeot /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
2c4a9e910SFrançois Tigeot */
3e555d299SFrançois Tigeot /*
4e555d299SFrançois Tigeot *
5e555d299SFrançois Tigeot * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6c4a9e910SFrançois Tigeot * All Rights Reserved.
7c4a9e910SFrançois Tigeot *
8c4a9e910SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
9e555d299SFrançois Tigeot * copy of this software and associated documentation files (the
10e555d299SFrançois Tigeot * "Software"), to deal in the Software without restriction, including
11e555d299SFrançois Tigeot * without limitation the rights to use, copy, modify, merge, publish,
12e555d299SFrançois Tigeot * distribute, sub license, and/or sell copies of the Software, and to
13e555d299SFrançois Tigeot * permit persons to whom the Software is furnished to do so, subject to
14e555d299SFrançois Tigeot * the following conditions:
15c4a9e910SFrançois Tigeot *
16e555d299SFrançois Tigeot * The above copyright notice and this permission notice (including the
17e555d299SFrançois Tigeot * next paragraph) shall be included in all copies or substantial portions
18e555d299SFrançois Tigeot * of the Software.
19c4a9e910SFrançois Tigeot *
20e555d299SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21e555d299SFrançois Tigeot * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22e555d299SFrançois Tigeot * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23e555d299SFrançois Tigeot * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24e555d299SFrançois Tigeot * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25e555d299SFrançois Tigeot * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26e555d299SFrançois Tigeot * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27c4a9e910SFrançois Tigeot *
28c4a9e910SFrançois Tigeot */
29c4a9e910SFrançois Tigeot
30ceb653e4SFrançois Tigeot #ifdef __DragonFly__
31ceb653e4SFrançois Tigeot #include "opt_drm.h" /* for VGA_SWITCHEROO */
32ceb653e4SFrançois Tigeot #endif
33ceb653e4SFrançois Tigeot
34922e7c40SFrançois Tigeot #include <linux/acpi.h>
351487f786SFrançois Tigeot #include <linux/device.h>
3671f41f3eSFrançois Tigeot #include <linux/oom.h>
379edbd4a0SFrançois Tigeot #include <linux/module.h>
381487f786SFrançois Tigeot #include <linux/pci.h>
391487f786SFrançois Tigeot #include <linux/pm.h>
40922e7c40SFrançois Tigeot #include <linux/pm_runtime.h>
4171f41f3eSFrançois Tigeot #include <linux/pnp.h>
421487f786SFrançois Tigeot #include <linux/slab.h>
43922e7c40SFrançois Tigeot #include <linux/vgaarb.h>
448621f407SFrançois Tigeot #include <linux/vga_switcheroo.h>
4571f41f3eSFrançois Tigeot #include <linux/vt.h>
461487f786SFrançois Tigeot #include <acpi/video.h>
471487f786SFrançois Tigeot
481487f786SFrançois Tigeot #include <drm/drmP.h>
499edbd4a0SFrançois Tigeot #include <drm/drm_crtc_helper.h>
50a85cb24fSFrançois Tigeot #include <drm/drm_atomic_helper.h>
511487f786SFrançois Tigeot #include <drm/i915_drm.h>
521487f786SFrançois Tigeot
531487f786SFrançois Tigeot #include "i915_drv.h"
541487f786SFrançois Tigeot #include "i915_trace.h"
551487f786SFrançois Tigeot #include "i915_vgpu.h"
561487f786SFrançois Tigeot #include "intel_drv.h"
57a85cb24fSFrançois Tigeot #include "intel_uc.h"
589edbd4a0SFrançois Tigeot
59f0b54121SFrançois Tigeot static struct drm_driver driver;
60f0b54121SFrançois Tigeot
611487f786SFrançois Tigeot static unsigned int i915_load_fail_count;
621487f786SFrançois Tigeot
__i915_inject_load_failure(const char * func,int line)631487f786SFrançois Tigeot bool __i915_inject_load_failure(const char *func, int line)
641487f786SFrançois Tigeot {
65*3f2dd94aSFrançois Tigeot if (i915_load_fail_count >= i915_modparams.inject_load_failure)
661487f786SFrançois Tigeot return false;
671487f786SFrançois Tigeot
68*3f2dd94aSFrançois Tigeot if (++i915_load_fail_count == i915_modparams.inject_load_failure) {
691487f786SFrançois Tigeot DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
70*3f2dd94aSFrançois Tigeot i915_modparams.inject_load_failure, func, line);
711487f786SFrançois Tigeot return true;
721487f786SFrançois Tigeot }
731487f786SFrançois Tigeot
741487f786SFrançois Tigeot return false;
751487f786SFrançois Tigeot }
761487f786SFrançois Tigeot
771487f786SFrançois Tigeot #define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI"
781487f786SFrançois Tigeot #define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \
791487f786SFrançois Tigeot "providing the dmesg log by booting with drm.debug=0xf"
801487f786SFrançois Tigeot
811487f786SFrançois Tigeot void
__i915_printk(struct drm_i915_private * dev_priv,const char * level,const char * fmt,...)821487f786SFrançois Tigeot __i915_printk(struct drm_i915_private *dev_priv, const char *level,
831487f786SFrançois Tigeot const char *fmt, ...)
841487f786SFrançois Tigeot {
851487f786SFrançois Tigeot static bool shown_bug_once;
861e12ee3bSFrançois Tigeot struct device *kdev = dev_priv->drm.dev;
871487f786SFrançois Tigeot bool is_error = level[1] <= KERN_ERR[1];
881487f786SFrançois Tigeot bool is_debug = level[1] == KERN_DEBUG[1];
891487f786SFrançois Tigeot struct va_format vaf;
901487f786SFrançois Tigeot va_list args;
911487f786SFrançois Tigeot
921487f786SFrançois Tigeot if (is_debug && !(drm_debug & DRM_UT_DRIVER))
931487f786SFrançois Tigeot return;
941487f786SFrançois Tigeot
951487f786SFrançois Tigeot va_start(args, fmt);
961487f786SFrançois Tigeot
971487f786SFrançois Tigeot vaf.fmt = fmt;
981487f786SFrançois Tigeot vaf.va = &args;
991487f786SFrançois Tigeot
1001e12ee3bSFrançois Tigeot dev_printk(level, kdev, "[" DRM_NAME ":%ps] %pV",
1011487f786SFrançois Tigeot __builtin_return_address(0), &vaf);
1021487f786SFrançois Tigeot
1031487f786SFrançois Tigeot if (is_error && !shown_bug_once) {
1041e12ee3bSFrançois Tigeot dev_notice(kdev, "%s", FDO_BUG_MSG);
1051487f786SFrançois Tigeot shown_bug_once = true;
1061487f786SFrançois Tigeot }
1071487f786SFrançois Tigeot
1081487f786SFrançois Tigeot va_end(args);
1091487f786SFrançois Tigeot }
1101487f786SFrançois Tigeot
i915_error_injected(struct drm_i915_private * dev_priv)1111487f786SFrançois Tigeot static bool i915_error_injected(struct drm_i915_private *dev_priv)
1121487f786SFrançois Tigeot {
113*3f2dd94aSFrançois Tigeot return i915_modparams.inject_load_failure &&
114*3f2dd94aSFrançois Tigeot i915_load_fail_count == i915_modparams.inject_load_failure;
1151487f786SFrançois Tigeot }
1161487f786SFrançois Tigeot
1171487f786SFrançois Tigeot #define i915_load_error(dev_priv, fmt, ...) \
1181487f786SFrançois Tigeot __i915_printk(dev_priv, \
1191487f786SFrançois Tigeot i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
1201487f786SFrançois Tigeot fmt, ##__VA_ARGS__)
1211487f786SFrançois Tigeot
1221487f786SFrançois Tigeot
intel_virt_detect_pch(struct drm_i915_private * dev_priv)1231e12ee3bSFrançois Tigeot static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
124352ff8bdSFrançois Tigeot {
125352ff8bdSFrançois Tigeot enum intel_pch ret = PCH_NOP;
126352ff8bdSFrançois Tigeot
127352ff8bdSFrançois Tigeot /*
128352ff8bdSFrançois Tigeot * In a virtualized passthrough environment we can be in a
129352ff8bdSFrançois Tigeot * setup where the ISA bridge is not able to be passed through.
130352ff8bdSFrançois Tigeot * In this case, a south bridge can be emulated and we have to
131352ff8bdSFrançois Tigeot * make an educated guess as to which PCH is really there.
132352ff8bdSFrançois Tigeot */
133352ff8bdSFrançois Tigeot
1341e12ee3bSFrançois Tigeot if (IS_GEN5(dev_priv)) {
135352ff8bdSFrançois Tigeot ret = PCH_IBX;
136352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
1371e12ee3bSFrançois Tigeot } else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
138352ff8bdSFrançois Tigeot ret = PCH_CPT;
139*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Assuming CougarPoint PCH\n");
1401e12ee3bSFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
141352ff8bdSFrançois Tigeot ret = PCH_LPT;
142*3f2dd94aSFrançois Tigeot if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
143*3f2dd94aSFrançois Tigeot dev_priv->pch_id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
144*3f2dd94aSFrançois Tigeot else
145*3f2dd94aSFrançois Tigeot dev_priv->pch_id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
146352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
1471e12ee3bSFrançois Tigeot } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
148352ff8bdSFrançois Tigeot ret = PCH_SPT;
149352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n");
150*3f2dd94aSFrançois Tigeot } else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
151*3f2dd94aSFrançois Tigeot ret = PCH_CNP;
152*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Assuming CannonPoint PCH\n");
153352ff8bdSFrançois Tigeot }
154352ff8bdSFrançois Tigeot
155352ff8bdSFrançois Tigeot return ret;
156352ff8bdSFrançois Tigeot }
157352ff8bdSFrançois Tigeot
intel_detect_pch(struct drm_i915_private * dev_priv)158a85cb24fSFrançois Tigeot static void intel_detect_pch(struct drm_i915_private *dev_priv)
159e9243325SFrançois Tigeot {
1605d302545SFrançois Tigeot device_t pch = NULL;
1611487f786SFrançois Tigeot struct pci_devinfo *di = NULL;
162e9243325SFrançois Tigeot
1638e26cdf6SFrançois Tigeot /* In all current cases, num_pipes is equivalent to the PCH_NOP setting
1648e26cdf6SFrançois Tigeot * (which really amounts to a PCH but no South Display).
1658e26cdf6SFrançois Tigeot */
1664be47400SFrançois Tigeot if (INTEL_INFO(dev_priv)->num_pipes == 0) {
1678e26cdf6SFrançois Tigeot dev_priv->pch_type = PCH_NOP;
1688e26cdf6SFrançois Tigeot return;
1698e26cdf6SFrançois Tigeot }
1708e26cdf6SFrançois Tigeot
1719edbd4a0SFrançois Tigeot /* XXX The ISA bridge probe causes some old Core2 machines to hang */
1724be47400SFrançois Tigeot if (INTEL_INFO(dev_priv)->gen < 5)
1739edbd4a0SFrançois Tigeot return;
1749edbd4a0SFrançois Tigeot
175e9243325SFrançois Tigeot /*
176e9243325SFrançois Tigeot * The reason to probe ISA bridge instead of Dev31:Fun0 is to
177e9243325SFrançois Tigeot * make graphics device passthrough work easy for VMM, that only
178e9243325SFrançois Tigeot * need to expose ISA bridge to let driver know the real hardware
179e9243325SFrançois Tigeot * underneath. This is a requirement from virtualization team.
1809edbd4a0SFrançois Tigeot *
1819edbd4a0SFrançois Tigeot * In some virtualized environments (e.g. XEN), there is irrelevant
1829edbd4a0SFrançois Tigeot * ISA bridge in the system. To work reliably, we should scan trhough
1839edbd4a0SFrançois Tigeot * all the ISA bridge devices and check for the first match, instead
1849edbd4a0SFrançois Tigeot * of only checking the first one.
185e9243325SFrançois Tigeot */
18627a0f882SMatthew Dillon while ((pch = pci_iterate_class(&di, PCIC_BRIDGE, PCIS_BRIDGE_ISA))) {
187bf017597SFrançois Tigeot if (pci_get_vendor(pch) == PCI_VENDOR_ID_INTEL) {
1889edbd4a0SFrançois Tigeot unsigned short id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
189*3f2dd94aSFrançois Tigeot
190e9243325SFrançois Tigeot dev_priv->pch_id = id;
191e9243325SFrançois Tigeot
192e9243325SFrançois Tigeot if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
193e9243325SFrançois Tigeot dev_priv->pch_type = PCH_IBX;
194e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
1951e12ee3bSFrançois Tigeot WARN_ON(!IS_GEN5(dev_priv));
196e9243325SFrançois Tigeot } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
197e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT;
198e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found CougarPoint PCH\n");
199*3f2dd94aSFrançois Tigeot WARN_ON(!IS_GEN6(dev_priv) &&
200*3f2dd94aSFrançois Tigeot !IS_IVYBRIDGE(dev_priv));
201e9243325SFrançois Tigeot } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
202e9243325SFrançois Tigeot /* PantherPoint is CPT compatible */
203e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT;
2049edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Found PantherPoint PCH\n");
205*3f2dd94aSFrançois Tigeot WARN_ON(!IS_GEN6(dev_priv) &&
206*3f2dd94aSFrançois Tigeot !IS_IVYBRIDGE(dev_priv));
207e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
208e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT;
209e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint PCH\n");
2101e12ee3bSFrançois Tigeot WARN_ON(!IS_HASWELL(dev_priv) &&
2111e12ee3bSFrançois Tigeot !IS_BROADWELL(dev_priv));
2121e12ee3bSFrançois Tigeot WARN_ON(IS_HSW_ULT(dev_priv) ||
2131e12ee3bSFrançois Tigeot IS_BDW_ULT(dev_priv));
214e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
215e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT;
216e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
2171e12ee3bSFrançois Tigeot WARN_ON(!IS_HASWELL(dev_priv) &&
2181e12ee3bSFrançois Tigeot !IS_BROADWELL(dev_priv));
2191e12ee3bSFrançois Tigeot WARN_ON(!IS_HSW_ULT(dev_priv) &&
2201e12ee3bSFrançois Tigeot !IS_BDW_ULT(dev_priv));
221*3f2dd94aSFrançois Tigeot } else if (id == INTEL_PCH_WPT_DEVICE_ID_TYPE) {
222*3f2dd94aSFrançois Tigeot /* WildcatPoint is LPT compatible */
223*3f2dd94aSFrançois Tigeot dev_priv->pch_type = PCH_LPT;
224*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
225*3f2dd94aSFrançois Tigeot WARN_ON(!IS_HASWELL(dev_priv) &&
226*3f2dd94aSFrançois Tigeot !IS_BROADWELL(dev_priv));
227*3f2dd94aSFrançois Tigeot WARN_ON(IS_HSW_ULT(dev_priv) ||
228*3f2dd94aSFrançois Tigeot IS_BDW_ULT(dev_priv));
229*3f2dd94aSFrançois Tigeot } else if (id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) {
230*3f2dd94aSFrançois Tigeot /* WildcatPoint is LPT compatible */
231*3f2dd94aSFrançois Tigeot dev_priv->pch_type = PCH_LPT;
232*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
233*3f2dd94aSFrançois Tigeot WARN_ON(!IS_HASWELL(dev_priv) &&
234*3f2dd94aSFrançois Tigeot !IS_BROADWELL(dev_priv));
235*3f2dd94aSFrançois Tigeot WARN_ON(!IS_HSW_ULT(dev_priv) &&
236*3f2dd94aSFrançois Tigeot !IS_BDW_ULT(dev_priv));
2372c9916cdSFrançois Tigeot } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
2382c9916cdSFrançois Tigeot dev_priv->pch_type = PCH_SPT;
2392c9916cdSFrançois Tigeot DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
2401e12ee3bSFrançois Tigeot WARN_ON(!IS_SKYLAKE(dev_priv) &&
2411e12ee3bSFrançois Tigeot !IS_KABYLAKE(dev_priv));
2422c9916cdSFrançois Tigeot } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
2432c9916cdSFrançois Tigeot dev_priv->pch_type = PCH_SPT;
2442c9916cdSFrançois Tigeot DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
2451e12ee3bSFrançois Tigeot WARN_ON(!IS_SKYLAKE(dev_priv) &&
2461e12ee3bSFrançois Tigeot !IS_KABYLAKE(dev_priv));
247303bf270SFrançois Tigeot } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
248303bf270SFrançois Tigeot dev_priv->pch_type = PCH_KBP;
249*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
2504be47400SFrançois Tigeot WARN_ON(!IS_SKYLAKE(dev_priv) &&
251*3f2dd94aSFrançois Tigeot !IS_KABYLAKE(dev_priv) &&
252*3f2dd94aSFrançois Tigeot !IS_COFFEELAKE(dev_priv));
253*3f2dd94aSFrançois Tigeot } else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
254*3f2dd94aSFrançois Tigeot dev_priv->pch_type = PCH_CNP;
255*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
256*3f2dd94aSFrançois Tigeot WARN_ON(!IS_CANNONLAKE(dev_priv) &&
257*3f2dd94aSFrançois Tigeot !IS_COFFEELAKE(dev_priv));
258*3f2dd94aSFrançois Tigeot } else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
259*3f2dd94aSFrançois Tigeot dev_priv->pch_type = PCH_CNP;
260*3f2dd94aSFrançois Tigeot DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
261*3f2dd94aSFrançois Tigeot WARN_ON(!IS_CANNONLAKE(dev_priv) &&
262*3f2dd94aSFrançois Tigeot !IS_COFFEELAKE(dev_priv));
263*3f2dd94aSFrançois Tigeot } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
264*3f2dd94aSFrançois Tigeot id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
265*3f2dd94aSFrançois Tigeot (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
2668621f407SFrançois Tigeot 1)) {
2671e12ee3bSFrançois Tigeot dev_priv->pch_type =
2681e12ee3bSFrançois Tigeot intel_virt_detect_pch(dev_priv);
2699edbd4a0SFrançois Tigeot } else
2709edbd4a0SFrançois Tigeot continue;
2719edbd4a0SFrançois Tigeot
2729edbd4a0SFrançois Tigeot break;
273e9243325SFrançois Tigeot }
274e9243325SFrançois Tigeot }
2759edbd4a0SFrançois Tigeot if (!pch)
2769edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("No PCH found.\n");
2779edbd4a0SFrançois Tigeot
278e9243325SFrançois Tigeot #if 0
279e9243325SFrançois Tigeot pci_dev_put(pch);
280e9243325SFrançois Tigeot #endif
281e9243325SFrançois Tigeot }
282e9243325SFrançois Tigeot
i915_getparam(struct drm_device * dev,void * data,struct drm_file * file_priv)2831487f786SFrançois Tigeot static int i915_getparam(struct drm_device *dev, void *data,
2841487f786SFrançois Tigeot struct drm_file *file_priv)
2851487f786SFrançois Tigeot {
286303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
2871e12ee3bSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
2881487f786SFrançois Tigeot drm_i915_getparam_t *param = data;
2891487f786SFrançois Tigeot int value;
2901487f786SFrançois Tigeot
2911487f786SFrançois Tigeot switch (param->param) {
2921487f786SFrançois Tigeot case I915_PARAM_IRQ_ACTIVE:
2931487f786SFrançois Tigeot case I915_PARAM_ALLOW_BATCHBUFFER:
2941487f786SFrançois Tigeot case I915_PARAM_LAST_DISPATCH:
2954be47400SFrançois Tigeot case I915_PARAM_HAS_EXEC_CONSTANTS:
2961487f786SFrançois Tigeot /* Reject all old ums/dri params. */
2971487f786SFrançois Tigeot return -ENODEV;
2981487f786SFrançois Tigeot case I915_PARAM_CHIPSET_ID:
2991e12ee3bSFrançois Tigeot value = pdev->device;
3001487f786SFrançois Tigeot break;
3011487f786SFrançois Tigeot case I915_PARAM_REVISION:
3021e12ee3bSFrançois Tigeot value = pdev->revision;
3031487f786SFrançois Tigeot break;
3041487f786SFrançois Tigeot case I915_PARAM_NUM_FENCES_AVAIL:
3051487f786SFrançois Tigeot value = dev_priv->num_fence_regs;
3061487f786SFrançois Tigeot break;
3071487f786SFrançois Tigeot case I915_PARAM_HAS_OVERLAY:
3081487f786SFrançois Tigeot value = dev_priv->overlay ? 1 : 0;
3091487f786SFrançois Tigeot break;
3101487f786SFrançois Tigeot case I915_PARAM_HAS_BSD:
3111e12ee3bSFrançois Tigeot value = !!dev_priv->engine[VCS];
3121487f786SFrançois Tigeot break;
3131487f786SFrançois Tigeot case I915_PARAM_HAS_BLT:
3141e12ee3bSFrançois Tigeot value = !!dev_priv->engine[BCS];
3151487f786SFrançois Tigeot break;
3161487f786SFrançois Tigeot case I915_PARAM_HAS_VEBOX:
3171e12ee3bSFrançois Tigeot value = !!dev_priv->engine[VECS];
3181487f786SFrançois Tigeot break;
3191487f786SFrançois Tigeot case I915_PARAM_HAS_BSD2:
3201e12ee3bSFrançois Tigeot value = !!dev_priv->engine[VCS2];
3211487f786SFrançois Tigeot break;
3221487f786SFrançois Tigeot case I915_PARAM_HAS_LLC:
3231e12ee3bSFrançois Tigeot value = HAS_LLC(dev_priv);
3241487f786SFrançois Tigeot break;
3251487f786SFrançois Tigeot case I915_PARAM_HAS_WT:
3261e12ee3bSFrançois Tigeot value = HAS_WT(dev_priv);
3271487f786SFrançois Tigeot break;
3281487f786SFrançois Tigeot case I915_PARAM_HAS_ALIASING_PPGTT:
3291e12ee3bSFrançois Tigeot value = USES_PPGTT(dev_priv);
3301487f786SFrançois Tigeot break;
3311487f786SFrançois Tigeot case I915_PARAM_HAS_SEMAPHORES:
332*3f2dd94aSFrançois Tigeot value = i915_modparams.semaphores;
3331487f786SFrançois Tigeot break;
3341e12ee3bSFrançois Tigeot #if 0
3351e12ee3bSFrançois Tigeot case I915_PARAM_HAS_SECURE_BATCHES:
3361e12ee3bSFrançois Tigeot value = capable(CAP_SYS_ADMIN);
3371487f786SFrançois Tigeot break;
3381e12ee3bSFrançois Tigeot #endif
3391487f786SFrançois Tigeot case I915_PARAM_CMD_PARSER_VERSION:
3401487f786SFrançois Tigeot value = i915_cmd_parser_get_version(dev_priv);
3411487f786SFrançois Tigeot break;
3421487f786SFrançois Tigeot case I915_PARAM_SUBSLICE_TOTAL:
3431e12ee3bSFrançois Tigeot value = sseu_subslice_total(&INTEL_INFO(dev_priv)->sseu);
3441487f786SFrançois Tigeot if (!value)
3451487f786SFrançois Tigeot return -ENODEV;
3461487f786SFrançois Tigeot break;
3471487f786SFrançois Tigeot case I915_PARAM_EU_TOTAL:
3481e12ee3bSFrançois Tigeot value = INTEL_INFO(dev_priv)->sseu.eu_total;
3491487f786SFrançois Tigeot if (!value)
3501487f786SFrançois Tigeot return -ENODEV;
3511487f786SFrançois Tigeot break;
3521487f786SFrançois Tigeot case I915_PARAM_HAS_GPU_RESET:
353*3f2dd94aSFrançois Tigeot value = i915_modparams.enable_hangcheck &&
354*3f2dd94aSFrançois Tigeot intel_has_gpu_reset(dev_priv);
355*3f2dd94aSFrançois Tigeot if (value && intel_has_reset_engine(dev_priv))
356*3f2dd94aSFrançois Tigeot value = 2;
3571487f786SFrançois Tigeot break;
3581487f786SFrançois Tigeot case I915_PARAM_HAS_RESOURCE_STREAMER:
3591e12ee3bSFrançois Tigeot value = HAS_RESOURCE_STREAMER(dev_priv);
3601487f786SFrançois Tigeot break;
3611487f786SFrançois Tigeot case I915_PARAM_HAS_POOLED_EU:
3621e12ee3bSFrançois Tigeot value = HAS_POOLED_EU(dev_priv);
3631487f786SFrançois Tigeot break;
3641487f786SFrançois Tigeot case I915_PARAM_MIN_EU_IN_POOL:
3651e12ee3bSFrançois Tigeot value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
3661e12ee3bSFrançois Tigeot break;
367a85cb24fSFrançois Tigeot case I915_PARAM_HUC_STATUS:
368a85cb24fSFrançois Tigeot intel_runtime_pm_get(dev_priv);
369a85cb24fSFrançois Tigeot value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
370a85cb24fSFrançois Tigeot intel_runtime_pm_put(dev_priv);
371a85cb24fSFrançois Tigeot break;
3721e12ee3bSFrançois Tigeot case I915_PARAM_MMAP_GTT_VERSION:
3731e12ee3bSFrançois Tigeot /* Though we've started our numbering from 1, and so class all
3741e12ee3bSFrançois Tigeot * earlier versions as 0, in effect their value is undefined as
3751e12ee3bSFrançois Tigeot * the ioctl will report EINVAL for the unknown param!
3761e12ee3bSFrançois Tigeot */
3771e12ee3bSFrançois Tigeot value = i915_gem_mmap_gtt_version();
3781e12ee3bSFrançois Tigeot break;
3794be47400SFrançois Tigeot case I915_PARAM_HAS_SCHEDULER:
380*3f2dd94aSFrançois Tigeot value = 0;
381*3f2dd94aSFrançois Tigeot if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) {
382*3f2dd94aSFrançois Tigeot value |= I915_SCHEDULER_CAP_ENABLED;
383*3f2dd94aSFrançois Tigeot value |= I915_SCHEDULER_CAP_PRIORITY;
384*3f2dd94aSFrançois Tigeot
385*3f2dd94aSFrançois Tigeot if (INTEL_INFO(dev_priv)->has_logical_ring_preemption &&
386*3f2dd94aSFrançois Tigeot i915_modparams.enable_execlists &&
387*3f2dd94aSFrançois Tigeot !i915_modparams.enable_guc_submission)
388*3f2dd94aSFrançois Tigeot value |= I915_SCHEDULER_CAP_PREEMPTION;
389*3f2dd94aSFrançois Tigeot }
3904be47400SFrançois Tigeot break;
3911e12ee3bSFrançois Tigeot case I915_PARAM_MMAP_VERSION:
3921e12ee3bSFrançois Tigeot /* Remember to bump this if the version changes! */
3931e12ee3bSFrançois Tigeot case I915_PARAM_HAS_GEM:
3941e12ee3bSFrançois Tigeot case I915_PARAM_HAS_PAGEFLIPPING:
3951e12ee3bSFrançois Tigeot case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
3961e12ee3bSFrançois Tigeot case I915_PARAM_HAS_RELAXED_FENCING:
3971e12ee3bSFrançois Tigeot case I915_PARAM_HAS_COHERENT_RINGS:
3981e12ee3bSFrançois Tigeot case I915_PARAM_HAS_RELAXED_DELTA:
3991e12ee3bSFrançois Tigeot case I915_PARAM_HAS_GEN7_SOL_RESET:
4001e12ee3bSFrançois Tigeot case I915_PARAM_HAS_WAIT_TIMEOUT:
4011e12ee3bSFrançois Tigeot #if 0
4021e12ee3bSFrançois Tigeot case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
4031e12ee3bSFrançois Tigeot #endif
4041e12ee3bSFrançois Tigeot case I915_PARAM_HAS_PINNED_BATCHES:
4051e12ee3bSFrançois Tigeot case I915_PARAM_HAS_EXEC_NO_RELOC:
4061e12ee3bSFrançois Tigeot case I915_PARAM_HAS_EXEC_HANDLE_LUT:
4071e12ee3bSFrançois Tigeot case I915_PARAM_HAS_COHERENT_PHYS_GTT:
4081e12ee3bSFrançois Tigeot case I915_PARAM_HAS_EXEC_SOFTPIN:
409a85cb24fSFrançois Tigeot case I915_PARAM_HAS_EXEC_ASYNC:
410a85cb24fSFrançois Tigeot case I915_PARAM_HAS_EXEC_FENCE:
411*3f2dd94aSFrançois Tigeot case I915_PARAM_HAS_EXEC_CAPTURE:
412*3f2dd94aSFrançois Tigeot case I915_PARAM_HAS_EXEC_BATCH_FIRST:
413*3f2dd94aSFrançois Tigeot case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
4141e12ee3bSFrançois Tigeot /* For the time being all of these are always true;
4151e12ee3bSFrançois Tigeot * if some supported hardware does not have one of these
4161e12ee3bSFrançois Tigeot * features this value needs to be provided from
4171e12ee3bSFrançois Tigeot * INTEL_INFO(), a feature macro, or similar.
4181e12ee3bSFrançois Tigeot */
4191e12ee3bSFrançois Tigeot value = 1;
4201487f786SFrançois Tigeot break;
421*3f2dd94aSFrançois Tigeot case I915_PARAM_SLICE_MASK:
422*3f2dd94aSFrançois Tigeot value = INTEL_INFO(dev_priv)->sseu.slice_mask;
423*3f2dd94aSFrançois Tigeot if (!value)
424*3f2dd94aSFrançois Tigeot return -ENODEV;
425*3f2dd94aSFrançois Tigeot break;
426*3f2dd94aSFrançois Tigeot case I915_PARAM_SUBSLICE_MASK:
427*3f2dd94aSFrançois Tigeot value = INTEL_INFO(dev_priv)->sseu.subslice_mask;
428*3f2dd94aSFrançois Tigeot if (!value)
429*3f2dd94aSFrançois Tigeot return -ENODEV;
430*3f2dd94aSFrançois Tigeot break;
4311487f786SFrançois Tigeot default:
4321487f786SFrançois Tigeot DRM_DEBUG("Unknown parameter %d\n", param->param);
4331487f786SFrançois Tigeot return -EINVAL;
4341487f786SFrançois Tigeot }
4351487f786SFrançois Tigeot
4361487f786SFrançois Tigeot if (put_user(value, param->value))
4371487f786SFrançois Tigeot return -EFAULT;
4381487f786SFrançois Tigeot
4391487f786SFrançois Tigeot return 0;
4401487f786SFrançois Tigeot }
4411487f786SFrançois Tigeot
i915_get_bridge_dev(struct drm_i915_private * dev_priv)442a85cb24fSFrançois Tigeot static int i915_get_bridge_dev(struct drm_i915_private *dev_priv)
4431487f786SFrançois Tigeot {
4441487f786SFrançois Tigeot static struct pci_dev i915_bridge_dev;
4451487f786SFrançois Tigeot
4461487f786SFrançois Tigeot i915_bridge_dev.dev.bsddev = pci_find_dbsf(0, 0, 0, 0);
4471487f786SFrançois Tigeot if (!i915_bridge_dev.dev.bsddev) {
4481487f786SFrançois Tigeot DRM_ERROR("bridge device not found\n");
4491487f786SFrançois Tigeot return -1;
4501487f786SFrançois Tigeot }
4511487f786SFrançois Tigeot
4521487f786SFrançois Tigeot dev_priv->bridge_dev = &i915_bridge_dev;
4531487f786SFrançois Tigeot return 0;
4541487f786SFrançois Tigeot }
4551487f786SFrançois Tigeot
4561487f786SFrançois Tigeot /* Allocate space for the MCH regs if needed, return nonzero on error */
4571487f786SFrançois Tigeot static int
intel_alloc_mchbar_resource(struct drm_i915_private * dev_priv)458a85cb24fSFrançois Tigeot intel_alloc_mchbar_resource(struct drm_i915_private *dev_priv)
4591487f786SFrançois Tigeot {
4604be47400SFrançois Tigeot int reg = INTEL_GEN(dev_priv) >= 4 ? MCHBAR_I965 : MCHBAR_I915;
4611487f786SFrançois Tigeot u32 temp_lo, temp_hi = 0;
4621487f786SFrançois Tigeot u64 mchbar_addr;
463a85cb24fSFrançois Tigeot device_t bsddev, vga;
4641487f786SFrançois Tigeot
4654be47400SFrançois Tigeot if (INTEL_GEN(dev_priv) >= 4)
4661487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
4671487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
4681487f786SFrançois Tigeot mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
4691487f786SFrançois Tigeot
4701487f786SFrançois Tigeot /* If ACPI doesn't have it, assume we need to allocate it ourselves */
4711487f786SFrançois Tigeot #ifdef CONFIG_PNP
4721487f786SFrançois Tigeot if (mchbar_addr &&
4731487f786SFrançois Tigeot pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
4741487f786SFrançois Tigeot return 0;
47519c468b4SFrançois Tigeot #endif
47619c468b4SFrançois Tigeot
4771487f786SFrançois Tigeot /* Get some space for it */
478a85cb24fSFrançois Tigeot bsddev = dev_priv->bridge_dev->dev.bsddev;
479a85cb24fSFrançois Tigeot vga = device_get_parent(bsddev);
4801487f786SFrançois Tigeot dev_priv->mch_res_rid = 0x100;
4811487f786SFrançois Tigeot dev_priv->mch_res = BUS_ALLOC_RESOURCE(device_get_parent(vga),
482a85cb24fSFrançois Tigeot bsddev, SYS_RES_MEMORY, &dev_priv->mch_res_rid, 0, ~0UL,
4831487f786SFrançois Tigeot MCHBAR_SIZE, RF_ACTIVE | RF_SHAREABLE, -1);
4841487f786SFrançois Tigeot if (dev_priv->mch_res == NULL) {
485*3f2dd94aSFrançois Tigeot DRM_DEBUG_DRIVER("failed mchbar resource alloc\n");
4861487f786SFrançois Tigeot return (-ENOMEM);
4871487f786SFrançois Tigeot }
4881487f786SFrançois Tigeot
4894be47400SFrançois Tigeot if (INTEL_GEN(dev_priv) >= 4)
4901487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
4911487f786SFrançois Tigeot upper_32_bits(rman_get_start(dev_priv->mch_res)));
4921487f786SFrançois Tigeot
4931487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, reg,
4941487f786SFrançois Tigeot lower_32_bits(rman_get_start(dev_priv->mch_res)));
4951487f786SFrançois Tigeot return 0;
4961487f786SFrançois Tigeot }
4971487f786SFrançois Tigeot
4981487f786SFrançois Tigeot /* Setup MCHBAR if possible, return true if we should disable it again */
4991487f786SFrançois Tigeot static void
intel_setup_mchbar(struct drm_i915_private * dev_priv)500a85cb24fSFrançois Tigeot intel_setup_mchbar(struct drm_i915_private *dev_priv)
5011487f786SFrançois Tigeot {
5024be47400SFrançois Tigeot int mchbar_reg = INTEL_GEN(dev_priv) >= 4 ? MCHBAR_I965 : MCHBAR_I915;
5031487f786SFrançois Tigeot u32 temp;
5041487f786SFrançois Tigeot bool enabled;
5051487f786SFrançois Tigeot
5061e12ee3bSFrançois Tigeot if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
5071487f786SFrançois Tigeot return;
5081487f786SFrançois Tigeot
5091487f786SFrançois Tigeot dev_priv->mchbar_need_disable = false;
5101487f786SFrançois Tigeot
5111e12ee3bSFrançois Tigeot if (IS_I915G(dev_priv) || IS_I915GM(dev_priv)) {
5121487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp);
5131487f786SFrançois Tigeot enabled = !!(temp & DEVEN_MCHBAR_EN);
5141487f786SFrançois Tigeot } else {
5151487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
5161487f786SFrançois Tigeot enabled = temp & 1;
5171487f786SFrançois Tigeot }
5181487f786SFrançois Tigeot
5191487f786SFrançois Tigeot /* If it's already enabled, don't have to do anything */
5201487f786SFrançois Tigeot if (enabled)
5211487f786SFrançois Tigeot return;
5221487f786SFrançois Tigeot
523a85cb24fSFrançois Tigeot if (intel_alloc_mchbar_resource(dev_priv))
5241487f786SFrançois Tigeot return;
5251487f786SFrançois Tigeot
5261487f786SFrançois Tigeot dev_priv->mchbar_need_disable = true;
5271487f786SFrançois Tigeot
5281487f786SFrançois Tigeot /* Space is allocated or reserved, so enable it. */
5291e12ee3bSFrançois Tigeot if (IS_I915G(dev_priv) || IS_I915GM(dev_priv)) {
5301487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
5311487f786SFrançois Tigeot temp | DEVEN_MCHBAR_EN);
5321487f786SFrançois Tigeot } else {
5331487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
5341487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
5351487f786SFrançois Tigeot }
5361487f786SFrançois Tigeot }
5371487f786SFrançois Tigeot
5381487f786SFrançois Tigeot static void
intel_teardown_mchbar(struct drm_i915_private * dev_priv)539a85cb24fSFrançois Tigeot intel_teardown_mchbar(struct drm_i915_private *dev_priv)
5401487f786SFrançois Tigeot {
5414be47400SFrançois Tigeot int mchbar_reg = INTEL_GEN(dev_priv) >= 4 ? MCHBAR_I965 : MCHBAR_I915;
542a85cb24fSFrançois Tigeot device_t bsddev, vga;
5431487f786SFrançois Tigeot
5441487f786SFrançois Tigeot if (dev_priv->mchbar_need_disable) {
5451e12ee3bSFrançois Tigeot if (IS_I915G(dev_priv) || IS_I915GM(dev_priv)) {
5461487f786SFrançois Tigeot u32 deven_val;
5471487f786SFrançois Tigeot
5481487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, DEVEN,
5491487f786SFrançois Tigeot &deven_val);
5501487f786SFrançois Tigeot deven_val &= ~DEVEN_MCHBAR_EN;
5511487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
5521487f786SFrançois Tigeot deven_val);
5531487f786SFrançois Tigeot } else {
5541487f786SFrançois Tigeot u32 mchbar_val;
5551487f786SFrançois Tigeot
5561487f786SFrançois Tigeot pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg,
5571487f786SFrançois Tigeot &mchbar_val);
5581487f786SFrançois Tigeot mchbar_val &= ~1;
5591487f786SFrançois Tigeot pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg,
5601487f786SFrançois Tigeot mchbar_val);
5611487f786SFrançois Tigeot }
5621487f786SFrançois Tigeot }
5631487f786SFrançois Tigeot
564a85cb24fSFrançois Tigeot bsddev = dev_priv->bridge_dev->dev.bsddev;
5651487f786SFrançois Tigeot if (dev_priv->mch_res != NULL) {
566a85cb24fSFrançois Tigeot vga = device_get_parent(bsddev);
567a85cb24fSFrançois Tigeot BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), bsddev,
5681487f786SFrançois Tigeot SYS_RES_MEMORY, dev_priv->mch_res_rid, dev_priv->mch_res);
569a85cb24fSFrançois Tigeot BUS_RELEASE_RESOURCE(device_get_parent(vga), bsddev,
5701487f786SFrançois Tigeot SYS_RES_MEMORY, dev_priv->mch_res_rid, dev_priv->mch_res);
5711487f786SFrançois Tigeot dev_priv->mch_res = NULL;
5721487f786SFrançois Tigeot }
5731487f786SFrançois Tigeot }
5741487f786SFrançois Tigeot
5751487f786SFrançois Tigeot #if 0
5761487f786SFrançois Tigeot /* true = enable decode, false = disable decoder */
5771487f786SFrançois Tigeot static unsigned int i915_vga_set_decode(void *cookie, bool state)
5781487f786SFrançois Tigeot {
579a85cb24fSFrançois Tigeot struct drm_i915_private *dev_priv = cookie;
5801487f786SFrançois Tigeot
581a85cb24fSFrançois Tigeot intel_modeset_vga_set_state(dev_priv, state);
5821487f786SFrançois Tigeot if (state)
5831487f786SFrançois Tigeot return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
5841487f786SFrançois Tigeot VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
5851487f786SFrançois Tigeot else
5861487f786SFrançois Tigeot return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
5871487f786SFrançois Tigeot }
5881487f786SFrançois Tigeot
589a85cb24fSFrançois Tigeot static int i915_resume_switcheroo(struct drm_device *dev);
590a85cb24fSFrançois Tigeot static int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
591a85cb24fSFrançois Tigeot
5921487f786SFrançois Tigeot static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
5931487f786SFrançois Tigeot {
5941487f786SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev);
5951487f786SFrançois Tigeot pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
5961487f786SFrançois Tigeot
5971487f786SFrançois Tigeot if (state == VGA_SWITCHEROO_ON) {
5981487f786SFrançois Tigeot pr_info("switched on\n");
5991487f786SFrançois Tigeot dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
6001487f786SFrançois Tigeot /* i915 resume handler doesn't set to D0 */
6011e12ee3bSFrançois Tigeot pci_set_power_state(pdev, PCI_D0);
6021487f786SFrançois Tigeot i915_resume_switcheroo(dev);
6031487f786SFrançois Tigeot dev->switch_power_state = DRM_SWITCH_POWER_ON;
6041487f786SFrançois Tigeot } else {
6051487f786SFrançois Tigeot pr_info("switched off\n");
6061487f786SFrançois Tigeot dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
6071487f786SFrançois Tigeot i915_suspend_switcheroo(dev, pmm);
6081487f786SFrançois Tigeot dev->switch_power_state = DRM_SWITCH_POWER_OFF;
6091487f786SFrançois Tigeot }
6101487f786SFrançois Tigeot }
6111487f786SFrançois Tigeot
6121487f786SFrançois Tigeot static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
6131487f786SFrançois Tigeot {
6141487f786SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev);
6151487f786SFrançois Tigeot
6161487f786SFrançois Tigeot /*
6171487f786SFrançois Tigeot * FIXME: open_count is protected by drm_global_mutex but that would lead to
6181487f786SFrançois Tigeot * locking inversion with the driver load path. And the access here is
6191487f786SFrançois Tigeot * completely racy anyway. So don't bother with locking for now.
6201487f786SFrançois Tigeot */
6211487f786SFrançois Tigeot return dev->open_count == 0;
6221487f786SFrançois Tigeot }
6231487f786SFrançois Tigeot
6241487f786SFrançois Tigeot static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
6251487f786SFrançois Tigeot .set_gpu_state = i915_switcheroo_set_state,
6261487f786SFrançois Tigeot .reprobe = NULL,
6271487f786SFrançois Tigeot .can_switch = i915_switcheroo_can_switch,
6281487f786SFrançois Tigeot };
6291487f786SFrançois Tigeot #endif
6301487f786SFrançois Tigeot
i915_gem_fini(struct drm_i915_private * dev_priv)6314be47400SFrançois Tigeot static void i915_gem_fini(struct drm_i915_private *dev_priv)
6321487f786SFrançois Tigeot {
633*3f2dd94aSFrançois Tigeot /* Flush any outstanding unpin_work. */
634*3f2dd94aSFrançois Tigeot i915_gem_drain_workqueue(dev_priv);
635*3f2dd94aSFrançois Tigeot
6364be47400SFrançois Tigeot mutex_lock(&dev_priv->drm.struct_mutex);
637a85cb24fSFrançois Tigeot intel_uc_fini_hw(dev_priv);
638a85cb24fSFrançois Tigeot i915_gem_cleanup_engines(dev_priv);
639*3f2dd94aSFrançois Tigeot i915_gem_contexts_fini(dev_priv);
6404be47400SFrançois Tigeot mutex_unlock(&dev_priv->drm.struct_mutex);
6411487f786SFrançois Tigeot
642*3f2dd94aSFrançois Tigeot i915_gem_cleanup_userptr(dev_priv);
643*3f2dd94aSFrançois Tigeot
644a85cb24fSFrançois Tigeot i915_gem_drain_freed_objects(dev_priv);
6454be47400SFrançois Tigeot
646*3f2dd94aSFrançois Tigeot WARN_ON(!list_empty(&dev_priv->contexts.list));
6471487f786SFrançois Tigeot }
6481487f786SFrançois Tigeot
i915_load_modeset_init(struct drm_device * dev)6491487f786SFrançois Tigeot static int i915_load_modeset_init(struct drm_device *dev)
6501487f786SFrançois Tigeot {
651bf017597SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
6521487f786SFrançois Tigeot int ret;
6531487f786SFrançois Tigeot
6541487f786SFrançois Tigeot if (i915_inject_load_failure())
6551487f786SFrançois Tigeot return -ENODEV;
6561487f786SFrançois Tigeot
657a85cb24fSFrançois Tigeot intel_bios_init(dev_priv);
6581487f786SFrançois Tigeot
6591487f786SFrançois Tigeot /* If we have > 1 VGA cards, then we need to arbitrate access
6601487f786SFrançois Tigeot * to the common VGA resources.
6611487f786SFrançois Tigeot *
6621487f786SFrançois Tigeot * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
6631487f786SFrançois Tigeot * then we do not take part in VGA arbitration and the
6641487f786SFrançois Tigeot * vga_client_register() fails with -ENODEV.
6651487f786SFrançois Tigeot */
6661487f786SFrançois Tigeot #if 0
667a85cb24fSFrançois Tigeot ret = vga_client_register(pdev, dev_priv, NULL, i915_vga_set_decode);
6681487f786SFrançois Tigeot if (ret && ret != -ENODEV)
6691487f786SFrançois Tigeot goto out;
6701487f786SFrançois Tigeot
6711487f786SFrançois Tigeot intel_register_dsm_handler();
6721487f786SFrançois Tigeot
673a85cb24fSFrançois Tigeot ret = vga_switcheroo_register_client(pdev, &i915_switcheroo_ops, false);
6741487f786SFrançois Tigeot if (ret)
6751487f786SFrançois Tigeot goto cleanup_vga_client;
6761487f786SFrançois Tigeot #endif
6771487f786SFrançois Tigeot
6781487f786SFrançois Tigeot /* must happen before intel_power_domains_init_hw() on VLV/CHV */
6791487f786SFrançois Tigeot intel_update_rawclk(dev_priv);
6801487f786SFrançois Tigeot
6811487f786SFrançois Tigeot intel_power_domains_init_hw(dev_priv, false);
6821487f786SFrançois Tigeot
6831487f786SFrançois Tigeot intel_csr_ucode_init(dev_priv);
6841487f786SFrançois Tigeot
6851487f786SFrançois Tigeot ret = intel_irq_install(dev_priv);
6861487f786SFrançois Tigeot if (ret)
6871487f786SFrançois Tigeot goto cleanup_csr;
6881487f786SFrançois Tigeot
689a85cb24fSFrançois Tigeot intel_setup_gmbus(dev_priv);
6901487f786SFrançois Tigeot
6911487f786SFrançois Tigeot /* Important: The output setup functions called by modeset_init need
6921487f786SFrançois Tigeot * working irqs for e.g. gmbus and dp aux transfers. */
6934be47400SFrançois Tigeot ret = intel_modeset_init(dev);
6944be47400SFrançois Tigeot if (ret)
6954be47400SFrançois Tigeot goto cleanup_irq;
6961487f786SFrançois Tigeot
697a85cb24fSFrançois Tigeot intel_uc_init_fw(dev_priv);
6981487f786SFrançois Tigeot
699a85cb24fSFrançois Tigeot ret = i915_gem_init(dev_priv);
7001487f786SFrançois Tigeot if (ret)
701a85cb24fSFrançois Tigeot goto cleanup_uc;
7021487f786SFrançois Tigeot
7031487f786SFrançois Tigeot intel_modeset_gem_init(dev);
7041487f786SFrançois Tigeot
7054be47400SFrançois Tigeot if (INTEL_INFO(dev_priv)->num_pipes == 0)
7061487f786SFrançois Tigeot return 0;
7071487f786SFrançois Tigeot
7081487f786SFrançois Tigeot ret = intel_fbdev_init(dev);
7091487f786SFrançois Tigeot if (ret)
7101487f786SFrançois Tigeot goto cleanup_gem;
7111487f786SFrançois Tigeot
7121487f786SFrançois Tigeot /* Only enable hotplug handling once the fbdev is fully set up. */
7131487f786SFrançois Tigeot intel_hpd_init(dev_priv);
7141487f786SFrançois Tigeot
7151487f786SFrançois Tigeot drm_kms_helper_poll_init(dev);
7161487f786SFrançois Tigeot
7171487f786SFrançois Tigeot #ifdef __DragonFly__
7181487f786SFrançois Tigeot /*
7191487f786SFrançois Tigeot * If we are dealing with dual GPU machines the vga_switcheroo module
7201487f786SFrançois Tigeot * has been loaded. Machines with dual GPUs have an integrated graphics
7211487f786SFrançois Tigeot * device (IGD), which we assume is an Intel device. The other, the
7221487f786SFrançois Tigeot * discrete device (DIS), is either an NVidia or a Radeon device. For
7231487f786SFrançois Tigeot * now we will force switch the gmux so the intel driver outputs
7241487f786SFrançois Tigeot * both to the laptop panel and the external monitor.
7251487f786SFrançois Tigeot *
7261487f786SFrançois Tigeot * DragonFly does not have an nvidia native driver yet. In the future,
7271487f786SFrançois Tigeot * we will check for the radeon device: if present, we will leave
7281487f786SFrançois Tigeot * the gmux switch as it is, so the user can choose between the IGD and
7291487f786SFrançois Tigeot * the DIS using the /dev/vga_switcheroo device.
7301487f786SFrançois Tigeot */
7311487f786SFrançois Tigeot if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {
7321487f786SFrançois Tigeot ret = vga_switcheroo_force_migd();
7331487f786SFrançois Tigeot if (ret) {
7341487f786SFrançois Tigeot DRM_INFO("could not switch gmux to IGD\n");
7351487f786SFrançois Tigeot }
7361487f786SFrançois Tigeot }
7371487f786SFrançois Tigeot #endif
7381487f786SFrançois Tigeot
7391487f786SFrançois Tigeot return 0;
7401487f786SFrançois Tigeot
7411487f786SFrançois Tigeot cleanup_gem:
742a85cb24fSFrançois Tigeot if (i915_gem_suspend(dev_priv))
7431e12ee3bSFrançois Tigeot DRM_ERROR("failed to idle hardware; continuing to unload!\n");
7444be47400SFrançois Tigeot i915_gem_fini(dev_priv);
745a85cb24fSFrançois Tigeot cleanup_uc:
746a85cb24fSFrançois Tigeot intel_uc_fini_fw(dev_priv);
7471487f786SFrançois Tigeot cleanup_irq:
7481487f786SFrançois Tigeot drm_irq_uninstall(dev);
749a85cb24fSFrançois Tigeot intel_teardown_gmbus(dev_priv);
7501487f786SFrançois Tigeot cleanup_csr:
7511487f786SFrançois Tigeot intel_csr_ucode_fini(dev_priv);
7521487f786SFrançois Tigeot intel_power_domains_fini(dev_priv);
7531487f786SFrançois Tigeot #if 0
754a85cb24fSFrançois Tigeot vga_switcheroo_unregister_client(pdev);
7551487f786SFrançois Tigeot cleanup_vga_client:
756a85cb24fSFrançois Tigeot vga_client_register(pdev, NULL, NULL, NULL);
7571487f786SFrançois Tigeot out:
7581487f786SFrançois Tigeot #endif
7591487f786SFrançois Tigeot return ret;
7601487f786SFrançois Tigeot }
7611487f786SFrançois Tigeot
762a85cb24fSFrançois Tigeot #ifdef __DragonFly__
i915_kick_out_firmware_fb(struct drm_i915_private * dev_priv)763a85cb24fSFrançois Tigeot static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
764a85cb24fSFrançois Tigeot {
765a85cb24fSFrançois Tigeot return 0;
766a85cb24fSFrançois Tigeot }
767a85cb24fSFrançois Tigeot #else
i915_kick_out_firmware_fb(struct drm_i915_private * dev_priv)7681487f786SFrançois Tigeot static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
7691487f786SFrançois Tigeot {
7701487f786SFrançois Tigeot struct apertures_struct *ap;
771303bf270SFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
7721487f786SFrançois Tigeot struct i915_ggtt *ggtt = &dev_priv->ggtt;
7731487f786SFrançois Tigeot bool primary;
7741487f786SFrançois Tigeot int ret;
7751487f786SFrançois Tigeot
7761487f786SFrançois Tigeot ap = alloc_apertures(1);
7771487f786SFrançois Tigeot if (!ap)
7781487f786SFrançois Tigeot return -ENOMEM;
7791487f786SFrançois Tigeot
7801487f786SFrançois Tigeot ap->ranges[0].base = ggtt->mappable_base;
7811487f786SFrançois Tigeot ap->ranges[0].size = ggtt->mappable_end;
7821487f786SFrançois Tigeot
7831487f786SFrançois Tigeot primary =
7841487f786SFrançois Tigeot pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
7851487f786SFrançois Tigeot
7861e12ee3bSFrançois Tigeot ret = drm_fb_helper_remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
7871487f786SFrançois Tigeot
7881487f786SFrançois Tigeot kfree(ap);
7891487f786SFrançois Tigeot
7901487f786SFrançois Tigeot return ret;
7911487f786SFrançois Tigeot }
7921487f786SFrançois Tigeot #endif
7931487f786SFrançois Tigeot
7941487f786SFrançois Tigeot #if !defined(CONFIG_VGA_CONSOLE)
i915_kick_out_vgacon(struct drm_i915_private * dev_priv)7951487f786SFrançois Tigeot static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
7961487f786SFrançois Tigeot {
7971487f786SFrançois Tigeot return 0;
7981487f786SFrançois Tigeot }
7991487f786SFrançois Tigeot #elif !defined(CONFIG_DUMMY_CONSOLE)
i915_kick_out_vgacon(struct drm_i915_private * dev_priv)8001487f786SFrançois Tigeot static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
8011487f786SFrançois Tigeot {
8021487f786SFrançois Tigeot return -ENODEV;
8031487f786SFrançois Tigeot }
8041487f786SFrançois Tigeot #else
i915_kick_out_vgacon(struct drm_i915_private * dev_priv)8051487f786SFrançois Tigeot static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
8061487f786SFrançois Tigeot {
8071487f786SFrançois Tigeot int ret = 0;
8081487f786SFrançois Tigeot
8091487f786SFrançois Tigeot DRM_INFO("Replacing VGA console driver\n");
8101487f786SFrançois Tigeot
8111487f786SFrançois Tigeot console_lock();
8121487f786SFrançois Tigeot if (con_is_bound(&vga_con))
8131487f786SFrançois Tigeot ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
8141487f786SFrançois Tigeot if (ret == 0) {
8151487f786SFrançois Tigeot ret = do_unregister_con_driver(&vga_con);
8161487f786SFrançois Tigeot
8171487f786SFrançois Tigeot /* Ignore "already unregistered". */
8181487f786SFrançois Tigeot if (ret == -ENODEV)
8191487f786SFrançois Tigeot ret = 0;
8201487f786SFrançois Tigeot }
8211487f786SFrançois Tigeot console_unlock();
8221487f786SFrançois Tigeot
8231487f786SFrançois Tigeot return ret;
8241487f786SFrançois Tigeot }
8251487f786SFrançois Tigeot #endif
8261487f786SFrançois Tigeot
intel_init_dpio(struct drm_i915_private * dev_priv)8271487f786SFrançois Tigeot static void intel_init_dpio(struct drm_i915_private *dev_priv)
8281487f786SFrançois Tigeot {
8291487f786SFrançois Tigeot /*
8301487f786SFrançois Tigeot * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
8311487f786SFrançois Tigeot * CHV x1 PHY (DP/HDMI D)
8321487f786SFrançois Tigeot * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
8331487f786SFrançois Tigeot */
8341487f786SFrançois Tigeot if (IS_CHERRYVIEW(dev_priv)) {
8351487f786SFrançois Tigeot DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
8361487f786SFrançois Tigeot DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
8371487f786SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv)) {
8381487f786SFrançois Tigeot DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
8391487f786SFrançois Tigeot }
8401487f786SFrançois Tigeot }
8411487f786SFrançois Tigeot
i915_workqueues_init(struct drm_i915_private * dev_priv)8421487f786SFrançois Tigeot static int i915_workqueues_init(struct drm_i915_private *dev_priv)
8431487f786SFrançois Tigeot {
8441487f786SFrançois Tigeot /*
8451487f786SFrançois Tigeot * The i915 workqueue is primarily used for batched retirement of
8461487f786SFrançois Tigeot * requests (and thus managing bo) once the task has been completed
8471487f786SFrançois Tigeot * by the GPU. i915_gem_retire_requests() is called directly when we
8481487f786SFrançois Tigeot * need high-priority retirement, such as waiting for an explicit
8491487f786SFrançois Tigeot * bo.
8501487f786SFrançois Tigeot *
8511487f786SFrançois Tigeot * It is also used for periodic low-priority events, such as
8521487f786SFrançois Tigeot * idle-timers and recording error state.
8531487f786SFrançois Tigeot *
8541487f786SFrançois Tigeot * All tasks on the workqueue are expected to acquire the dev mutex
8551487f786SFrançois Tigeot * so there is no point in running more than one instance of the
8561487f786SFrançois Tigeot * workqueue at any time. Use an ordered one.
8571487f786SFrançois Tigeot */
8581487f786SFrançois Tigeot dev_priv->wq = alloc_ordered_workqueue("i915", 0);
8591487f786SFrançois Tigeot if (dev_priv->wq == NULL)
8601487f786SFrançois Tigeot goto out_err;
8611487f786SFrançois Tigeot
8621487f786SFrançois Tigeot dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
8631487f786SFrançois Tigeot if (dev_priv->hotplug.dp_wq == NULL)
8641487f786SFrançois Tigeot goto out_free_wq;
8651487f786SFrançois Tigeot
8661487f786SFrançois Tigeot return 0;
8671487f786SFrançois Tigeot
8681487f786SFrançois Tigeot out_free_wq:
8691487f786SFrançois Tigeot destroy_workqueue(dev_priv->wq);
8701487f786SFrançois Tigeot out_err:
8711487f786SFrançois Tigeot DRM_ERROR("Failed to allocate workqueues.\n");
8721487f786SFrançois Tigeot
8731487f786SFrançois Tigeot return -ENOMEM;
8741487f786SFrançois Tigeot }
8751487f786SFrançois Tigeot
i915_engines_cleanup(struct drm_i915_private * i915)876a85cb24fSFrançois Tigeot static void i915_engines_cleanup(struct drm_i915_private *i915)
877a85cb24fSFrançois Tigeot {
878a85cb24fSFrançois Tigeot struct intel_engine_cs *engine;
879a85cb24fSFrançois Tigeot enum intel_engine_id id;
880a85cb24fSFrançois Tigeot
881a85cb24fSFrançois Tigeot for_each_engine(engine, i915, id)
882a85cb24fSFrançois Tigeot kfree(engine);
883a85cb24fSFrançois Tigeot }
884a85cb24fSFrançois Tigeot
i915_workqueues_cleanup(struct drm_i915_private * dev_priv)8851487f786SFrançois Tigeot static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
8861487f786SFrançois Tigeot {
8871487f786SFrançois Tigeot destroy_workqueue(dev_priv->hotplug.dp_wq);
8881487f786SFrançois Tigeot destroy_workqueue(dev_priv->wq);
8891487f786SFrançois Tigeot }
8901487f786SFrançois Tigeot
8911e12ee3bSFrançois Tigeot /*
8921e12ee3bSFrançois Tigeot * We don't keep the workarounds for pre-production hardware, so we expect our
8931e12ee3bSFrançois Tigeot * driver to fail on these machines in one way or another. A little warning on
8941e12ee3bSFrançois Tigeot * dmesg may help both the user and the bug triagers.
8951e12ee3bSFrançois Tigeot */
intel_detect_preproduction_hw(struct drm_i915_private * dev_priv)8961e12ee3bSFrançois Tigeot static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
8971e12ee3bSFrançois Tigeot {
898a85cb24fSFrançois Tigeot bool pre = false;
899a85cb24fSFrançois Tigeot
900a85cb24fSFrançois Tigeot pre |= IS_HSW_EARLY_SDV(dev_priv);
901a85cb24fSFrançois Tigeot pre |= IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0);
902a85cb24fSFrançois Tigeot pre |= IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST);
903a85cb24fSFrançois Tigeot
904a85cb24fSFrançois Tigeot if (pre) {
9051e12ee3bSFrançois Tigeot DRM_ERROR("This is a pre-production stepping. "
9061e12ee3bSFrançois Tigeot "It may not be fully functional.\n");
907a85cb24fSFrançois Tigeot add_taint(TAINT_MACHINE_CHECK, LOCKDEP_STILL_OK);
908a85cb24fSFrançois Tigeot }
9091e12ee3bSFrançois Tigeot }
9101e12ee3bSFrançois Tigeot
9111487f786SFrançois Tigeot /**
9121487f786SFrançois Tigeot * i915_driver_init_early - setup state not requiring device access
9131487f786SFrançois Tigeot * @dev_priv: device private
9141487f786SFrançois Tigeot *
9151487f786SFrançois Tigeot * Initialize everything that is a "SW-only" state, that is state not
9161487f786SFrançois Tigeot * requiring accessing the device or exposing the driver via kernel internal
9171487f786SFrançois Tigeot * or userspace interfaces. Example steps belonging here: lock initialization,
9181487f786SFrançois Tigeot * system memory allocation, setting up device specific attributes and
9191487f786SFrançois Tigeot * function hooks not requiring accessing the device.
9201487f786SFrançois Tigeot */
i915_driver_init_early(struct drm_i915_private * dev_priv,const struct pci_device_id * ent)9211487f786SFrançois Tigeot static int i915_driver_init_early(struct drm_i915_private *dev_priv,
9221487f786SFrançois Tigeot const struct pci_device_id *ent)
9231487f786SFrançois Tigeot {
9241487f786SFrançois Tigeot const struct intel_device_info *match_info =
9251487f786SFrançois Tigeot (struct intel_device_info *)ent->driver_data;
9261487f786SFrançois Tigeot struct intel_device_info *device_info;
9271487f786SFrançois Tigeot int ret = 0;
9281487f786SFrançois Tigeot
9291487f786SFrançois Tigeot if (i915_inject_load_failure())
9301487f786SFrançois Tigeot return -ENODEV;
9311487f786SFrançois Tigeot
9321487f786SFrançois Tigeot /* Setup the write-once "constant" device info */
933303bf270SFrançois Tigeot device_info = mkwrite_device_info(dev_priv);
9341487f786SFrançois Tigeot memcpy(device_info, match_info, sizeof(*device_info));
9351487f786SFrançois Tigeot device_info->device_id = dev_priv->drm.pdev->device;
9361487f786SFrançois Tigeot
937*3f2dd94aSFrançois Tigeot BUILD_BUG_ON(INTEL_MAX_PLATFORMS >
938*3f2dd94aSFrançois Tigeot sizeof(device_info->platform_mask) * BITS_PER_BYTE);
939*3f2dd94aSFrançois Tigeot device_info->platform_mask = BIT(device_info->platform);
940*3f2dd94aSFrançois Tigeot
9411487f786SFrançois Tigeot BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE);
9421487f786SFrançois Tigeot device_info->gen_mask = BIT(device_info->gen - 1);
9431487f786SFrançois Tigeot
94471f41f3eSFrançois Tigeot lockinit(&dev_priv->irq_lock, "userirq", 0, 0);
94571f41f3eSFrançois Tigeot lockinit(&dev_priv->gpu_error.lock, "915err", 0, 0);
9461487f786SFrançois Tigeot lockinit(&dev_priv->backlight_lock, "i915bl", 0, LK_CANRECURSE);
94771f41f3eSFrançois Tigeot lockinit(&dev_priv->uncore.lock, "915gt", 0, 0);
948a85cb24fSFrançois Tigeot
9499a49c39cSFrançois Tigeot lockinit(&dev_priv->mm.object_stat_lock, "i915osl", 0, 0);
9501487f786SFrançois Tigeot lockinit(&dev_priv->sb_lock, "i915sbl", 0, LK_CANRECURSE);
9511487f786SFrançois Tigeot lockinit(&dev_priv->modeset_restore_lock, "i915mrl", 0, LK_CANRECURSE);
9521487f786SFrançois Tigeot lockinit(&dev_priv->av_mutex, "i915am", 0, LK_CANRECURSE);
9531487f786SFrançois Tigeot lockinit(&dev_priv->wm.wm_mutex, "i915wm", 0, LK_CANRECURSE);
9541487f786SFrançois Tigeot lockinit(&dev_priv->pps_mutex, "i915pm", 0, LK_CANRECURSE);
9551487f786SFrançois Tigeot
956a85cb24fSFrançois Tigeot intel_uc_init_early(dev_priv);
9571e12ee3bSFrançois Tigeot i915_memcpy_init_early(dev_priv);
9581e12ee3bSFrançois Tigeot
9591487f786SFrançois Tigeot ret = i915_workqueues_init(dev_priv);
9601487f786SFrançois Tigeot if (ret < 0)
961a85cb24fSFrançois Tigeot goto err_engines;
9621487f786SFrançois Tigeot
9631487f786SFrançois Tigeot /* This must be called before any calls to HAS_PCH_* */
964a85cb24fSFrançois Tigeot intel_detect_pch(dev_priv);
9651487f786SFrançois Tigeot
966a85cb24fSFrançois Tigeot intel_pm_setup(dev_priv);
9671487f786SFrançois Tigeot intel_init_dpio(dev_priv);
9681487f786SFrançois Tigeot intel_power_domains_init(dev_priv);
9691487f786SFrançois Tigeot intel_irq_init(dev_priv);
9704be47400SFrançois Tigeot intel_hangcheck_init(dev_priv);
9711487f786SFrançois Tigeot intel_init_display_hooks(dev_priv);
9721487f786SFrançois Tigeot intel_init_clock_gating_hooks(dev_priv);
9731487f786SFrançois Tigeot intel_init_audio_hooks(dev_priv);
974a85cb24fSFrançois Tigeot ret = i915_gem_load_init(dev_priv);
9754be47400SFrançois Tigeot if (ret < 0)
976*3f2dd94aSFrançois Tigeot goto err_irq;
9771487f786SFrançois Tigeot
9781e12ee3bSFrançois Tigeot intel_display_crc_init(dev_priv);
9791487f786SFrançois Tigeot
980303bf270SFrançois Tigeot intel_device_info_dump(dev_priv);
9811487f786SFrançois Tigeot
9821e12ee3bSFrançois Tigeot intel_detect_preproduction_hw(dev_priv);
9831487f786SFrançois Tigeot
984a85cb24fSFrançois Tigeot i915_perf_init(dev_priv);
985a85cb24fSFrançois Tigeot
9861487f786SFrançois Tigeot return 0;
9871487f786SFrançois Tigeot
988*3f2dd94aSFrançois Tigeot err_irq:
989*3f2dd94aSFrançois Tigeot intel_irq_fini(dev_priv);
9901487f786SFrançois Tigeot i915_workqueues_cleanup(dev_priv);
991a85cb24fSFrançois Tigeot err_engines:
992a85cb24fSFrançois Tigeot i915_engines_cleanup(dev_priv);
9931487f786SFrançois Tigeot return ret;
9941487f786SFrançois Tigeot }
9951487f786SFrançois Tigeot
9961487f786SFrançois Tigeot /**
9971487f786SFrançois Tigeot * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early()
9981487f786SFrançois Tigeot * @dev_priv: device private
9991487f786SFrançois Tigeot */
i915_driver_cleanup_early(struct drm_i915_private * dev_priv)10001487f786SFrançois Tigeot static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
10011487f786SFrançois Tigeot {
1002a85cb24fSFrançois Tigeot i915_perf_fini(dev_priv);
1003a85cb24fSFrançois Tigeot i915_gem_load_cleanup(dev_priv);
1004*3f2dd94aSFrançois Tigeot intel_irq_fini(dev_priv);
10051487f786SFrançois Tigeot i915_workqueues_cleanup(dev_priv);
1006a85cb24fSFrançois Tigeot i915_engines_cleanup(dev_priv);
10071487f786SFrançois Tigeot }
10081487f786SFrançois Tigeot
i915_mmio_setup(struct drm_i915_private * dev_priv)1009a85cb24fSFrançois Tigeot static int i915_mmio_setup(struct drm_i915_private *dev_priv)
10101487f786SFrançois Tigeot {
10111e12ee3bSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
10121487f786SFrançois Tigeot int mmio_bar;
10131487f786SFrançois Tigeot int mmio_size;
10141487f786SFrançois Tigeot
10151e12ee3bSFrançois Tigeot mmio_bar = IS_GEN2(dev_priv) ? 1 : 0;
10161487f786SFrançois Tigeot /*
10171487f786SFrançois Tigeot * Before gen4, the registers and the GTT are behind different BARs.
10181487f786SFrançois Tigeot * However, from gen4 onwards, the registers and the GTT are shared
10191487f786SFrançois Tigeot * in the same BAR, so we want to restrict this ioremap from
10201487f786SFrançois Tigeot * clobbering the GTT which we want ioremap_wc instead. Fortunately,
10211487f786SFrançois Tigeot * the register BAR remains the same size for all the earlier
10221487f786SFrançois Tigeot * generations up to Ironlake.
10231487f786SFrançois Tigeot */
10244be47400SFrançois Tigeot if (INTEL_GEN(dev_priv) < 5)
10251487f786SFrançois Tigeot mmio_size = 512 * 1024;
10261487f786SFrançois Tigeot else
10271487f786SFrançois Tigeot mmio_size = 2 * 1024 * 1024;
10281e12ee3bSFrançois Tigeot dev_priv->regs = pci_iomap(pdev, mmio_bar, mmio_size);
10291487f786SFrançois Tigeot if (dev_priv->regs == NULL) {
10301487f786SFrançois Tigeot DRM_ERROR("failed to map registers\n");
10311487f786SFrançois Tigeot
10321487f786SFrançois Tigeot return -EIO;
10331487f786SFrançois Tigeot }
10341487f786SFrançois Tigeot
10351487f786SFrançois Tigeot /* Try to make sure MCHBAR is enabled before poking at it */
1036a85cb24fSFrançois Tigeot intel_setup_mchbar(dev_priv);
10371487f786SFrançois Tigeot
10381487f786SFrançois Tigeot return 0;
10391487f786SFrançois Tigeot }
10401487f786SFrançois Tigeot
i915_mmio_cleanup(struct drm_i915_private * dev_priv)1041a85cb24fSFrançois Tigeot static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)
10421487f786SFrançois Tigeot {
10431487f786SFrançois Tigeot #if 0
1044a85cb24fSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
10451487f786SFrançois Tigeot #endif
10461487f786SFrançois Tigeot
1047a85cb24fSFrançois Tigeot intel_teardown_mchbar(dev_priv);
10481487f786SFrançois Tigeot #if 0
10491e12ee3bSFrançois Tigeot pci_iounmap(pdev, dev_priv->regs);
10501487f786SFrançois Tigeot #endif
10511487f786SFrançois Tigeot }
10521487f786SFrançois Tigeot
10531487f786SFrançois Tigeot /**
10541487f786SFrançois Tigeot * i915_driver_init_mmio - setup device MMIO
10551487f786SFrançois Tigeot * @dev_priv: device private
10561487f786SFrançois Tigeot *
10571487f786SFrançois Tigeot * Setup minimal device state necessary for MMIO accesses later in the
10581487f786SFrançois Tigeot * initialization sequence. The setup here should avoid any other device-wide
10591487f786SFrançois Tigeot * side effects or exposing the driver via kernel internal or user space
10601487f786SFrançois Tigeot * interfaces.
10611487f786SFrançois Tigeot */
i915_driver_init_mmio(struct drm_i915_private * dev_priv)10621487f786SFrançois Tigeot static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
10631487f786SFrançois Tigeot {
10641487f786SFrançois Tigeot int ret;
10651487f786SFrançois Tigeot
10661487f786SFrançois Tigeot if (i915_inject_load_failure())
10671487f786SFrançois Tigeot return -ENODEV;
10681487f786SFrançois Tigeot
1069a85cb24fSFrançois Tigeot if (i915_get_bridge_dev(dev_priv))
10701487f786SFrançois Tigeot return -EIO;
10711487f786SFrançois Tigeot
1072a85cb24fSFrançois Tigeot ret = i915_mmio_setup(dev_priv);
10731487f786SFrançois Tigeot if (ret < 0)
1074*3f2dd94aSFrançois Tigeot goto err_bridge;
10751487f786SFrançois Tigeot
10761487f786SFrançois Tigeot intel_uncore_init(dev_priv);
1077*3f2dd94aSFrançois Tigeot
1078*3f2dd94aSFrançois Tigeot intel_uc_init_mmio(dev_priv);
1079*3f2dd94aSFrançois Tigeot
1080*3f2dd94aSFrançois Tigeot ret = intel_engines_init_mmio(dev_priv);
1081*3f2dd94aSFrançois Tigeot if (ret)
1082*3f2dd94aSFrançois Tigeot goto err_uncore;
1083*3f2dd94aSFrançois Tigeot
1084a85cb24fSFrançois Tigeot i915_gem_init_mmio(dev_priv);
10851487f786SFrançois Tigeot
10861487f786SFrançois Tigeot return 0;
10871487f786SFrançois Tigeot
1088*3f2dd94aSFrançois Tigeot err_uncore:
1089*3f2dd94aSFrançois Tigeot intel_uncore_fini(dev_priv);
1090*3f2dd94aSFrançois Tigeot err_bridge:
10911487f786SFrançois Tigeot pci_dev_put(dev_priv->bridge_dev);
10921487f786SFrançois Tigeot
10931487f786SFrançois Tigeot return ret;
10941487f786SFrançois Tigeot }
10951487f786SFrançois Tigeot
10961487f786SFrançois Tigeot /**
10971487f786SFrançois Tigeot * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio()
10981487f786SFrançois Tigeot * @dev_priv: device private
10991487f786SFrançois Tigeot */
i915_driver_cleanup_mmio(struct drm_i915_private * dev_priv)11001487f786SFrançois Tigeot static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
11011487f786SFrançois Tigeot {
11021487f786SFrançois Tigeot intel_uncore_fini(dev_priv);
1103a85cb24fSFrançois Tigeot i915_mmio_cleanup(dev_priv);
11041487f786SFrançois Tigeot pci_dev_put(dev_priv->bridge_dev);
11051487f786SFrançois Tigeot }
11061487f786SFrançois Tigeot
intel_sanitize_options(struct drm_i915_private * dev_priv)1107303bf270SFrançois Tigeot static void intel_sanitize_options(struct drm_i915_private *dev_priv)
1108303bf270SFrançois Tigeot {
1109*3f2dd94aSFrançois Tigeot i915_modparams.enable_execlists =
1110303bf270SFrançois Tigeot intel_sanitize_enable_execlists(dev_priv,
1111*3f2dd94aSFrançois Tigeot i915_modparams.enable_execlists);
1112303bf270SFrançois Tigeot
1113303bf270SFrançois Tigeot /*
1114303bf270SFrançois Tigeot * i915.enable_ppgtt is read-only, so do an early pass to validate the
1115303bf270SFrançois Tigeot * user's requested state against the hardware/driver capabilities. We
1116303bf270SFrançois Tigeot * do this now so that we can print out any log messages once rather
1117303bf270SFrançois Tigeot * than every time we check intel_enable_ppgtt().
1118303bf270SFrançois Tigeot */
1119*3f2dd94aSFrançois Tigeot i915_modparams.enable_ppgtt =
1120*3f2dd94aSFrançois Tigeot intel_sanitize_enable_ppgtt(dev_priv,
1121*3f2dd94aSFrançois Tigeot i915_modparams.enable_ppgtt);
1122*3f2dd94aSFrançois Tigeot DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt);
112387df8fc6SFrançois Tigeot
1124*3f2dd94aSFrançois Tigeot i915_modparams.semaphores =
1125*3f2dd94aSFrançois Tigeot intel_sanitize_semaphores(dev_priv, i915_modparams.semaphores);
1126*3f2dd94aSFrançois Tigeot DRM_DEBUG_DRIVER("use GPU semaphores? %s\n",
1127*3f2dd94aSFrançois Tigeot yesno(i915_modparams.semaphores));
1128a85cb24fSFrançois Tigeot
1129a85cb24fSFrançois Tigeot intel_uc_sanitize_options(dev_priv);
1130*3f2dd94aSFrançois Tigeot
1131*3f2dd94aSFrançois Tigeot intel_gvt_sanitize_options(dev_priv);
1132303bf270SFrançois Tigeot }
1133303bf270SFrançois Tigeot
11341487f786SFrançois Tigeot /**
11351487f786SFrançois Tigeot * i915_driver_init_hw - setup state requiring device access
11361487f786SFrançois Tigeot * @dev_priv: device private
11371487f786SFrançois Tigeot *
11381487f786SFrançois Tigeot * Setup state that requires accessing the device, but doesn't require
11391487f786SFrançois Tigeot * exposing the driver via kernel internal or userspace interfaces.
11401487f786SFrançois Tigeot */
i915_driver_init_hw(struct drm_i915_private * dev_priv)11411487f786SFrançois Tigeot static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
11421487f786SFrançois Tigeot {
11431e12ee3bSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
11441487f786SFrançois Tigeot int ret;
11451487f786SFrançois Tigeot
11461487f786SFrançois Tigeot if (i915_inject_load_failure())
11471487f786SFrançois Tigeot return -ENODEV;
11481487f786SFrançois Tigeot
1149303bf270SFrançois Tigeot intel_device_info_runtime_init(dev_priv);
1150303bf270SFrançois Tigeot
1151303bf270SFrançois Tigeot intel_sanitize_options(dev_priv);
11521487f786SFrançois Tigeot
115371f41f3eSFrançois Tigeot ret = i915_ggtt_probe_hw(dev_priv);
11541487f786SFrançois Tigeot if (ret)
11551487f786SFrançois Tigeot return ret;
11561487f786SFrançois Tigeot
11571487f786SFrançois Tigeot /* WARNING: Apparently we must kick fbdev drivers before vgacon,
11581487f786SFrançois Tigeot * otherwise the vga fbdev driver falls over. */
11591487f786SFrançois Tigeot ret = i915_kick_out_firmware_fb(dev_priv);
11601487f786SFrançois Tigeot if (ret) {
11611487f786SFrançois Tigeot DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
11621487f786SFrançois Tigeot goto out_ggtt;
11631487f786SFrançois Tigeot }
11641487f786SFrançois Tigeot
11651487f786SFrançois Tigeot ret = i915_kick_out_vgacon(dev_priv);
11661487f786SFrançois Tigeot if (ret) {
11671487f786SFrançois Tigeot DRM_ERROR("failed to remove conflicting VGA console\n");
11681487f786SFrançois Tigeot goto out_ggtt;
11691487f786SFrançois Tigeot }
11701487f786SFrançois Tigeot
117171f41f3eSFrançois Tigeot ret = i915_ggtt_init_hw(dev_priv);
117271f41f3eSFrançois Tigeot if (ret)
117371f41f3eSFrançois Tigeot return ret;
117471f41f3eSFrançois Tigeot
117571f41f3eSFrançois Tigeot ret = i915_ggtt_enable_hw(dev_priv);
117671f41f3eSFrançois Tigeot if (ret) {
117771f41f3eSFrançois Tigeot DRM_ERROR("failed to enable GGTT\n");
117871f41f3eSFrançois Tigeot goto out_ggtt;
117971f41f3eSFrançois Tigeot }
118071f41f3eSFrançois Tigeot
11811e12ee3bSFrançois Tigeot pci_set_master(pdev);
11821487f786SFrançois Tigeot
118371f41f3eSFrançois Tigeot #if 0
11841487f786SFrançois Tigeot /* overlay on gen2 is broken and can't address above 1G */
11851e12ee3bSFrançois Tigeot if (IS_GEN2(dev_priv)) {
11861e12ee3bSFrançois Tigeot ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(30));
11871487f786SFrançois Tigeot if (ret) {
11881487f786SFrançois Tigeot DRM_ERROR("failed to set DMA mask\n");
11891487f786SFrançois Tigeot
11901487f786SFrançois Tigeot goto out_ggtt;
11911487f786SFrançois Tigeot }
11921487f786SFrançois Tigeot }
11931487f786SFrançois Tigeot
11941487f786SFrançois Tigeot /* 965GM sometimes incorrectly writes to hardware status page (HWS)
11951487f786SFrançois Tigeot * using 32bit addressing, overwriting memory if HWS is located
11961487f786SFrançois Tigeot * above 4GB.
11971487f786SFrançois Tigeot *
11981487f786SFrançois Tigeot * The documentation also mentions an issue with undefined
11991487f786SFrançois Tigeot * behaviour if any general state is accessed within a page above 4GB,
12001487f786SFrançois Tigeot * which also needs to be handled carefully.
12011487f786SFrançois Tigeot */
1202a85cb24fSFrançois Tigeot if (IS_I965G(dev_priv) || IS_I965GM(dev_priv)) {
12031e12ee3bSFrançois Tigeot ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
12041487f786SFrançois Tigeot
12051487f786SFrançois Tigeot if (ret) {
12061487f786SFrançois Tigeot DRM_ERROR("failed to set DMA mask\n");
12071487f786SFrançois Tigeot
12081487f786SFrançois Tigeot goto out_ggtt;
12091487f786SFrançois Tigeot }
12101487f786SFrançois Tigeot }
12111487f786SFrançois Tigeot #endif
12121487f786SFrançois Tigeot
12131487f786SFrançois Tigeot pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
12141487f786SFrançois Tigeot PM_QOS_DEFAULT_VALUE);
12151487f786SFrançois Tigeot
12161487f786SFrançois Tigeot intel_uncore_sanitize(dev_priv);
12171487f786SFrançois Tigeot
12181487f786SFrançois Tigeot intel_opregion_setup(dev_priv);
12191487f786SFrançois Tigeot
12201487f786SFrançois Tigeot i915_gem_load_init_fences(dev_priv);
12211487f786SFrançois Tigeot
12221487f786SFrançois Tigeot /* On the 945G/GM, the chipset reports the MSI capability on the
12231487f786SFrançois Tigeot * integrated graphics even though the support isn't actually there
12241487f786SFrançois Tigeot * according to the published specs. It doesn't appear to function
12251487f786SFrançois Tigeot * correctly in testing on 945G.
12261487f786SFrançois Tigeot * This may be a side effect of MSI having been made available for PEG
12271487f786SFrançois Tigeot * and the registers being closely associated.
12281487f786SFrançois Tigeot *
12291487f786SFrançois Tigeot * According to chipset errata, on the 965GM, MSI interrupts may
1230a85cb24fSFrançois Tigeot * be lost or delayed, and was defeatured. MSI interrupts seem to
1231a85cb24fSFrançois Tigeot * get lost on g4x as well, and interrupt delivery seems to stay
1232a85cb24fSFrançois Tigeot * properly dead afterwards. So we'll just disable them for all
1233a85cb24fSFrançois Tigeot * pre-gen5 chipsets.
12341487f786SFrançois Tigeot */
12351487f786SFrançois Tigeot #if 0
1236*3f2dd94aSFrançois Tigeot if (INTEL_GEN(dev_priv) >= 5) {
12371e12ee3bSFrançois Tigeot if (pci_enable_msi(pdev) < 0)
12381487f786SFrançois Tigeot DRM_DEBUG_DRIVER("can't enable MSI");
1239a85cb24fSFrançois Tigeot }
1240*3f2dd94aSFrançois Tigeot #endif
12411487f786SFrançois Tigeot
1242a85cb24fSFrançois Tigeot ret = intel_gvt_init(dev_priv);
1243a85cb24fSFrançois Tigeot if (ret)
1244a85cb24fSFrançois Tigeot goto out_ggtt;
1245a85cb24fSFrançois Tigeot
1246*3f2dd94aSFrançois Tigeot return 0;
1247*3f2dd94aSFrançois Tigeot
12481487f786SFrançois Tigeot out_ggtt:
124971f41f3eSFrançois Tigeot i915_ggtt_cleanup_hw(dev_priv);
12501487f786SFrançois Tigeot
12511487f786SFrançois Tigeot return ret;
12521487f786SFrançois Tigeot }
12531487f786SFrançois Tigeot
12541487f786SFrançois Tigeot /**
12551487f786SFrançois Tigeot * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw()
12561487f786SFrançois Tigeot * @dev_priv: device private
12571487f786SFrançois Tigeot */
i915_driver_cleanup_hw(struct drm_i915_private * dev_priv)12581487f786SFrançois Tigeot static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
12591487f786SFrançois Tigeot {
12601e12ee3bSFrançois Tigeot #if 0
1261a85cb24fSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
1262a85cb24fSFrançois Tigeot
1263a85cb24fSFrançois Tigeot if (pdev->msi_enabled)
1264a85cb24fSFrançois Tigeot pci_disable_msi(pdev);
12651487f786SFrançois Tigeot #endif
12661487f786SFrançois Tigeot
12671487f786SFrançois Tigeot pm_qos_remove_request(&dev_priv->pm_qos);
126871f41f3eSFrançois Tigeot i915_ggtt_cleanup_hw(dev_priv);
12691487f786SFrançois Tigeot }
12701487f786SFrançois Tigeot
12711487f786SFrançois Tigeot /**
12721487f786SFrançois Tigeot * i915_driver_register - register the driver with the rest of the system
12731487f786SFrançois Tigeot * @dev_priv: device private
12741487f786SFrançois Tigeot *
12751487f786SFrançois Tigeot * Perform any steps necessary to make the driver available via kernel
12761487f786SFrançois Tigeot * internal or userspace interfaces.
12771487f786SFrançois Tigeot */
i915_driver_register(struct drm_i915_private * dev_priv)12781487f786SFrançois Tigeot static void i915_driver_register(struct drm_i915_private *dev_priv)
12791487f786SFrançois Tigeot {
1280303bf270SFrançois Tigeot struct drm_device *dev = &dev_priv->drm;
12811487f786SFrançois Tigeot
12821487f786SFrançois Tigeot i915_gem_shrinker_init(dev_priv);
12831487f786SFrançois Tigeot
12841487f786SFrançois Tigeot /*
12851487f786SFrançois Tigeot * Notify a valid surface after modesetting,
12861487f786SFrançois Tigeot * when running inside a VM.
12871487f786SFrançois Tigeot */
12881487f786SFrançois Tigeot if (intel_vgpu_active(dev_priv))
12891487f786SFrançois Tigeot I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
12901487f786SFrançois Tigeot
12911487f786SFrançois Tigeot /* Reveal our presence to userspace */
12921487f786SFrançois Tigeot if (drm_dev_register(dev, 0) == 0) {
12931487f786SFrançois Tigeot i915_debugfs_register(dev_priv);
1294a85cb24fSFrançois Tigeot i915_guc_log_register(dev_priv);
12951e12ee3bSFrançois Tigeot i915_setup_sysfs(dev_priv);
1296a85cb24fSFrançois Tigeot
1297a85cb24fSFrançois Tigeot /* Depends on sysfs having been initialized */
1298a85cb24fSFrançois Tigeot i915_perf_register(dev_priv);
12991487f786SFrançois Tigeot } else
13001487f786SFrançois Tigeot DRM_ERROR("Failed to register driver for userspace access!\n");
13011487f786SFrançois Tigeot
13021487f786SFrançois Tigeot if (INTEL_INFO(dev_priv)->num_pipes) {
13031487f786SFrançois Tigeot /* Must be done after probing outputs */
13041487f786SFrançois Tigeot intel_opregion_register(dev_priv);
13051487f786SFrançois Tigeot acpi_video_register();
13061487f786SFrançois Tigeot }
13071487f786SFrançois Tigeot
13081487f786SFrançois Tigeot if (IS_GEN5(dev_priv))
13091487f786SFrançois Tigeot intel_gpu_ips_init(dev_priv);
13101487f786SFrançois Tigeot
1311a85cb24fSFrançois Tigeot intel_audio_init(dev_priv);
13121487f786SFrançois Tigeot
13131487f786SFrançois Tigeot /*
13141487f786SFrançois Tigeot * Some ports require correctly set-up hpd registers for detection to
13151487f786SFrançois Tigeot * work properly (leading to ghost connected connector status), e.g. VGA
13161487f786SFrançois Tigeot * on gm45. Hence we can only set up the initial fbdev config after hpd
13171487f786SFrançois Tigeot * irqs are fully enabled. We do it last so that the async config
13181487f786SFrançois Tigeot * cannot run before the connectors are registered.
13191487f786SFrançois Tigeot */
13201487f786SFrançois Tigeot intel_fbdev_initial_config_async(dev);
13211487f786SFrançois Tigeot }
13221487f786SFrançois Tigeot
13231487f786SFrançois Tigeot /**
13241487f786SFrançois Tigeot * i915_driver_unregister - cleanup the registration done in i915_driver_regiser()
13251487f786SFrançois Tigeot * @dev_priv: device private
13261487f786SFrançois Tigeot */
i915_driver_unregister(struct drm_i915_private * dev_priv)13271487f786SFrançois Tigeot static void i915_driver_unregister(struct drm_i915_private *dev_priv)
13281487f786SFrançois Tigeot {
1329*3f2dd94aSFrançois Tigeot intel_fbdev_unregister(dev_priv);
1330a85cb24fSFrançois Tigeot intel_audio_deinit(dev_priv);
13311487f786SFrançois Tigeot
13321487f786SFrançois Tigeot intel_gpu_ips_teardown();
13331487f786SFrançois Tigeot acpi_video_unregister();
13341487f786SFrançois Tigeot intel_opregion_unregister(dev_priv);
13351487f786SFrançois Tigeot
1336a85cb24fSFrançois Tigeot i915_perf_unregister(dev_priv);
1337a85cb24fSFrançois Tigeot
13381e12ee3bSFrançois Tigeot i915_teardown_sysfs(dev_priv);
1339a85cb24fSFrançois Tigeot i915_guc_log_unregister(dev_priv);
1340303bf270SFrançois Tigeot drm_dev_unregister(&dev_priv->drm);
13411487f786SFrançois Tigeot
13421487f786SFrançois Tigeot i915_gem_shrinker_cleanup(dev_priv);
13431487f786SFrançois Tigeot }
13441487f786SFrançois Tigeot
13451487f786SFrançois Tigeot /**
13461487f786SFrançois Tigeot * i915_driver_load - setup chip and create an initial config
13474be47400SFrançois Tigeot * @pdev: PCI device
13484be47400SFrançois Tigeot * @ent: matching PCI ID entry
13491487f786SFrançois Tigeot *
13501487f786SFrançois Tigeot * The driver load routine has to do several things:
13511487f786SFrançois Tigeot * - drive output discovery via intel_modeset_init()
13521487f786SFrançois Tigeot * - initialize the memory manager
13531487f786SFrançois Tigeot * - allocate initial config memory
13541487f786SFrançois Tigeot * - setup the DRM framebuffer with the allocated memory
13551487f786SFrançois Tigeot */
i915_driver_load(struct pci_dev * pdev,const struct pci_device_id * ent)13561487f786SFrançois Tigeot int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
13571487f786SFrançois Tigeot {
1358a85cb24fSFrançois Tigeot const struct intel_device_info *match_info =
1359a85cb24fSFrançois Tigeot (struct intel_device_info *)ent->driver_data;
13601487f786SFrançois Tigeot struct drm_i915_private *dev_priv;
13611487f786SFrançois Tigeot int ret;
13621487f786SFrançois Tigeot
1363*3f2dd94aSFrançois Tigeot /* Enable nuclear pageflip on ILK+ */
1364*3f2dd94aSFrançois Tigeot if (!i915_modparams.nuclear_pageflip && match_info->gen < 5)
1365a85cb24fSFrançois Tigeot driver.driver_features &= ~DRIVER_ATOMIC;
13661487f786SFrançois Tigeot
13671487f786SFrançois Tigeot ret = -ENOMEM;
13681487f786SFrançois Tigeot dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
13691487f786SFrançois Tigeot if (dev_priv)
13701487f786SFrançois Tigeot ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev);
13711487f786SFrançois Tigeot if (ret) {
1372a85cb24fSFrançois Tigeot DRM_DEV_ERROR(&pdev->dev, "allocation failed\n");
1373a85cb24fSFrançois Tigeot goto out_free;
13741487f786SFrançois Tigeot }
13751487f786SFrançois Tigeot
13761487f786SFrançois Tigeot dev_priv->drm.pdev = pdev;
13771487f786SFrançois Tigeot dev_priv->drm.dev_private = dev_priv;
13781487f786SFrançois Tigeot
13791487f786SFrançois Tigeot #if 0
13801487f786SFrançois Tigeot ret = pci_enable_device(pdev);
13811487f786SFrançois Tigeot if (ret)
1382a85cb24fSFrançois Tigeot goto out_fini;
13831487f786SFrançois Tigeot #endif
13841487f786SFrançois Tigeot
13851487f786SFrançois Tigeot pci_set_drvdata(pdev, &dev_priv->drm);
1386a85cb24fSFrançois Tigeot /*
1387a85cb24fSFrançois Tigeot * Disable the system suspend direct complete optimization, which can
1388a85cb24fSFrançois Tigeot * leave the device suspended skipping the driver's suspend handlers
1389a85cb24fSFrançois Tigeot * if the device was already runtime suspended. This is needed due to
1390a85cb24fSFrançois Tigeot * the difference in our runtime and system suspend sequence and
1391a85cb24fSFrançois Tigeot * becaue the HDA driver may require us to enable the audio power
1392a85cb24fSFrançois Tigeot * domain during system suspend.
1393a85cb24fSFrançois Tigeot */
1394*3f2dd94aSFrançois Tigeot dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NEVER_SKIP);
13951487f786SFrançois Tigeot
13961487f786SFrançois Tigeot ret = i915_driver_init_early(dev_priv, ent);
13971487f786SFrançois Tigeot if (ret < 0)
13981487f786SFrançois Tigeot goto out_pci_disable;
13991487f786SFrançois Tigeot
14001487f786SFrançois Tigeot intel_runtime_pm_get(dev_priv);
14011487f786SFrançois Tigeot
14021487f786SFrançois Tigeot ret = i915_driver_init_mmio(dev_priv);
14031487f786SFrançois Tigeot if (ret < 0)
14041487f786SFrançois Tigeot goto out_runtime_pm_put;
14051487f786SFrançois Tigeot
14061487f786SFrançois Tigeot ret = i915_driver_init_hw(dev_priv);
14071487f786SFrançois Tigeot if (ret < 0)
14081487f786SFrançois Tigeot goto out_cleanup_mmio;
14091487f786SFrançois Tigeot
14101487f786SFrançois Tigeot /*
14111487f786SFrançois Tigeot * TODO: move the vblank init and parts of modeset init steps into one
14121487f786SFrançois Tigeot * of the i915_driver_init_/i915_driver_register functions according
14131487f786SFrançois Tigeot * to the role/effect of the given init step.
14141487f786SFrançois Tigeot */
14151487f786SFrançois Tigeot if (INTEL_INFO(dev_priv)->num_pipes) {
1416303bf270SFrançois Tigeot ret = drm_vblank_init(&dev_priv->drm,
14171487f786SFrançois Tigeot INTEL_INFO(dev_priv)->num_pipes);
14181487f786SFrançois Tigeot if (ret)
14191487f786SFrançois Tigeot goto out_cleanup_hw;
14201487f786SFrançois Tigeot }
14211487f786SFrançois Tigeot
1422303bf270SFrançois Tigeot ret = i915_load_modeset_init(&dev_priv->drm);
14231487f786SFrançois Tigeot if (ret < 0)
1424*3f2dd94aSFrançois Tigeot goto out_cleanup_hw;
14251487f786SFrançois Tigeot
14261487f786SFrançois Tigeot i915_driver_register(dev_priv);
14271487f786SFrançois Tigeot
14281487f786SFrançois Tigeot intel_runtime_pm_enable(dev_priv);
14291487f786SFrançois Tigeot
1430*3f2dd94aSFrançois Tigeot intel_init_ipc(dev_priv);
1431a85cb24fSFrançois Tigeot
14321e12ee3bSFrançois Tigeot if (IS_ENABLED(CONFIG_DRM_I915_DEBUG))
14331e12ee3bSFrançois Tigeot DRM_INFO("DRM_I915_DEBUG enabled\n");
14341e12ee3bSFrançois Tigeot if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
14351e12ee3bSFrançois Tigeot DRM_INFO("DRM_I915_DEBUG_GEM enabled\n");
14361e12ee3bSFrançois Tigeot
14371e12ee3bSFrançois Tigeot intel_runtime_pm_put(dev_priv);
1438bf017597SFrançois Tigeot
14391487f786SFrançois Tigeot return 0;
14401487f786SFrançois Tigeot
14411487f786SFrançois Tigeot out_cleanup_hw:
14421487f786SFrançois Tigeot i915_driver_cleanup_hw(dev_priv);
14431487f786SFrançois Tigeot out_cleanup_mmio:
14441487f786SFrançois Tigeot i915_driver_cleanup_mmio(dev_priv);
14451487f786SFrançois Tigeot out_runtime_pm_put:
14461487f786SFrançois Tigeot intel_runtime_pm_put(dev_priv);
14471487f786SFrançois Tigeot i915_driver_cleanup_early(dev_priv);
14481487f786SFrançois Tigeot out_pci_disable:
14491487f786SFrançois Tigeot #if 0
14501487f786SFrançois Tigeot pci_disable_device(pdev);
1451a85cb24fSFrançois Tigeot out_fini:
14521487f786SFrançois Tigeot #endif
14531487f786SFrançois Tigeot i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
1454a85cb24fSFrançois Tigeot drm_dev_fini(&dev_priv->drm);
1455a85cb24fSFrançois Tigeot out_free:
1456a85cb24fSFrançois Tigeot kfree(dev_priv);
14571487f786SFrançois Tigeot return ret;
14581487f786SFrançois Tigeot }
14591487f786SFrançois Tigeot
i915_driver_unload(struct drm_device * dev)14601487f786SFrançois Tigeot void i915_driver_unload(struct drm_device *dev)
14611487f786SFrançois Tigeot {
1462303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
14631487f786SFrançois Tigeot
1464*3f2dd94aSFrançois Tigeot i915_driver_unregister(dev_priv);
14651487f786SFrançois Tigeot
1466a85cb24fSFrançois Tigeot if (i915_gem_suspend(dev_priv))
14671487f786SFrançois Tigeot DRM_ERROR("failed to idle hardware; continuing to unload!\n");
14681487f786SFrançois Tigeot
14691487f786SFrançois Tigeot intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
14701487f786SFrançois Tigeot
1471*3f2dd94aSFrançois Tigeot drm_atomic_helper_shutdown(dev);
1472a85cb24fSFrançois Tigeot
1473a85cb24fSFrançois Tigeot intel_gvt_cleanup(dev_priv);
1474a85cb24fSFrançois Tigeot
14751487f786SFrançois Tigeot intel_modeset_cleanup(dev);
14761487f786SFrançois Tigeot
14771487f786SFrançois Tigeot /*
14781487f786SFrançois Tigeot * free the memory space allocated for the child device
14791487f786SFrançois Tigeot * config parsed from VBT
14801487f786SFrançois Tigeot */
14811487f786SFrançois Tigeot if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
14821487f786SFrançois Tigeot kfree(dev_priv->vbt.child_dev);
14831487f786SFrançois Tigeot dev_priv->vbt.child_dev = NULL;
14841487f786SFrançois Tigeot dev_priv->vbt.child_dev_num = 0;
14851487f786SFrançois Tigeot }
14861487f786SFrançois Tigeot kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
14871487f786SFrançois Tigeot dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
14881487f786SFrançois Tigeot kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
14891487f786SFrançois Tigeot dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
14901487f786SFrançois Tigeot
14911487f786SFrançois Tigeot #if 0
1492a85cb24fSFrançois Tigeot vga_switcheroo_unregister_client(pdev);
1493a85cb24fSFrançois Tigeot vga_client_register(pdev, NULL, NULL, NULL);
14941487f786SFrançois Tigeot #endif
14951487f786SFrançois Tigeot
14961487f786SFrançois Tigeot intel_csr_ucode_fini(dev_priv);
14971487f786SFrançois Tigeot
14981487f786SFrançois Tigeot /* Free error state after interrupts are fully disabled. */
14991487f786SFrançois Tigeot cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
1500a85cb24fSFrançois Tigeot i915_reset_error_state(dev_priv);
15011487f786SFrançois Tigeot
15024be47400SFrançois Tigeot i915_gem_fini(dev_priv);
1503a85cb24fSFrançois Tigeot intel_uc_fini_fw(dev_priv);
15041487f786SFrançois Tigeot intel_fbc_cleanup_cfb(dev_priv);
15051487f786SFrançois Tigeot
15061487f786SFrançois Tigeot intel_power_domains_fini(dev_priv);
15071487f786SFrançois Tigeot
15081487f786SFrançois Tigeot i915_driver_cleanup_hw(dev_priv);
15091487f786SFrançois Tigeot i915_driver_cleanup_mmio(dev_priv);
15101487f786SFrançois Tigeot
15111487f786SFrançois Tigeot intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
1512a85cb24fSFrançois Tigeot }
1513a85cb24fSFrançois Tigeot
i915_driver_release(struct drm_device * dev)1514a85cb24fSFrançois Tigeot static void i915_driver_release(struct drm_device *dev)
1515a85cb24fSFrançois Tigeot {
1516a85cb24fSFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
15171487f786SFrançois Tigeot
15181487f786SFrançois Tigeot i915_driver_cleanup_early(dev_priv);
1519a85cb24fSFrançois Tigeot drm_dev_fini(&dev_priv->drm);
1520a85cb24fSFrançois Tigeot
1521a85cb24fSFrançois Tigeot kfree(dev_priv);
15221487f786SFrançois Tigeot }
15231487f786SFrançois Tigeot
i915_driver_open(struct drm_device * dev,struct drm_file * file)15241487f786SFrançois Tigeot static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
15251487f786SFrançois Tigeot {
1526*3f2dd94aSFrançois Tigeot struct drm_i915_private *i915 = to_i915(dev);
15271487f786SFrançois Tigeot int ret;
15281487f786SFrançois Tigeot
1529*3f2dd94aSFrançois Tigeot ret = i915_gem_open(i915, file);
15301487f786SFrançois Tigeot if (ret)
15311487f786SFrançois Tigeot return ret;
15321487f786SFrançois Tigeot
15331487f786SFrançois Tigeot return 0;
15341487f786SFrançois Tigeot }
15351487f786SFrançois Tigeot
15361487f786SFrançois Tigeot /**
15371487f786SFrançois Tigeot * i915_driver_lastclose - clean up after all DRM clients have exited
15381487f786SFrançois Tigeot * @dev: DRM device
15391487f786SFrançois Tigeot *
15401487f786SFrançois Tigeot * Take care of cleaning up after all DRM clients have exited. In the
15411487f786SFrançois Tigeot * mode setting case, we want to restore the kernel's initial mode (just
15421487f786SFrançois Tigeot * in case the last client left us in a bad state).
15431487f786SFrançois Tigeot *
15441487f786SFrançois Tigeot * Additionally, in the non-mode setting case, we'll tear down the GTT
15451487f786SFrançois Tigeot * and DMA structures, since the kernel won't be using them, and clea
15461487f786SFrançois Tigeot * up any GEM state.
15471487f786SFrançois Tigeot */
i915_driver_lastclose(struct drm_device * dev)15481487f786SFrançois Tigeot static void i915_driver_lastclose(struct drm_device *dev)
15491487f786SFrançois Tigeot {
15501487f786SFrançois Tigeot intel_fbdev_restore_mode(dev);
15511487f786SFrançois Tigeot #if 0
15521487f786SFrançois Tigeot vga_switcheroo_process_delayed_switch();
15531487f786SFrançois Tigeot #endif
15541487f786SFrançois Tigeot }
15551487f786SFrançois Tigeot
i915_driver_postclose(struct drm_device * dev,struct drm_file * file)15561487f786SFrançois Tigeot static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
15571487f786SFrançois Tigeot {
15581487f786SFrançois Tigeot struct drm_i915_file_private *file_priv = file->driver_priv;
15591487f786SFrançois Tigeot
1560a85cb24fSFrançois Tigeot mutex_lock(&dev->struct_mutex);
1561*3f2dd94aSFrançois Tigeot i915_gem_context_close(file);
1562a85cb24fSFrançois Tigeot i915_gem_release(dev, file);
1563a85cb24fSFrançois Tigeot mutex_unlock(&dev->struct_mutex);
1564a85cb24fSFrançois Tigeot
15651487f786SFrançois Tigeot kfree(file_priv);
15661487f786SFrançois Tigeot }
15671487f786SFrançois Tigeot
1568a85cb24fSFrançois Tigeot #if 0
156924edb884SFrançois Tigeot static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
157024edb884SFrançois Tigeot {
1571303bf270SFrançois Tigeot struct drm_device *dev = &dev_priv->drm;
1572aee94f86SFrançois Tigeot struct intel_encoder *encoder;
157324edb884SFrançois Tigeot
157424edb884SFrançois Tigeot drm_modeset_lock_all(dev);
1575aee94f86SFrançois Tigeot for_each_intel_encoder(dev, encoder)
1576aee94f86SFrançois Tigeot if (encoder->suspend)
1577aee94f86SFrançois Tigeot encoder->suspend(encoder);
157824edb884SFrançois Tigeot drm_modeset_unlock_all(dev);
157924edb884SFrançois Tigeot }
158024edb884SFrançois Tigeot
15812c9916cdSFrançois Tigeot static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
15821b13d190SFrançois Tigeot bool rpm_resume);
15838621f407SFrançois Tigeot static int vlv_suspend_complete(struct drm_i915_private *dev_priv);
158419c468b4SFrançois Tigeot
1585aee94f86SFrançois Tigeot static bool suspend_to_idle(struct drm_i915_private *dev_priv)
1586aee94f86SFrançois Tigeot {
1587aee94f86SFrançois Tigeot #if IS_ENABLED(CONFIG_ACPI_SLEEP)
1588aee94f86SFrançois Tigeot if (acpi_target_system_state() < ACPI_STATE_S3)
1589aee94f86SFrançois Tigeot return true;
1590aee94f86SFrançois Tigeot #endif
1591aee94f86SFrançois Tigeot return false;
1592aee94f86SFrançois Tigeot }
15931b13d190SFrançois Tigeot
15942c9916cdSFrançois Tigeot static int i915_drm_suspend(struct drm_device *dev)
1595e3adcf8fSFrançois Tigeot {
1596bf017597SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
15971e12ee3bSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
159824edb884SFrançois Tigeot pci_power_t opregion_target_state;
1599477eb7f9SFrançois Tigeot int error;
16009edbd4a0SFrançois Tigeot
1601a2fdbec6SFrançois Tigeot /* ignore lid events during suspend */
1602a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock);
1603a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_SUSPENDED;
1604a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock);
1605a2fdbec6SFrançois Tigeot
1606aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
1607aee94f86SFrançois Tigeot
16089edbd4a0SFrançois Tigeot /* We do a lot of poking in a lot of registers, make sure they work
16099edbd4a0SFrançois Tigeot * properly. */
1610ba55f2f5SFrançois Tigeot intel_display_set_init_power(dev_priv, true);
1611a2fdbec6SFrançois Tigeot
1612e3adcf8fSFrançois Tigeot drm_kms_helper_poll_disable(dev);
1613e3adcf8fSFrançois Tigeot
16141e12ee3bSFrançois Tigeot pci_save_state(pdev);
16151e12ee3bSFrançois Tigeot
1616a85cb24fSFrançois Tigeot error = i915_gem_suspend(dev_priv);
1617e3adcf8fSFrançois Tigeot if (error) {
16181e12ee3bSFrançois Tigeot dev_err(&pdev->dev,
1619a2fdbec6SFrançois Tigeot "GEM idle failed, resume might fail\n");
1620aee94f86SFrançois Tigeot goto out;
1621e3adcf8fSFrançois Tigeot }
1622a2fdbec6SFrançois Tigeot
1623a05eeebfSFrançois Tigeot intel_display_suspend(dev);
16245d0b1887SFrançois Tigeot
162524edb884SFrançois Tigeot intel_dp_mst_suspend(dev);
162624edb884SFrançois Tigeot
16272c9916cdSFrançois Tigeot intel_runtime_pm_disable_interrupts(dev_priv);
162824edb884SFrançois Tigeot intel_hpd_cancel_work(dev_priv);
162924edb884SFrançois Tigeot
163024edb884SFrançois Tigeot intel_suspend_encoders(dev_priv);
163124edb884SFrançois Tigeot
16324be47400SFrançois Tigeot intel_suspend_hw(dev_priv);
1633e3adcf8fSFrançois Tigeot
16344be47400SFrançois Tigeot i915_gem_suspend_gtt_mappings(dev_priv);
16359edbd4a0SFrançois Tigeot
1636a85cb24fSFrançois Tigeot i915_save_state(dev_priv);
1637e3adcf8fSFrançois Tigeot
1638aee94f86SFrançois Tigeot opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
16391487f786SFrançois Tigeot intel_opregion_notify_adapter(dev_priv, opregion_target_state);
164024edb884SFrançois Tigeot
1641a85cb24fSFrançois Tigeot intel_uncore_suspend(dev_priv);
16421487f786SFrançois Tigeot intel_opregion_unregister(dev_priv);
1643e3adcf8fSFrançois Tigeot
1644477eb7f9SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
16455d0b1887SFrançois Tigeot
1646ba55f2f5SFrançois Tigeot dev_priv->suspend_count++;
1647ba55f2f5SFrançois Tigeot
16488621f407SFrançois Tigeot intel_csr_ucode_suspend(dev_priv);
1649aee94f86SFrançois Tigeot
1650aee94f86SFrançois Tigeot out:
1651aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
1652aee94f86SFrançois Tigeot
1653aee94f86SFrançois Tigeot return error;
1654e3adcf8fSFrançois Tigeot }
1655e3adcf8fSFrançois Tigeot
16561e12ee3bSFrançois Tigeot static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
16572c9916cdSFrançois Tigeot {
16581e12ee3bSFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
1659a85cb24fSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
1660aee94f86SFrançois Tigeot bool fw_csr;
16612c9916cdSFrançois Tigeot int ret;
16622c9916cdSFrançois Tigeot
1663aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
1664aee94f86SFrançois Tigeot
16651e12ee3bSFrançois Tigeot intel_display_set_init_power(dev_priv, false);
16661e12ee3bSFrançois Tigeot
1667*3f2dd94aSFrançois Tigeot fw_csr = !IS_GEN9_LP(dev_priv) && !hibernation &&
16688621f407SFrançois Tigeot suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
1669aee94f86SFrançois Tigeot /*
1670aee94f86SFrançois Tigeot * In case of firmware assisted context save/restore don't manually
1671aee94f86SFrançois Tigeot * deinit the power domains. This also means the CSR/DMC firmware will
1672aee94f86SFrançois Tigeot * stay active, it will power down any HW resources as required and
1673aee94f86SFrançois Tigeot * also enable deeper system power states that would be blocked if the
1674aee94f86SFrançois Tigeot * firmware was inactive.
1675aee94f86SFrançois Tigeot */
1676aee94f86SFrançois Tigeot if (!fw_csr)
1677aee94f86SFrançois Tigeot intel_power_domains_suspend(dev_priv);
1678aee94f86SFrançois Tigeot
16798621f407SFrançois Tigeot ret = 0;
1680a85cb24fSFrançois Tigeot if (IS_GEN9_LP(dev_priv))
16818621f407SFrançois Tigeot bxt_enable_dc9(dev_priv);
16828621f407SFrançois Tigeot else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
16838621f407SFrançois Tigeot hsw_enable_pc8(dev_priv);
16848621f407SFrançois Tigeot else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
16858621f407SFrançois Tigeot ret = vlv_suspend_complete(dev_priv);
16862c9916cdSFrançois Tigeot
16872c9916cdSFrançois Tigeot if (ret) {
16882c9916cdSFrançois Tigeot DRM_ERROR("Suspend complete failed: %d\n", ret);
1689aee94f86SFrançois Tigeot if (!fw_csr)
1690aee94f86SFrançois Tigeot intel_power_domains_init_hw(dev_priv, true);
16912c9916cdSFrançois Tigeot
1692aee94f86SFrançois Tigeot goto out;
16932c9916cdSFrançois Tigeot }
16942c9916cdSFrançois Tigeot
1695a85cb24fSFrançois Tigeot pci_disable_device(pdev);
16962c9916cdSFrançois Tigeot /*
1697a05eeebfSFrançois Tigeot * During hibernation on some platforms the BIOS may try to access
16982c9916cdSFrançois Tigeot * the device even though it's already in D3 and hang the machine. So
16992c9916cdSFrançois Tigeot * leave the device in D0 on those platforms and hope the BIOS will
1700a05eeebfSFrançois Tigeot * power down the device properly. The issue was seen on multiple old
1701a05eeebfSFrançois Tigeot * GENs with different BIOS vendors, so having an explicit blacklist
1702a05eeebfSFrançois Tigeot * is inpractical; apply the workaround on everything pre GEN6. The
1703a05eeebfSFrançois Tigeot * platforms where the issue was seen:
1704a05eeebfSFrançois Tigeot * Lenovo Thinkpad X301, X61s, X60, T60, X41
1705a05eeebfSFrançois Tigeot * Fujitsu FSC S7110
1706a05eeebfSFrançois Tigeot * Acer Aspire 1830T
17072c9916cdSFrançois Tigeot */
17084be47400SFrançois Tigeot if (!(hibernation && INTEL_GEN(dev_priv) < 6))
1709a85cb24fSFrançois Tigeot pci_set_power_state(pdev, PCI_D3hot);
17102c9916cdSFrançois Tigeot
1711aee94f86SFrançois Tigeot dev_priv->suspended_to_idle = suspend_to_idle(dev_priv);
1712aee94f86SFrançois Tigeot
1713aee94f86SFrançois Tigeot out:
1714aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
1715aee94f86SFrançois Tigeot
1716aee94f86SFrançois Tigeot return ret;
17172c9916cdSFrançois Tigeot }
17182c9916cdSFrançois Tigeot
1719a85cb24fSFrançois Tigeot static int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state)
1720e3adcf8fSFrançois Tigeot {
1721e3adcf8fSFrançois Tigeot int error;
1722e3adcf8fSFrançois Tigeot
1723303bf270SFrançois Tigeot if (!dev) {
17249edbd4a0SFrançois Tigeot DRM_ERROR("dev: %p\n", dev);
1725c4a9e910SFrançois Tigeot DRM_ERROR("DRM not initialized, aborting suspend.\n");
1726c4a9e910SFrançois Tigeot return -ENODEV;
1727c4a9e910SFrançois Tigeot }
1728c4a9e910SFrançois Tigeot
17292c9916cdSFrançois Tigeot if (WARN_ON_ONCE(state.event != PM_EVENT_SUSPEND &&
17302c9916cdSFrançois Tigeot state.event != PM_EVENT_FREEZE))
17312c9916cdSFrançois Tigeot return -EINVAL;
17322c9916cdSFrançois Tigeot
17339edbd4a0SFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
17349edbd4a0SFrançois Tigeot return 0;
17359edbd4a0SFrançois Tigeot
17362c9916cdSFrançois Tigeot error = i915_drm_suspend(dev);
1737e3adcf8fSFrançois Tigeot if (error)
17389edbd4a0SFrançois Tigeot return error;
17399edbd4a0SFrançois Tigeot
17402c9916cdSFrançois Tigeot return i915_drm_suspend_late(dev, false);
1741c4a9e910SFrançois Tigeot }
1742c4a9e910SFrançois Tigeot
17432c9916cdSFrançois Tigeot static int i915_drm_resume(struct drm_device *dev)
1744c4a9e910SFrançois Tigeot {
1745303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
17468621f407SFrançois Tigeot int ret;
17479edbd4a0SFrançois Tigeot
1748aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
17491e12ee3bSFrançois Tigeot intel_sanitize_gt_powersave(dev_priv);
1750aee94f86SFrançois Tigeot
175171f41f3eSFrançois Tigeot ret = i915_ggtt_enable_hw(dev_priv);
17528621f407SFrançois Tigeot if (ret)
17538621f407SFrançois Tigeot DRM_ERROR("failed to re-enable GGTT\n");
17548621f407SFrançois Tigeot
17558621f407SFrançois Tigeot intel_csr_ucode_resume(dev_priv);
17568621f407SFrançois Tigeot
1757a85cb24fSFrançois Tigeot i915_gem_resume(dev_priv);
17589edbd4a0SFrançois Tigeot
1759a85cb24fSFrançois Tigeot i915_restore_state(dev_priv);
17601e12ee3bSFrançois Tigeot intel_pps_unlock_regs_wa(dev_priv);
17611487f786SFrançois Tigeot intel_opregion_setup(dev_priv);
1762c4a9e910SFrançois Tigeot
1763a85cb24fSFrançois Tigeot intel_init_pch_refclk(dev_priv);
176419df918dSFrançois Tigeot
1765477eb7f9SFrançois Tigeot /*
1766477eb7f9SFrançois Tigeot * Interrupts have to be enabled before any batches are run. If not the
1767477eb7f9SFrançois Tigeot * GPU will hang. i915_gem_init_hw() will initiate batches to
1768477eb7f9SFrançois Tigeot * update/restore the context.
1769477eb7f9SFrançois Tigeot *
17704be47400SFrançois Tigeot * drm_mode_config_reset() needs AUX interrupts.
17714be47400SFrançois Tigeot *
1772477eb7f9SFrançois Tigeot * Modeset enabling in intel_modeset_init_hw() also needs working
1773477eb7f9SFrançois Tigeot * interrupts.
1774477eb7f9SFrançois Tigeot */
1775477eb7f9SFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv);
1776477eb7f9SFrançois Tigeot
17774be47400SFrançois Tigeot drm_mode_config_reset(dev);
17784be47400SFrançois Tigeot
1779a2fdbec6SFrançois Tigeot mutex_lock(&dev->struct_mutex);
1780a85cb24fSFrançois Tigeot if (i915_gem_init_hw(dev_priv)) {
1781ba55f2f5SFrançois Tigeot DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
17821e12ee3bSFrançois Tigeot i915_gem_set_wedged(dev_priv);
1783ba55f2f5SFrançois Tigeot }
1784a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex);
1785a2fdbec6SFrançois Tigeot
1786a85cb24fSFrançois Tigeot intel_guc_resume(dev_priv);
1787352ff8bdSFrançois Tigeot
178819df918dSFrançois Tigeot intel_modeset_init_hw(dev);
1789*3f2dd94aSFrançois Tigeot intel_init_clock_gating(dev_priv);
17908e26cdf6SFrançois Tigeot
17915e269720SFrançois Tigeot spin_lock_irq(&dev_priv->irq_lock);
17922c9916cdSFrançois Tigeot if (dev_priv->display.hpd_irq_setup)
17931487f786SFrançois Tigeot dev_priv->display.hpd_irq_setup(dev_priv);
17945e269720SFrançois Tigeot spin_unlock_irq(&dev_priv->irq_lock);
17952c9916cdSFrançois Tigeot
17962c9916cdSFrançois Tigeot intel_dp_mst_resume(dev);
17972c9916cdSFrançois Tigeot
1798c0e85e96SFrançois Tigeot intel_display_resume(dev);
1799c0e85e96SFrançois Tigeot
18004be47400SFrançois Tigeot drm_kms_helper_poll_enable(dev);
18014be47400SFrançois Tigeot
1802a2fdbec6SFrançois Tigeot /*
1803a2fdbec6SFrançois Tigeot * ... but also need to make sure that hotplug processing
1804a2fdbec6SFrançois Tigeot * doesn't cause havoc. Like in the driver load code we don't
1805a2fdbec6SFrançois Tigeot * bother with the tiny race here where we might loose hotplug
1806a2fdbec6SFrançois Tigeot * notifications.
1807a2fdbec6SFrançois Tigeot * */
18082c9916cdSFrançois Tigeot intel_hpd_init(dev_priv);
1809c4a9e910SFrançois Tigeot
18101487f786SFrançois Tigeot intel_opregion_register(dev_priv);
1811e3adcf8fSFrançois Tigeot
18121b13d190SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false);
1813a2fdbec6SFrançois Tigeot
1814a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock);
1815a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_DONE;
1816a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock);
18179edbd4a0SFrançois Tigeot
18181487f786SFrançois Tigeot intel_opregion_notify_adapter(dev_priv, PCI_D0);
181924edb884SFrançois Tigeot
182087df8fc6SFrançois Tigeot intel_autoenable_gt_powersave(dev_priv);
18212c9916cdSFrançois Tigeot
1822aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
1823aee94f86SFrançois Tigeot
1824ba55f2f5SFrançois Tigeot return 0;
1825a2fdbec6SFrançois Tigeot }
1826a2fdbec6SFrançois Tigeot
18272c9916cdSFrançois Tigeot static int i915_drm_resume_early(struct drm_device *dev)
1828c4a9e910SFrançois Tigeot {
1829bf017597SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
18301e12ee3bSFrançois Tigeot struct pci_dev *pdev = dev_priv->drm.pdev;
1831a85cb24fSFrançois Tigeot int ret;
1832c4a9e910SFrançois Tigeot
18335d0b1887SFrançois Tigeot /*
18342c9916cdSFrançois Tigeot * We have a resume ordering issue with the snd-hda driver also
18352c9916cdSFrançois Tigeot * requiring our device to be power up. Due to the lack of a
18362c9916cdSFrançois Tigeot * parent/child relationship we currently solve this with an early
18372c9916cdSFrançois Tigeot * resume hook.
18382c9916cdSFrançois Tigeot *
18392c9916cdSFrançois Tigeot * FIXME: This should be solved with a special hdmi sink device or
18402c9916cdSFrançois Tigeot * similar so that power domains can be employed.
18415d0b1887SFrançois Tigeot */
1842c0e85e96SFrançois Tigeot
1843c0e85e96SFrançois Tigeot /*
1844c0e85e96SFrançois Tigeot * Note that we need to set the power state explicitly, since we
1845c0e85e96SFrançois Tigeot * powered off the device during freeze and the PCI core won't power
1846c0e85e96SFrançois Tigeot * it back up for us during thaw. Powering off the device during
1847c0e85e96SFrançois Tigeot * freeze is not a hard requirement though, and during the
1848c0e85e96SFrançois Tigeot * suspend/resume phases the PCI core makes sure we get here with the
1849c0e85e96SFrançois Tigeot * device powered on. So in case we change our freeze logic and keep
1850c0e85e96SFrançois Tigeot * the device powered we can also remove the following set power state
1851c0e85e96SFrançois Tigeot * call.
1852c0e85e96SFrançois Tigeot */
1853a85cb24fSFrançois Tigeot ret = pci_set_power_state(pdev, PCI_D0);
1854c0e85e96SFrançois Tigeot if (ret) {
1855c0e85e96SFrançois Tigeot DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret);
1856c0e85e96SFrançois Tigeot goto out;
1857c0e85e96SFrançois Tigeot }
1858c0e85e96SFrançois Tigeot
1859c0e85e96SFrançois Tigeot /*
1860c0e85e96SFrançois Tigeot * Note that pci_enable_device() first enables any parent bridge
1861c0e85e96SFrançois Tigeot * device and only then sets the power state for this device. The
1862c0e85e96SFrançois Tigeot * bridge enabling is a nop though, since bridge devices are resumed
1863c0e85e96SFrançois Tigeot * first. The order of enabling power and enabling the device is
1864c0e85e96SFrançois Tigeot * imposed by the PCI core as described above, so here we preserve the
1865c0e85e96SFrançois Tigeot * same order for the freeze/thaw phases.
1866c0e85e96SFrançois Tigeot *
1867c0e85e96SFrançois Tigeot * TODO: eventually we should remove pci_disable_device() /
1868c0e85e96SFrançois Tigeot * pci_enable_enable_device() from suspend/resume. Due to how they
1869c0e85e96SFrançois Tigeot * depend on the device enable refcount we can't anyway depend on them
1870c0e85e96SFrançois Tigeot * disabling/enabling the device.
1871c0e85e96SFrançois Tigeot */
1872a85cb24fSFrançois Tigeot if (pci_enable_device(pdev)) {
1873aee94f86SFrançois Tigeot ret = -EIO;
1874aee94f86SFrançois Tigeot goto out;
1875aee94f86SFrançois Tigeot }
18762c9916cdSFrançois Tigeot
18771e12ee3bSFrançois Tigeot pci_set_master(pdev);
18782c9916cdSFrançois Tigeot
1879aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
1880aee94f86SFrançois Tigeot
1881aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
18822c9916cdSFrançois Tigeot ret = vlv_resume_prepare(dev_priv, false);
18832c9916cdSFrançois Tigeot if (ret)
188419c468b4SFrançois Tigeot DRM_ERROR("Resume prepare failed: %d, continuing anyway\n",
188519c468b4SFrançois Tigeot ret);
18862c9916cdSFrançois Tigeot
1887a85cb24fSFrançois Tigeot intel_uncore_resume_early(dev_priv);
18882c9916cdSFrançois Tigeot
1889a85cb24fSFrançois Tigeot if (IS_GEN9_LP(dev_priv)) {
18908621f407SFrançois Tigeot if (!dev_priv->suspended_to_idle)
18918621f407SFrançois Tigeot gen9_sanitize_dc_state(dev_priv);
18928621f407SFrançois Tigeot bxt_disable_dc9(dev_priv);
18938621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
18942c9916cdSFrançois Tigeot hsw_disable_pc8(dev_priv);
18958621f407SFrançois Tigeot }
18962c9916cdSFrançois Tigeot
18971487f786SFrançois Tigeot intel_uncore_sanitize(dev_priv);
1898aee94f86SFrançois Tigeot
1899a85cb24fSFrançois Tigeot if (IS_GEN9_LP(dev_priv) ||
19008621f407SFrançois Tigeot !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
1901aee94f86SFrançois Tigeot intel_power_domains_init_hw(dev_priv, true);
1902*3f2dd94aSFrançois Tigeot else
1903*3f2dd94aSFrançois Tigeot intel_display_set_init_power(dev_priv, true);
1904aee94f86SFrançois Tigeot
1905a85cb24fSFrançois Tigeot i915_gem_sanitize(dev_priv);
1906a85cb24fSFrançois Tigeot
19078621f407SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
19088621f407SFrançois Tigeot
1909aee94f86SFrançois Tigeot out:
1910aee94f86SFrançois Tigeot dev_priv->suspended_to_idle = false;
1911aee94f86SFrançois Tigeot
19122c9916cdSFrançois Tigeot return ret;
19132c9916cdSFrançois Tigeot }
19142c9916cdSFrançois Tigeot
1915a85cb24fSFrançois Tigeot static int i915_resume_switcheroo(struct drm_device *dev)
19162c9916cdSFrançois Tigeot {
19172c9916cdSFrançois Tigeot int ret;
19182c9916cdSFrançois Tigeot
19192c9916cdSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
19202c9916cdSFrançois Tigeot return 0;
19212c9916cdSFrançois Tigeot
19222c9916cdSFrançois Tigeot ret = i915_drm_resume_early(dev);
19235d0b1887SFrançois Tigeot if (ret)
19245d0b1887SFrançois Tigeot return ret;
1925e3adcf8fSFrançois Tigeot
19262c9916cdSFrançois Tigeot return i915_drm_resume(dev);
1927c4a9e910SFrançois Tigeot }
1928a85cb24fSFrançois Tigeot #endif
19291e12ee3bSFrançois Tigeot
1930e9243325SFrançois Tigeot /**
1931e9243325SFrançois Tigeot * i915_reset - reset chip after a hang
1932*3f2dd94aSFrançois Tigeot * @i915: #drm_i915_private to reset
1933*3f2dd94aSFrançois Tigeot * @flags: Instructions
1934e9243325SFrançois Tigeot *
19351e12ee3bSFrançois Tigeot * Reset the chip. Useful if a hang is detected. Marks the device as wedged
19361e12ee3bSFrançois Tigeot * on failure.
19371e12ee3bSFrançois Tigeot *
19381e12ee3bSFrançois Tigeot * Caller must hold the struct_mutex.
1939e9243325SFrançois Tigeot *
1940e9243325SFrançois Tigeot * Procedure is fairly simple:
1941e9243325SFrançois Tigeot * - reset the chip using the reset reg
1942e9243325SFrançois Tigeot * - re-init context state
1943e9243325SFrançois Tigeot * - re-init hardware status page
1944e9243325SFrançois Tigeot * - re-init ring buffer
1945e9243325SFrançois Tigeot * - re-init interrupt state
1946e9243325SFrançois Tigeot * - re-init display
1947e9243325SFrançois Tigeot */
i915_reset(struct drm_i915_private * i915,unsigned int flags)1948*3f2dd94aSFrançois Tigeot void i915_reset(struct drm_i915_private *i915, unsigned int flags)
1949e3adcf8fSFrançois Tigeot {
1950*3f2dd94aSFrançois Tigeot struct i915_gpu_error *error = &i915->gpu_error;
1951e9243325SFrançois Tigeot int ret;
1952e9243325SFrançois Tigeot
1953*3f2dd94aSFrançois Tigeot lockdep_assert_held(&i915->drm.struct_mutex);
1954a85cb24fSFrançois Tigeot GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
19551e12ee3bSFrançois Tigeot
1956a85cb24fSFrançois Tigeot if (!test_bit(I915_RESET_HANDOFF, &error->flags))
19571e12ee3bSFrançois Tigeot return;
1958e3adcf8fSFrançois Tigeot
19598621f407SFrançois Tigeot /* Clear any previous failed attempts at recovery. Time to try again. */
1960*3f2dd94aSFrançois Tigeot if (!i915_gem_unset_wedged(i915))
1961a85cb24fSFrançois Tigeot goto wakeup;
1962a85cb24fSFrançois Tigeot
1963*3f2dd94aSFrançois Tigeot if (!(flags & I915_RESET_QUIET))
1964*3f2dd94aSFrançois Tigeot dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n");
19651e12ee3bSFrançois Tigeot error->reset_count++;
19668621f407SFrançois Tigeot
1967*3f2dd94aSFrançois Tigeot disable_irq(i915->drm.irq);
1968*3f2dd94aSFrançois Tigeot ret = i915_gem_reset_prepare(i915);
1969a85cb24fSFrançois Tigeot if (ret) {
1970a85cb24fSFrançois Tigeot DRM_ERROR("GPU recovery failed\n");
1971*3f2dd94aSFrançois Tigeot intel_gpu_reset(i915, ALL_ENGINES);
1972a85cb24fSFrançois Tigeot goto error;
1973a85cb24fSFrançois Tigeot }
1974303bf270SFrançois Tigeot
1975*3f2dd94aSFrançois Tigeot ret = intel_gpu_reset(i915, ALL_ENGINES);
1976e3adcf8fSFrançois Tigeot if (ret) {
19778621f407SFrançois Tigeot if (ret != -ENODEV)
19789edbd4a0SFrançois Tigeot DRM_ERROR("Failed to reset chip: %i\n", ret);
19798621f407SFrançois Tigeot else
19808621f407SFrançois Tigeot DRM_DEBUG_DRIVER("GPU reset disabled\n");
19818621f407SFrançois Tigeot goto error;
1982e3adcf8fSFrançois Tigeot }
1983e3adcf8fSFrançois Tigeot
1984*3f2dd94aSFrançois Tigeot i915_gem_reset(i915);
1985*3f2dd94aSFrançois Tigeot intel_overlay_reset(i915);
19862c9916cdSFrançois Tigeot
1987e9243325SFrançois Tigeot /* Ok, now get things going again... */
1988e9243325SFrançois Tigeot
1989e9243325SFrançois Tigeot /*
1990e9243325SFrançois Tigeot * Everything depends on having the GTT running, so we need to start
1991*3f2dd94aSFrançois Tigeot * there.
1992*3f2dd94aSFrançois Tigeot */
1993*3f2dd94aSFrançois Tigeot ret = i915_ggtt_enable_hw(i915);
1994*3f2dd94aSFrançois Tigeot if (ret) {
1995*3f2dd94aSFrançois Tigeot DRM_ERROR("Failed to re-enable GGTT following reset %d\n", ret);
1996*3f2dd94aSFrançois Tigeot goto error;
1997*3f2dd94aSFrançois Tigeot }
1998*3f2dd94aSFrançois Tigeot
1999*3f2dd94aSFrançois Tigeot /*
2000e9243325SFrançois Tigeot * Next we need to restore the context, but we don't use those
2001e9243325SFrançois Tigeot * yet either...
2002e9243325SFrançois Tigeot *
2003e9243325SFrançois Tigeot * Ring buffer needs to be re-initialized in the KMS case, or if X
2004e9243325SFrançois Tigeot * was running at the time of the reset (i.e. we weren't VT
2005e9243325SFrançois Tigeot * switched away).
2006e9243325SFrançois Tigeot */
2007*3f2dd94aSFrançois Tigeot ret = i915_gem_init_hw(i915);
20089edbd4a0SFrançois Tigeot if (ret) {
20099edbd4a0SFrançois Tigeot DRM_ERROR("Failed hw init on reset %d\n", ret);
20108621f407SFrançois Tigeot goto error;
20119edbd4a0SFrançois Tigeot }
2012e3adcf8fSFrançois Tigeot
2013*3f2dd94aSFrançois Tigeot i915_queue_hangcheck(i915);
2014a85cb24fSFrançois Tigeot
2015a85cb24fSFrançois Tigeot finish:
2016*3f2dd94aSFrançois Tigeot i915_gem_reset_finish(i915);
2017*3f2dd94aSFrançois Tigeot enable_irq(i915->drm.irq);
2018a85cb24fSFrançois Tigeot
20191e12ee3bSFrançois Tigeot wakeup:
2020a85cb24fSFrançois Tigeot clear_bit(I915_RESET_HANDOFF, &error->flags);
2021a85cb24fSFrançois Tigeot wake_up_bit(&error->flags, I915_RESET_HANDOFF);
20221e12ee3bSFrançois Tigeot return;
20238621f407SFrançois Tigeot
20248621f407SFrançois Tigeot error:
2025*3f2dd94aSFrançois Tigeot i915_gem_set_wedged(i915);
2026*3f2dd94aSFrançois Tigeot i915_gem_retire_requests(i915);
2027a85cb24fSFrançois Tigeot goto finish;
2028e9243325SFrançois Tigeot }
2029e9243325SFrançois Tigeot
2030*3f2dd94aSFrançois Tigeot /**
2031*3f2dd94aSFrançois Tigeot * i915_reset_engine - reset GPU engine to recover from a hang
2032*3f2dd94aSFrançois Tigeot * @engine: engine to reset
2033*3f2dd94aSFrançois Tigeot * @flags: options
2034*3f2dd94aSFrançois Tigeot *
2035*3f2dd94aSFrançois Tigeot * Reset a specific GPU engine. Useful if a hang is detected.
2036*3f2dd94aSFrançois Tigeot * Returns zero on successful reset or otherwise an error code.
2037*3f2dd94aSFrançois Tigeot *
2038*3f2dd94aSFrançois Tigeot * Procedure is:
2039*3f2dd94aSFrançois Tigeot * - identifies the request that caused the hang and it is dropped
2040*3f2dd94aSFrançois Tigeot * - reset engine (which will force the engine to idle)
2041*3f2dd94aSFrançois Tigeot * - re-init/configure engine
2042*3f2dd94aSFrançois Tigeot */
i915_reset_engine(struct intel_engine_cs * engine,unsigned int flags)2043*3f2dd94aSFrançois Tigeot int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
2044*3f2dd94aSFrançois Tigeot {
2045*3f2dd94aSFrançois Tigeot struct i915_gpu_error *error = &engine->i915->gpu_error;
2046*3f2dd94aSFrançois Tigeot struct drm_i915_gem_request *active_request;
2047*3f2dd94aSFrançois Tigeot int ret;
2048*3f2dd94aSFrançois Tigeot
2049*3f2dd94aSFrançois Tigeot GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
2050*3f2dd94aSFrançois Tigeot
2051*3f2dd94aSFrançois Tigeot if (!(flags & I915_RESET_QUIET)) {
2052*3f2dd94aSFrançois Tigeot dev_notice(engine->i915->drm.dev,
2053*3f2dd94aSFrançois Tigeot "Resetting %s after gpu hang\n", engine->name);
2054*3f2dd94aSFrançois Tigeot }
2055*3f2dd94aSFrançois Tigeot error->reset_engine_count[engine->id]++;
2056*3f2dd94aSFrançois Tigeot
2057*3f2dd94aSFrançois Tigeot active_request = i915_gem_reset_prepare_engine(engine);
2058*3f2dd94aSFrançois Tigeot if (IS_ERR(active_request)) {
2059*3f2dd94aSFrançois Tigeot DRM_DEBUG_DRIVER("Previous reset failed, promote to full reset\n");
2060*3f2dd94aSFrançois Tigeot ret = PTR_ERR(active_request);
2061*3f2dd94aSFrançois Tigeot goto out;
2062*3f2dd94aSFrançois Tigeot }
2063*3f2dd94aSFrançois Tigeot
2064*3f2dd94aSFrançois Tigeot ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
2065*3f2dd94aSFrançois Tigeot if (ret) {
2066*3f2dd94aSFrançois Tigeot /* If we fail here, we expect to fallback to a global reset */
2067*3f2dd94aSFrançois Tigeot DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
2068*3f2dd94aSFrançois Tigeot engine->name, ret);
2069*3f2dd94aSFrançois Tigeot goto out;
2070*3f2dd94aSFrançois Tigeot }
2071*3f2dd94aSFrançois Tigeot
2072*3f2dd94aSFrançois Tigeot /*
2073*3f2dd94aSFrançois Tigeot * The request that caused the hang is stuck on elsp, we know the
2074*3f2dd94aSFrançois Tigeot * active request and can drop it, adjust head to skip the offending
2075*3f2dd94aSFrançois Tigeot * request to resume executing remaining requests in the queue.
2076*3f2dd94aSFrançois Tigeot */
2077*3f2dd94aSFrançois Tigeot i915_gem_reset_engine(engine, active_request);
2078*3f2dd94aSFrançois Tigeot
2079*3f2dd94aSFrançois Tigeot /*
2080*3f2dd94aSFrançois Tigeot * The engine and its registers (and workarounds in case of render)
2081*3f2dd94aSFrançois Tigeot * have been reset to their default values. Follow the init_ring
2082*3f2dd94aSFrançois Tigeot * process to program RING_MODE, HWSP and re-enable submission.
2083*3f2dd94aSFrançois Tigeot */
2084*3f2dd94aSFrançois Tigeot ret = engine->init_hw(engine);
2085*3f2dd94aSFrançois Tigeot if (ret)
2086*3f2dd94aSFrançois Tigeot goto out;
2087*3f2dd94aSFrançois Tigeot
2088*3f2dd94aSFrançois Tigeot out:
2089*3f2dd94aSFrançois Tigeot i915_gem_reset_finish_engine(engine);
2090*3f2dd94aSFrançois Tigeot return ret;
2091*3f2dd94aSFrançois Tigeot }
2092*3f2dd94aSFrançois Tigeot
20939edbd4a0SFrançois Tigeot #if 0
20941e12ee3bSFrançois Tigeot static int i915_pm_suspend(struct device *kdev)
20959edbd4a0SFrançois Tigeot {
20961e12ee3bSFrançois Tigeot struct pci_dev *pdev = to_pci_dev(kdev);
20971e12ee3bSFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev);
20989edbd4a0SFrançois Tigeot
20991e12ee3bSFrançois Tigeot if (!dev) {
21001e12ee3bSFrançois Tigeot dev_err(kdev, "DRM not initialized, aborting suspend.\n");
21019edbd4a0SFrançois Tigeot return -ENODEV;
21029edbd4a0SFrançois Tigeot }
21039edbd4a0SFrançois Tigeot
21041e12ee3bSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
21059edbd4a0SFrançois Tigeot return 0;
21069edbd4a0SFrançois Tigeot
21071e12ee3bSFrançois Tigeot return i915_drm_suspend(dev);
21089edbd4a0SFrançois Tigeot }
21099edbd4a0SFrançois Tigeot
21101e12ee3bSFrançois Tigeot static int i915_pm_suspend_late(struct device *kdev)
211124edb884SFrançois Tigeot {
21121e12ee3bSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21131e12ee3bSFrançois Tigeot
211424edb884SFrançois Tigeot /*
211519c468b4SFrançois Tigeot * We have a suspend ordering issue with the snd-hda driver also
211624edb884SFrançois Tigeot * requiring our device to be power up. Due to the lack of a
211724edb884SFrançois Tigeot * parent/child relationship we currently solve this with an late
211824edb884SFrançois Tigeot * suspend hook.
211924edb884SFrançois Tigeot *
212024edb884SFrançois Tigeot * FIXME: This should be solved with a special hdmi sink device or
212124edb884SFrançois Tigeot * similar so that power domains can be employed.
212224edb884SFrançois Tigeot */
21231e12ee3bSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
212424edb884SFrançois Tigeot return 0;
212524edb884SFrançois Tigeot
21261e12ee3bSFrançois Tigeot return i915_drm_suspend_late(dev, false);
21271b13d190SFrançois Tigeot }
212824edb884SFrançois Tigeot
21291e12ee3bSFrançois Tigeot static int i915_pm_poweroff_late(struct device *kdev)
21302c9916cdSFrançois Tigeot {
21311e12ee3bSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21322c9916cdSFrançois Tigeot
21331e12ee3bSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
21342c9916cdSFrançois Tigeot return 0;
21352c9916cdSFrançois Tigeot
21361e12ee3bSFrançois Tigeot return i915_drm_suspend_late(dev, true);
21372c9916cdSFrançois Tigeot }
21382c9916cdSFrançois Tigeot
21391e12ee3bSFrançois Tigeot static int i915_pm_resume_early(struct device *kdev)
21402c9916cdSFrançois Tigeot {
21411e12ee3bSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21422c9916cdSFrançois Tigeot
21431e12ee3bSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
21442c9916cdSFrançois Tigeot return 0;
21452c9916cdSFrançois Tigeot
21461e12ee3bSFrançois Tigeot return i915_drm_resume_early(dev);
214724edb884SFrançois Tigeot }
214824edb884SFrançois Tigeot
21491e12ee3bSFrançois Tigeot static int i915_pm_resume(struct device *kdev)
21509edbd4a0SFrançois Tigeot {
21511e12ee3bSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21529edbd4a0SFrançois Tigeot
21531e12ee3bSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
21542c9916cdSFrançois Tigeot return 0;
21552c9916cdSFrançois Tigeot
21561e12ee3bSFrançois Tigeot return i915_drm_resume(dev);
21579edbd4a0SFrançois Tigeot }
21581487f786SFrançois Tigeot
21591487f786SFrançois Tigeot /* freeze: before creating the hibernation_image */
21601e12ee3bSFrançois Tigeot static int i915_pm_freeze(struct device *kdev)
21611487f786SFrançois Tigeot {
2162*3f2dd94aSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21631487f786SFrançois Tigeot int ret;
21641487f786SFrançois Tigeot
2165*3f2dd94aSFrançois Tigeot if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) {
2166*3f2dd94aSFrançois Tigeot ret = i915_drm_suspend(dev);
21671487f786SFrançois Tigeot if (ret)
21681487f786SFrançois Tigeot return ret;
2169*3f2dd94aSFrançois Tigeot }
21701487f786SFrançois Tigeot
21711e12ee3bSFrançois Tigeot ret = i915_gem_freeze(kdev_to_i915(kdev));
21721e12ee3bSFrançois Tigeot if (ret)
21731e12ee3bSFrançois Tigeot return ret;
21741e12ee3bSFrançois Tigeot
21751e12ee3bSFrançois Tigeot return 0;
21761e12ee3bSFrançois Tigeot }
21771e12ee3bSFrançois Tigeot
21781e12ee3bSFrançois Tigeot static int i915_pm_freeze_late(struct device *kdev)
21791e12ee3bSFrançois Tigeot {
2180*3f2dd94aSFrançois Tigeot struct drm_device *dev = &kdev_to_i915(kdev)->drm;
21811e12ee3bSFrançois Tigeot int ret;
21821e12ee3bSFrançois Tigeot
2183*3f2dd94aSFrançois Tigeot if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) {
2184*3f2dd94aSFrançois Tigeot ret = i915_drm_suspend_late(dev, true);
21851e12ee3bSFrançois Tigeot if (ret)
21861e12ee3bSFrançois Tigeot return ret;
2187*3f2dd94aSFrançois Tigeot }
21881e12ee3bSFrançois Tigeot
21891e12ee3bSFrançois Tigeot ret = i915_gem_freeze_late(kdev_to_i915(kdev));
21901487f786SFrançois Tigeot if (ret)
21911487f786SFrançois Tigeot return ret;
21921487f786SFrançois Tigeot
21931487f786SFrançois Tigeot return 0;
21941487f786SFrançois Tigeot }
21951487f786SFrançois Tigeot
21961487f786SFrançois Tigeot /* thaw: called after creating the hibernation image, but before turning off. */
21971e12ee3bSFrançois Tigeot static int i915_pm_thaw_early(struct device *kdev)
21981487f786SFrançois Tigeot {
21991e12ee3bSFrançois Tigeot return i915_pm_resume_early(kdev);
22001487f786SFrançois Tigeot }
22011487f786SFrançois Tigeot
22021e12ee3bSFrançois Tigeot static int i915_pm_thaw(struct device *kdev)
22031487f786SFrançois Tigeot {
22041e12ee3bSFrançois Tigeot return i915_pm_resume(kdev);
22051487f786SFrançois Tigeot }
22061487f786SFrançois Tigeot
22071487f786SFrançois Tigeot /* restore: called after loading the hibernation image. */
22081e12ee3bSFrançois Tigeot static int i915_pm_restore_early(struct device *kdev)
22091487f786SFrançois Tigeot {
22101e12ee3bSFrançois Tigeot return i915_pm_resume_early(kdev);
22111487f786SFrançois Tigeot }
22121487f786SFrançois Tigeot
22131e12ee3bSFrançois Tigeot static int i915_pm_restore(struct device *kdev)
22141487f786SFrançois Tigeot {
22151e12ee3bSFrançois Tigeot return i915_pm_resume(kdev);
22161487f786SFrançois Tigeot }
22179edbd4a0SFrançois Tigeot
2218ba55f2f5SFrançois Tigeot /*
2219ba55f2f5SFrançois Tigeot * Save all Gunit registers that may be lost after a D3 and a subsequent
2220ba55f2f5SFrançois Tigeot * S0i[R123] transition. The list of registers needing a save/restore is
2221ba55f2f5SFrançois Tigeot * defined in the VLV2_S0IXRegs document. This documents marks all Gunit
2222ba55f2f5SFrançois Tigeot * registers in the following way:
2223ba55f2f5SFrançois Tigeot * - Driver: saved/restored by the driver
2224ba55f2f5SFrançois Tigeot * - Punit : saved/restored by the Punit firmware
2225ba55f2f5SFrançois Tigeot * - No, w/o marking: no need to save/restore, since the register is R/O or
2226ba55f2f5SFrançois Tigeot * used internally by the HW in a way that doesn't depend
2227ba55f2f5SFrançois Tigeot * keeping the content across a suspend/resume.
2228ba55f2f5SFrançois Tigeot * - Debug : used for debugging
2229ba55f2f5SFrançois Tigeot *
2230ba55f2f5SFrançois Tigeot * We save/restore all registers marked with 'Driver', with the following
2231ba55f2f5SFrançois Tigeot * exceptions:
2232ba55f2f5SFrançois Tigeot * - Registers out of use, including also registers marked with 'Debug'.
2233ba55f2f5SFrançois Tigeot * These have no effect on the driver's operation, so we don't save/restore
2234ba55f2f5SFrançois Tigeot * them to reduce the overhead.
2235ba55f2f5SFrançois Tigeot * - Registers that are fully setup by an initialization function called from
2236ba55f2f5SFrançois Tigeot * the resume path. For example many clock gating and RPS/RC6 registers.
2237ba55f2f5SFrançois Tigeot * - Registers that provide the right functionality with their reset defaults.
2238ba55f2f5SFrançois Tigeot *
2239ba55f2f5SFrançois Tigeot * TODO: Except for registers that based on the above 3 criteria can be safely
2240ba55f2f5SFrançois Tigeot * ignored, we save/restore all others, practically treating the HW context as
2241ba55f2f5SFrançois Tigeot * a black-box for the driver. Further investigation is needed to reduce the
2242ba55f2f5SFrançois Tigeot * saved/restored registers even further, by following the same 3 criteria.
2243ba55f2f5SFrançois Tigeot */
2244ba55f2f5SFrançois Tigeot static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
2245ba55f2f5SFrançois Tigeot {
2246ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
2247ba55f2f5SFrançois Tigeot int i;
2248ba55f2f5SFrançois Tigeot
2249ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */
2250ba55f2f5SFrançois Tigeot s->wr_watermark = I915_READ(GEN7_WR_WATERMARK);
2251ba55f2f5SFrançois Tigeot s->gfx_prio_ctrl = I915_READ(GEN7_GFX_PRIO_CTRL);
2252ba55f2f5SFrançois Tigeot s->arb_mode = I915_READ(ARB_MODE);
2253ba55f2f5SFrançois Tigeot s->gfx_pend_tlb0 = I915_READ(GEN7_GFX_PEND_TLB0);
2254ba55f2f5SFrançois Tigeot s->gfx_pend_tlb1 = I915_READ(GEN7_GFX_PEND_TLB1);
2255ba55f2f5SFrançois Tigeot
2256ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
2257352ff8bdSFrançois Tigeot s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS(i));
2258ba55f2f5SFrançois Tigeot
2259ba55f2f5SFrançois Tigeot s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
2260477eb7f9SFrançois Tigeot s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT);
2261ba55f2f5SFrançois Tigeot
2262ba55f2f5SFrançois Tigeot s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7);
2263ba55f2f5SFrançois Tigeot s->ecochk = I915_READ(GAM_ECOCHK);
2264ba55f2f5SFrançois Tigeot s->bsd_hwsp = I915_READ(BSD_HWS_PGA_GEN7);
2265ba55f2f5SFrançois Tigeot s->blt_hwsp = I915_READ(BLT_HWS_PGA_GEN7);
2266ba55f2f5SFrançois Tigeot
2267ba55f2f5SFrançois Tigeot s->tlb_rd_addr = I915_READ(GEN7_TLB_RD_ADDR);
2268ba55f2f5SFrançois Tigeot
2269ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */
2270ba55f2f5SFrançois Tigeot s->g3dctl = I915_READ(VLV_G3DCTL);
2271ba55f2f5SFrançois Tigeot s->gsckgctl = I915_READ(VLV_GSCKGCTL);
2272ba55f2f5SFrançois Tigeot s->mbctl = I915_READ(GEN6_MBCTL);
2273ba55f2f5SFrançois Tigeot
2274ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */
2275ba55f2f5SFrançois Tigeot s->ucgctl1 = I915_READ(GEN6_UCGCTL1);
2276ba55f2f5SFrançois Tigeot s->ucgctl3 = I915_READ(GEN6_UCGCTL3);
2277ba55f2f5SFrançois Tigeot s->rcgctl1 = I915_READ(GEN6_RCGCTL1);
2278ba55f2f5SFrançois Tigeot s->rcgctl2 = I915_READ(GEN6_RCGCTL2);
2279ba55f2f5SFrançois Tigeot s->rstctl = I915_READ(GEN6_RSTCTL);
2280ba55f2f5SFrançois Tigeot s->misccpctl = I915_READ(GEN7_MISCCPCTL);
2281ba55f2f5SFrançois Tigeot
2282ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */
2283ba55f2f5SFrançois Tigeot s->gfxpause = I915_READ(GEN6_GFXPAUSE);
2284ba55f2f5SFrançois Tigeot s->rpdeuhwtc = I915_READ(GEN6_RPDEUHWTC);
2285ba55f2f5SFrançois Tigeot s->rpdeuc = I915_READ(GEN6_RPDEUC);
2286ba55f2f5SFrançois Tigeot s->ecobus = I915_READ(ECOBUS);
2287ba55f2f5SFrançois Tigeot s->pwrdwnupctl = I915_READ(VLV_PWRDWNUPCTL);
2288ba55f2f5SFrançois Tigeot s->rp_down_timeout = I915_READ(GEN6_RP_DOWN_TIMEOUT);
2289ba55f2f5SFrançois Tigeot s->rp_deucsw = I915_READ(GEN6_RPDEUCSW);
2290ba55f2f5SFrançois Tigeot s->rcubmabdtmr = I915_READ(GEN6_RCUBMABDTMR);
2291ba55f2f5SFrançois Tigeot s->rcedata = I915_READ(VLV_RCEDATA);
2292ba55f2f5SFrançois Tigeot s->spare2gh = I915_READ(VLV_SPAREG2H);
2293ba55f2f5SFrançois Tigeot
2294ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */
2295ba55f2f5SFrançois Tigeot s->gt_imr = I915_READ(GTIMR);
2296ba55f2f5SFrançois Tigeot s->gt_ier = I915_READ(GTIER);
2297ba55f2f5SFrançois Tigeot s->pm_imr = I915_READ(GEN6_PMIMR);
2298ba55f2f5SFrançois Tigeot s->pm_ier = I915_READ(GEN6_PMIER);
2299ba55f2f5SFrançois Tigeot
2300ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
2301352ff8bdSFrançois Tigeot s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH(i));
2302ba55f2f5SFrançois Tigeot
2303ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */
2304ba55f2f5SFrançois Tigeot s->tilectl = I915_READ(TILECTL);
2305ba55f2f5SFrançois Tigeot s->gt_fifoctl = I915_READ(GTFIFOCTL);
2306ba55f2f5SFrançois Tigeot s->gtlc_wake_ctrl = I915_READ(VLV_GTLC_WAKE_CTRL);
2307ba55f2f5SFrançois Tigeot s->gtlc_survive = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
2308ba55f2f5SFrançois Tigeot s->pmwgicz = I915_READ(VLV_PMWGICZ);
2309ba55f2f5SFrançois Tigeot
2310ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */
2311ba55f2f5SFrançois Tigeot s->gu_ctl0 = I915_READ(VLV_GU_CTL0);
2312ba55f2f5SFrançois Tigeot s->gu_ctl1 = I915_READ(VLV_GU_CTL1);
23132c9916cdSFrançois Tigeot s->pcbr = I915_READ(VLV_PCBR);
2314ba55f2f5SFrançois Tigeot s->clock_gate_dis2 = I915_READ(VLV_GUNIT_CLOCK_GATE2);
2315ba55f2f5SFrançois Tigeot
2316ba55f2f5SFrançois Tigeot /*
2317ba55f2f5SFrançois Tigeot * Not saving any of:
2318ba55f2f5SFrançois Tigeot * DFT, 0x9800-0x9EC0
2319ba55f2f5SFrançois Tigeot * SARB, 0xB000-0xB1FC
2320ba55f2f5SFrançois Tigeot * GAC, 0x5208-0x524C, 0x14000-0x14C000
2321ba55f2f5SFrançois Tigeot * PCI CFG
2322ba55f2f5SFrançois Tigeot */
2323ba55f2f5SFrançois Tigeot }
2324ba55f2f5SFrançois Tigeot
2325ba55f2f5SFrançois Tigeot static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
2326ba55f2f5SFrançois Tigeot {
2327ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state;
2328ba55f2f5SFrançois Tigeot u32 val;
2329ba55f2f5SFrançois Tigeot int i;
2330ba55f2f5SFrançois Tigeot
2331ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */
2332ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_WR_WATERMARK, s->wr_watermark);
2333ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PRIO_CTRL, s->gfx_prio_ctrl);
2334ba55f2f5SFrançois Tigeot I915_WRITE(ARB_MODE, s->arb_mode | (0xffff << 16));
2335ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB0, s->gfx_pend_tlb0);
2336ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB1, s->gfx_pend_tlb1);
2337ba55f2f5SFrançois Tigeot
2338ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++)
2339352ff8bdSFrançois Tigeot I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]);
2340ba55f2f5SFrançois Tigeot
2341ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count);
2342477eb7f9SFrançois Tigeot I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count);
2343ba55f2f5SFrançois Tigeot
2344ba55f2f5SFrançois Tigeot I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp);
2345ba55f2f5SFrançois Tigeot I915_WRITE(GAM_ECOCHK, s->ecochk);
2346ba55f2f5SFrançois Tigeot I915_WRITE(BSD_HWS_PGA_GEN7, s->bsd_hwsp);
2347ba55f2f5SFrançois Tigeot I915_WRITE(BLT_HWS_PGA_GEN7, s->blt_hwsp);
2348ba55f2f5SFrançois Tigeot
2349ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_TLB_RD_ADDR, s->tlb_rd_addr);
2350ba55f2f5SFrançois Tigeot
2351ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */
2352ba55f2f5SFrançois Tigeot I915_WRITE(VLV_G3DCTL, s->g3dctl);
2353ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GSCKGCTL, s->gsckgctl);
2354ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_MBCTL, s->mbctl);
2355ba55f2f5SFrançois Tigeot
2356ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */
2357ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL1, s->ucgctl1);
2358ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL3, s->ucgctl3);
2359ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL1, s->rcgctl1);
2360ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL2, s->rcgctl2);
2361ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RSTCTL, s->rstctl);
2362ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MISCCPCTL, s->misccpctl);
2363ba55f2f5SFrançois Tigeot
2364ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */
2365ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_GFXPAUSE, s->gfxpause);
2366ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUHWTC, s->rpdeuhwtc);
2367ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUC, s->rpdeuc);
2368ba55f2f5SFrançois Tigeot I915_WRITE(ECOBUS, s->ecobus);
2369ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PWRDWNUPCTL, s->pwrdwnupctl);
2370ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RP_DOWN_TIMEOUT,s->rp_down_timeout);
2371ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUCSW, s->rp_deucsw);
2372ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCUBMABDTMR, s->rcubmabdtmr);
2373ba55f2f5SFrançois Tigeot I915_WRITE(VLV_RCEDATA, s->rcedata);
2374ba55f2f5SFrançois Tigeot I915_WRITE(VLV_SPAREG2H, s->spare2gh);
2375ba55f2f5SFrançois Tigeot
2376ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */
2377ba55f2f5SFrançois Tigeot I915_WRITE(GTIMR, s->gt_imr);
2378ba55f2f5SFrançois Tigeot I915_WRITE(GTIER, s->gt_ier);
2379ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIMR, s->pm_imr);
2380ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIER, s->pm_ier);
2381ba55f2f5SFrançois Tigeot
2382ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++)
2383352ff8bdSFrançois Tigeot I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]);
2384ba55f2f5SFrançois Tigeot
2385ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */
2386ba55f2f5SFrançois Tigeot I915_WRITE(TILECTL, s->tilectl);
2387ba55f2f5SFrançois Tigeot I915_WRITE(GTFIFOCTL, s->gt_fifoctl);
2388ba55f2f5SFrançois Tigeot /*
2389ba55f2f5SFrançois Tigeot * Preserve the GT allow wake and GFX force clock bit, they are not
2390ba55f2f5SFrançois Tigeot * be restored, as they are used to control the s0ix suspend/resume
2391ba55f2f5SFrançois Tigeot * sequence by the caller.
2392ba55f2f5SFrançois Tigeot */
2393ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL);
2394ba55f2f5SFrançois Tigeot val &= VLV_GTLC_ALLOWWAKEREQ;
2395ba55f2f5SFrançois Tigeot val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ;
2396ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val);
2397ba55f2f5SFrançois Tigeot
2398ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
2399ba55f2f5SFrançois Tigeot val &= VLV_GFX_CLK_FORCE_ON_BIT;
2400ba55f2f5SFrançois Tigeot val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT;
2401ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val);
2402ba55f2f5SFrançois Tigeot
2403ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PMWGICZ, s->pmwgicz);
2404ba55f2f5SFrançois Tigeot
2405ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */
2406ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL0, s->gu_ctl0);
2407ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL1, s->gu_ctl1);
24082c9916cdSFrançois Tigeot I915_WRITE(VLV_PCBR, s->pcbr);
2409ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GUNIT_CLOCK_GATE2, s->clock_gate_dis2);
2410ba55f2f5SFrançois Tigeot }
2411ba55f2f5SFrançois Tigeot
2412a85cb24fSFrançois Tigeot static int vlv_wait_for_pw_status(struct drm_i915_private *dev_priv,
2413a85cb24fSFrançois Tigeot u32 mask, u32 val)
2414a85cb24fSFrançois Tigeot {
2415a85cb24fSFrançois Tigeot /* The HW does not like us polling for PW_STATUS frequently, so
2416a85cb24fSFrançois Tigeot * use the sleeping loop rather than risk the busy spin within
2417a85cb24fSFrançois Tigeot * intel_wait_for_register().
2418a85cb24fSFrançois Tigeot *
2419a85cb24fSFrançois Tigeot * Transitioning between RC6 states should be at most 2ms (see
2420a85cb24fSFrançois Tigeot * valleyview_enable_rps) so use a 3ms timeout.
2421a85cb24fSFrançois Tigeot */
2422a85cb24fSFrançois Tigeot return wait_for((I915_READ_NOTRACE(VLV_GTLC_PW_STATUS) & mask) == val,
2423a85cb24fSFrançois Tigeot 3);
2424a85cb24fSFrançois Tigeot }
2425a85cb24fSFrançois Tigeot #endif
2426a85cb24fSFrançois Tigeot
vlv_force_gfx_clock(struct drm_i915_private * dev_priv,bool force_on)2427ba55f2f5SFrançois Tigeot int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
2428ba55f2f5SFrançois Tigeot {
2429ba55f2f5SFrançois Tigeot u32 val;
2430ba55f2f5SFrançois Tigeot int err;
2431ba55f2f5SFrançois Tigeot
2432ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG);
2433ba55f2f5SFrançois Tigeot val &= ~VLV_GFX_CLK_FORCE_ON_BIT;
2434ba55f2f5SFrançois Tigeot if (force_on)
2435ba55f2f5SFrançois Tigeot val |= VLV_GFX_CLK_FORCE_ON_BIT;
2436ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val);
2437ba55f2f5SFrançois Tigeot
2438ba55f2f5SFrançois Tigeot if (!force_on)
2439ba55f2f5SFrançois Tigeot return 0;
2440ba55f2f5SFrançois Tigeot
24411487f786SFrançois Tigeot err = intel_wait_for_register(dev_priv,
24421487f786SFrançois Tigeot VLV_GTLC_SURVIVABILITY_REG,
24431487f786SFrançois Tigeot VLV_GFX_CLK_STATUS_BIT,
24441487f786SFrançois Tigeot VLV_GFX_CLK_STATUS_BIT,
24451487f786SFrançois Tigeot 20);
2446ba55f2f5SFrançois Tigeot if (err)
2447ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n",
2448ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_SURVIVABILITY_REG));
2449ba55f2f5SFrançois Tigeot
2450ba55f2f5SFrançois Tigeot return err;
2451ba55f2f5SFrançois Tigeot }
2452ba55f2f5SFrançois Tigeot
2453a85cb24fSFrançois Tigeot #if 0
2454ba55f2f5SFrançois Tigeot static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow)
2455ba55f2f5SFrançois Tigeot {
2456a85cb24fSFrançois Tigeot u32 mask;
2457ba55f2f5SFrançois Tigeot u32 val;
2458a85cb24fSFrançois Tigeot int err;
2459ba55f2f5SFrançois Tigeot
2460ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL);
2461ba55f2f5SFrançois Tigeot val &= ~VLV_GTLC_ALLOWWAKEREQ;
2462ba55f2f5SFrançois Tigeot if (allow)
2463ba55f2f5SFrançois Tigeot val |= VLV_GTLC_ALLOWWAKEREQ;
2464ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val);
2465ba55f2f5SFrançois Tigeot POSTING_READ(VLV_GTLC_WAKE_CTRL);
2466ba55f2f5SFrançois Tigeot
2467a85cb24fSFrançois Tigeot mask = VLV_GTLC_ALLOWWAKEACK;
2468a85cb24fSFrançois Tigeot val = allow ? mask : 0;
2469a85cb24fSFrançois Tigeot
2470a85cb24fSFrançois Tigeot err = vlv_wait_for_pw_status(dev_priv, mask, val);
2471ba55f2f5SFrançois Tigeot if (err)
2472ba55f2f5SFrançois Tigeot DRM_ERROR("timeout disabling GT waking\n");
24731487f786SFrançois Tigeot
2474ba55f2f5SFrançois Tigeot return err;
2475ba55f2f5SFrançois Tigeot }
2476ba55f2f5SFrançois Tigeot
2477a85cb24fSFrançois Tigeot static void vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv,
2478ba55f2f5SFrançois Tigeot bool wait_for_on)
2479ba55f2f5SFrançois Tigeot {
2480ba55f2f5SFrançois Tigeot u32 mask;
2481ba55f2f5SFrançois Tigeot u32 val;
2482ba55f2f5SFrançois Tigeot
2483ba55f2f5SFrançois Tigeot mask = VLV_GTLC_PW_MEDIA_STATUS_MASK | VLV_GTLC_PW_RENDER_STATUS_MASK;
2484ba55f2f5SFrançois Tigeot val = wait_for_on ? mask : 0;
2485ba55f2f5SFrançois Tigeot
2486ba55f2f5SFrançois Tigeot /*
2487ba55f2f5SFrançois Tigeot * RC6 transitioning can be delayed up to 2 msec (see
2488ba55f2f5SFrançois Tigeot * valleyview_enable_rps), use 3 msec for safety.
2489ba55f2f5SFrançois Tigeot */
2490a85cb24fSFrançois Tigeot if (vlv_wait_for_pw_status(dev_priv, mask, val))
2491ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GT wells to go %s\n",
2492c0e85e96SFrançois Tigeot onoff(wait_for_on));
2493ba55f2f5SFrançois Tigeot }
2494ba55f2f5SFrançois Tigeot
2495ba55f2f5SFrançois Tigeot static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv)
2496ba55f2f5SFrançois Tigeot {
2497ba55f2f5SFrançois Tigeot if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR))
2498ba55f2f5SFrançois Tigeot return;
2499ba55f2f5SFrançois Tigeot
2500c0e85e96SFrançois Tigeot DRM_DEBUG_DRIVER("GT register access while GT waking disabled\n");
2501ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR);
2502ba55f2f5SFrançois Tigeot }
2503ba55f2f5SFrançois Tigeot
25041b13d190SFrançois Tigeot static int vlv_suspend_complete(struct drm_i915_private *dev_priv)
2505ba55f2f5SFrançois Tigeot {
2506ba55f2f5SFrançois Tigeot u32 mask;
2507ba55f2f5SFrançois Tigeot int err;
2508ba55f2f5SFrançois Tigeot
2509ba55f2f5SFrançois Tigeot /*
2510ba55f2f5SFrançois Tigeot * Bspec defines the following GT well on flags as debug only, so
2511ba55f2f5SFrançois Tigeot * don't treat them as hard failures.
2512ba55f2f5SFrançois Tigeot */
2513a85cb24fSFrançois Tigeot vlv_wait_for_gt_wells(dev_priv, false);
2514ba55f2f5SFrançois Tigeot
2515ba55f2f5SFrançois Tigeot mask = VLV_GTLC_RENDER_CTX_EXISTS | VLV_GTLC_MEDIA_CTX_EXISTS;
2516ba55f2f5SFrançois Tigeot WARN_ON((I915_READ(VLV_GTLC_WAKE_CTRL) & mask) != mask);
2517ba55f2f5SFrançois Tigeot
2518ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv);
2519ba55f2f5SFrançois Tigeot
2520ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, true);
2521ba55f2f5SFrançois Tigeot if (err)
2522ba55f2f5SFrançois Tigeot goto err1;
2523ba55f2f5SFrançois Tigeot
2524ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, false);
2525ba55f2f5SFrançois Tigeot if (err)
2526ba55f2f5SFrançois Tigeot goto err2;
25272c9916cdSFrançois Tigeot
25288621f407SFrançois Tigeot if (!IS_CHERRYVIEW(dev_priv))
2529ba55f2f5SFrançois Tigeot vlv_save_gunit_s0ix_state(dev_priv);
2530ba55f2f5SFrançois Tigeot
2531ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false);
2532ba55f2f5SFrançois Tigeot if (err)
2533ba55f2f5SFrançois Tigeot goto err2;
2534ba55f2f5SFrançois Tigeot
2535ba55f2f5SFrançois Tigeot return 0;
2536ba55f2f5SFrançois Tigeot
2537ba55f2f5SFrançois Tigeot err2:
2538ba55f2f5SFrançois Tigeot /* For safety always re-enable waking and disable gfx clock forcing */
2539ba55f2f5SFrançois Tigeot vlv_allow_gt_wake(dev_priv, true);
2540ba55f2f5SFrançois Tigeot err1:
2541ba55f2f5SFrançois Tigeot vlv_force_gfx_clock(dev_priv, false);
2542ba55f2f5SFrançois Tigeot
2543ba55f2f5SFrançois Tigeot return err;
2544ba55f2f5SFrançois Tigeot }
2545ba55f2f5SFrançois Tigeot
25461b13d190SFrançois Tigeot static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
25471b13d190SFrançois Tigeot bool rpm_resume)
2548ba55f2f5SFrançois Tigeot {
2549ba55f2f5SFrançois Tigeot int err;
2550ba55f2f5SFrançois Tigeot int ret;
2551ba55f2f5SFrançois Tigeot
2552ba55f2f5SFrançois Tigeot /*
2553ba55f2f5SFrançois Tigeot * If any of the steps fail just try to continue, that's the best we
2554ba55f2f5SFrançois Tigeot * can do at this point. Return the first error code (which will also
2555ba55f2f5SFrançois Tigeot * leave RPM permanently disabled).
2556ba55f2f5SFrançois Tigeot */
2557ba55f2f5SFrançois Tigeot ret = vlv_force_gfx_clock(dev_priv, true);
2558ba55f2f5SFrançois Tigeot
25598621f407SFrançois Tigeot if (!IS_CHERRYVIEW(dev_priv))
2560ba55f2f5SFrançois Tigeot vlv_restore_gunit_s0ix_state(dev_priv);
2561ba55f2f5SFrançois Tigeot
2562ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, true);
2563ba55f2f5SFrançois Tigeot if (!ret)
2564ba55f2f5SFrançois Tigeot ret = err;
2565ba55f2f5SFrançois Tigeot
2566ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false);
2567ba55f2f5SFrançois Tigeot if (!ret)
2568ba55f2f5SFrançois Tigeot ret = err;
2569ba55f2f5SFrançois Tigeot
2570ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv);
2571ba55f2f5SFrançois Tigeot
25724be47400SFrançois Tigeot if (rpm_resume)
25734be47400SFrançois Tigeot intel_init_clock_gating(dev_priv);
2574ba55f2f5SFrançois Tigeot
2575ba55f2f5SFrançois Tigeot return ret;
2576ba55f2f5SFrançois Tigeot }
2577ba55f2f5SFrançois Tigeot
2578a85cb24fSFrançois Tigeot static int intel_runtime_suspend(struct device *kdev)
25799edbd4a0SFrançois Tigeot {
2580a85cb24fSFrançois Tigeot struct pci_dev *pdev = to_pci_dev(kdev);
25819edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev);
2582303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
2583ba55f2f5SFrançois Tigeot int ret;
2584ba55f2f5SFrançois Tigeot
2585*3f2dd94aSFrançois Tigeot if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && intel_rc6_enabled())))
2586ba55f2f5SFrançois Tigeot return -ENODEV;
25879edbd4a0SFrançois Tigeot
25881e12ee3bSFrançois Tigeot if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
25891b13d190SFrançois Tigeot return -ENODEV;
25901b13d190SFrançois Tigeot
25919edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Suspending device\n");
25929edbd4a0SFrançois Tigeot
2593aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
2594aee94f86SFrançois Tigeot
2595ba55f2f5SFrançois Tigeot /*
2596ba55f2f5SFrançois Tigeot * We are safe here against re-faults, since the fault handler takes
2597ba55f2f5SFrançois Tigeot * an RPM reference.
2598ba55f2f5SFrançois Tigeot */
25994be47400SFrançois Tigeot i915_gem_runtime_suspend(dev_priv);
2600ba55f2f5SFrançois Tigeot
2601a85cb24fSFrançois Tigeot intel_guc_suspend(dev_priv);
2602352ff8bdSFrançois Tigeot
26032c9916cdSFrançois Tigeot intel_runtime_pm_disable_interrupts(dev_priv);
2604ba55f2f5SFrançois Tigeot
26058621f407SFrançois Tigeot ret = 0;
2606a85cb24fSFrançois Tigeot if (IS_GEN9_LP(dev_priv)) {
26078621f407SFrançois Tigeot bxt_display_core_uninit(dev_priv);
26088621f407SFrançois Tigeot bxt_enable_dc9(dev_priv);
26098621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
26108621f407SFrançois Tigeot hsw_enable_pc8(dev_priv);
26118621f407SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
26128621f407SFrançois Tigeot ret = vlv_suspend_complete(dev_priv);
26138621f407SFrançois Tigeot }
26148621f407SFrançois Tigeot
2615ba55f2f5SFrançois Tigeot if (ret) {
2616ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret);
26172c9916cdSFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv);
2618ba55f2f5SFrançois Tigeot
2619aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
2620aee94f86SFrançois Tigeot
2621ba55f2f5SFrançois Tigeot return ret;
2622ba55f2f5SFrançois Tigeot }
26239edbd4a0SFrançois Tigeot
2624a85cb24fSFrançois Tigeot intel_uncore_suspend(dev_priv);
2625aee94f86SFrançois Tigeot
2626aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
2627*3f2dd94aSFrançois Tigeot WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count));
2628c0e85e96SFrançois Tigeot
2629c0e85e96SFrançois Tigeot if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv))
2630c0e85e96SFrançois Tigeot DRM_ERROR("Unclaimed access detected prior to suspending\n");
2631c0e85e96SFrançois Tigeot
2632*3f2dd94aSFrançois Tigeot dev_priv->runtime_pm.suspended = true;
26339edbd4a0SFrançois Tigeot
26349edbd4a0SFrançois Tigeot /*
26351b13d190SFrançois Tigeot * FIXME: We really should find a document that references the arguments
26361b13d190SFrançois Tigeot * used below!
26371b13d190SFrançois Tigeot */
26381487f786SFrançois Tigeot if (IS_BROADWELL(dev_priv)) {
2639a05eeebfSFrançois Tigeot /*
2640a05eeebfSFrançois Tigeot * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop
2641a05eeebfSFrançois Tigeot * being detected, and the call we do at intel_runtime_resume()
2642a05eeebfSFrançois Tigeot * won't be able to restore them. Since PCI_D3hot matches the
2643a05eeebfSFrançois Tigeot * actual specification and appears to be working, use it.
2644a05eeebfSFrançois Tigeot */
26451487f786SFrançois Tigeot intel_opregion_notify_adapter(dev_priv, PCI_D3hot);
2646a05eeebfSFrançois Tigeot } else {
26471b13d190SFrançois Tigeot /*
26489edbd4a0SFrançois Tigeot * current versions of firmware which depend on this opregion
26499edbd4a0SFrançois Tigeot * notification have repurposed the D1 definition to mean
26509edbd4a0SFrançois Tigeot * "runtime suspended" vs. what you would normally expect (D3)
26511b13d190SFrançois Tigeot * to distinguish it from notifications that might be sent via
26521b13d190SFrançois Tigeot * the suspend path.
26539edbd4a0SFrançois Tigeot */
26541487f786SFrançois Tigeot intel_opregion_notify_adapter(dev_priv, PCI_D1);
26551b13d190SFrançois Tigeot }
26569edbd4a0SFrançois Tigeot
26572c9916cdSFrançois Tigeot assert_forcewakes_inactive(dev_priv);
26582c9916cdSFrançois Tigeot
26594be47400SFrançois Tigeot if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
2660bf017597SFrançois Tigeot intel_hpd_poll_init(dev_priv);
2661bf017597SFrançois Tigeot
2662ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device suspended\n");
26639edbd4a0SFrançois Tigeot return 0;
26649edbd4a0SFrançois Tigeot }
26659edbd4a0SFrançois Tigeot
26661e12ee3bSFrançois Tigeot static int intel_runtime_resume(struct device *kdev)
26679edbd4a0SFrançois Tigeot {
26681e12ee3bSFrançois Tigeot struct pci_dev *pdev = to_pci_dev(kdev);
26699edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev);
2670303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev);
26712c9916cdSFrançois Tigeot int ret = 0;
26729edbd4a0SFrançois Tigeot
26731e12ee3bSFrançois Tigeot if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
26741b13d190SFrançois Tigeot return -ENODEV;
26759edbd4a0SFrançois Tigeot
26769edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Resuming device\n");
26779edbd4a0SFrançois Tigeot
2678*3f2dd94aSFrançois Tigeot WARN_ON_ONCE(atomic_read(&dev_priv->runtime_pm.wakeref_count));
2679aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv);
2680aee94f86SFrançois Tigeot
26811487f786SFrançois Tigeot intel_opregion_notify_adapter(dev_priv, PCI_D0);
2682*3f2dd94aSFrançois Tigeot dev_priv->runtime_pm.suspended = false;
2683c0e85e96SFrançois Tigeot if (intel_uncore_unclaimed_mmio(dev_priv))
2684c0e85e96SFrançois Tigeot DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
26859edbd4a0SFrançois Tigeot
2686a85cb24fSFrançois Tigeot intel_guc_resume(dev_priv);
2687352ff8bdSFrançois Tigeot
2688a85cb24fSFrançois Tigeot if (IS_GEN9_LP(dev_priv)) {
26898621f407SFrançois Tigeot bxt_disable_dc9(dev_priv);
26908621f407SFrançois Tigeot bxt_display_core_init(dev_priv, true);
26918621f407SFrançois Tigeot if (dev_priv->csr.dmc_payload &&
26928621f407SFrançois Tigeot (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5))
26938621f407SFrançois Tigeot gen9_enable_dc5(dev_priv);
26948621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
26952c9916cdSFrançois Tigeot hsw_disable_pc8(dev_priv);
26968621f407SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
26972c9916cdSFrançois Tigeot ret = vlv_resume_prepare(dev_priv, true);
26988621f407SFrançois Tigeot }
26992c9916cdSFrançois Tigeot
2700*3f2dd94aSFrançois Tigeot intel_uncore_runtime_resume(dev_priv);
2701*3f2dd94aSFrançois Tigeot
2702ba55f2f5SFrançois Tigeot /*
2703ba55f2f5SFrançois Tigeot * No point of rolling back things in case of an error, as the best
2704ba55f2f5SFrançois Tigeot * we can do is to hope that things will still work (and disable RPM).
2705ba55f2f5SFrançois Tigeot */
27064be47400SFrançois Tigeot i915_gem_init_swizzling(dev_priv);
27074be47400SFrançois Tigeot i915_gem_restore_fences(dev_priv);
2708ba55f2f5SFrançois Tigeot
27092c9916cdSFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv);
2710352ff8bdSFrançois Tigeot
2711352ff8bdSFrançois Tigeot /*
2712352ff8bdSFrançois Tigeot * On VLV/CHV display interrupts are part of the display
2713352ff8bdSFrançois Tigeot * power well, so hpd is reinitialized from there. For
2714352ff8bdSFrançois Tigeot * everyone else do it here.
2715352ff8bdSFrançois Tigeot */
2716aee94f86SFrançois Tigeot if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
2717352ff8bdSFrançois Tigeot intel_hpd_init(dev_priv);
2718352ff8bdSFrançois Tigeot
2719*3f2dd94aSFrançois Tigeot intel_enable_ipc(dev_priv);
2720*3f2dd94aSFrançois Tigeot
2721aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv);
2722aee94f86SFrançois Tigeot
2723ba55f2f5SFrançois Tigeot if (ret)
2724ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret);
2725ba55f2f5SFrançois Tigeot else
2726ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device resumed\n");
2727ba55f2f5SFrançois Tigeot
2728ba55f2f5SFrançois Tigeot return ret;
27299edbd4a0SFrançois Tigeot }
27309edbd4a0SFrançois Tigeot
27311487f786SFrançois Tigeot const struct dev_pm_ops i915_pm_ops = {
27322c9916cdSFrançois Tigeot /*
27332c9916cdSFrançois Tigeot * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
27342c9916cdSFrançois Tigeot * PMSG_RESUME]
27352c9916cdSFrançois Tigeot */
27369edbd4a0SFrançois Tigeot .suspend = i915_pm_suspend,
27372c9916cdSFrançois Tigeot .suspend_late = i915_pm_suspend_late,
27382c9916cdSFrançois Tigeot .resume_early = i915_pm_resume_early,
27399edbd4a0SFrançois Tigeot .resume = i915_pm_resume,
27402c9916cdSFrançois Tigeot
27412c9916cdSFrançois Tigeot /*
27422c9916cdSFrançois Tigeot * S4 event handlers
27432c9916cdSFrançois Tigeot * @freeze, @freeze_late : called (1) before creating the
27442c9916cdSFrançois Tigeot * hibernation image [PMSG_FREEZE] and
27452c9916cdSFrançois Tigeot * (2) after rebooting, before restoring
27462c9916cdSFrançois Tigeot * the image [PMSG_QUIESCE]
27472c9916cdSFrançois Tigeot * @thaw, @thaw_early : called (1) after creating the hibernation
27482c9916cdSFrançois Tigeot * image, before writing it [PMSG_THAW]
27492c9916cdSFrançois Tigeot * and (2) after failing to create or
27502c9916cdSFrançois Tigeot * restore the image [PMSG_RECOVER]
27512c9916cdSFrançois Tigeot * @poweroff, @poweroff_late: called after writing the hibernation
27522c9916cdSFrançois Tigeot * image, before rebooting [PMSG_HIBERNATE]
27532c9916cdSFrançois Tigeot * @restore, @restore_early : called after rebooting and restoring the
27542c9916cdSFrançois Tigeot * hibernation image [PMSG_RESTORE]
27552c9916cdSFrançois Tigeot */
27561487f786SFrançois Tigeot .freeze = i915_pm_freeze,
27571487f786SFrançois Tigeot .freeze_late = i915_pm_freeze_late,
27581487f786SFrançois Tigeot .thaw_early = i915_pm_thaw_early,
27591487f786SFrançois Tigeot .thaw = i915_pm_thaw,
27602c9916cdSFrançois Tigeot .poweroff = i915_pm_suspend,
27612c9916cdSFrançois Tigeot .poweroff_late = i915_pm_poweroff_late,
27621487f786SFrançois Tigeot .restore_early = i915_pm_restore_early,
27631487f786SFrançois Tigeot .restore = i915_pm_restore,
27642c9916cdSFrançois Tigeot
27652c9916cdSFrançois Tigeot /* S0ix (via runtime suspend) event handlers */
2766ba55f2f5SFrançois Tigeot .runtime_suspend = intel_runtime_suspend,
2767ba55f2f5SFrançois Tigeot .runtime_resume = intel_runtime_resume,
27689edbd4a0SFrançois Tigeot };
27699edbd4a0SFrançois Tigeot
27709edbd4a0SFrançois Tigeot static const struct vm_operations_struct i915_gem_vm_ops = {
27719edbd4a0SFrançois Tigeot .fault = i915_gem_fault,
27729edbd4a0SFrançois Tigeot .open = drm_gem_vm_open,
27739edbd4a0SFrançois Tigeot .close = drm_gem_vm_close,
27749edbd4a0SFrançois Tigeot };
2775922e7c40SFrançois Tigeot #endif
27769edbd4a0SFrançois Tigeot
2777bf017597SFrançois Tigeot static struct cdev_pager_ops i915_gem_vm_ops = {
2778bf017597SFrançois Tigeot .cdev_pg_fault = i915_gem_fault,
2779bf017597SFrançois Tigeot .cdev_pg_ctor = i915_gem_pager_ctor,
2780bf017597SFrançois Tigeot .cdev_pg_dtor = i915_gem_pager_dtor
2781bf017597SFrançois Tigeot };
2782bf017597SFrançois Tigeot
27839edbd4a0SFrançois Tigeot static const struct file_operations i915_driver_fops = {
27849edbd4a0SFrançois Tigeot .owner = THIS_MODULE,
2785922e7c40SFrançois Tigeot #if 0
27869edbd4a0SFrançois Tigeot .open = drm_open,
27879edbd4a0SFrançois Tigeot .release = drm_release,
27889edbd4a0SFrançois Tigeot .unlocked_ioctl = drm_ioctl,
27899edbd4a0SFrançois Tigeot .mmap = drm_gem_mmap,
27909edbd4a0SFrançois Tigeot .poll = drm_poll,
27919edbd4a0SFrançois Tigeot .read = drm_read,
27929edbd4a0SFrançois Tigeot .compat_ioctl = i915_compat_ioctl,
27939edbd4a0SFrançois Tigeot .llseek = noop_llseek,
27949edbd4a0SFrançois Tigeot #endif
2795922e7c40SFrançois Tigeot };
27969edbd4a0SFrançois Tigeot
27971487f786SFrançois Tigeot static int
i915_gem_reject_pin_ioctl(struct drm_device * dev,void * data,struct drm_file * file)27981487f786SFrançois Tigeot i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
27991487f786SFrançois Tigeot struct drm_file *file)
28001487f786SFrançois Tigeot {
28011487f786SFrançois Tigeot return -ENODEV;
28021487f786SFrançois Tigeot }
28031487f786SFrançois Tigeot
28041487f786SFrançois Tigeot static const struct drm_ioctl_desc i915_ioctls[] = {
28051487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28061487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH),
28071487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH),
28081487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH),
28091487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH),
28101487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH),
28111487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW),
28121487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_SETPARAM, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28131487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
28141487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
28151487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28161487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH),
28171487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28181487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28191487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, drm_noop, DRM_AUTH),
28201487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
28211487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28221487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28231487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
2824a85cb24fSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
28251487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
28261487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
28271487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
28281487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW),
28291487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW),
28301487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
28311487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28321487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
28331487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
28341487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
28351487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
28361487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
28371487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
28381487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
28391487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
2840a85cb24fSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
2841a85cb24fSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW),
28421487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
28431487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
28441487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
28451487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
28461487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
28471487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
28481487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
28491487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
28501487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
28511487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
28521487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
28531487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
28541487f786SFrançois Tigeot #if 0
28551487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
28561487f786SFrançois Tigeot #endif
28571487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
28581487f786SFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
2859a85cb24fSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
2860*3f2dd94aSFrançois Tigeot #if 0
2861*3f2dd94aSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
2862*3f2dd94aSFrançois Tigeot DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
2863*3f2dd94aSFrançois Tigeot #endif
28641487f786SFrançois Tigeot };
28651487f786SFrançois Tigeot
i915_sysctl_init(struct drm_device * dev,struct sysctl_ctx_list * ctx,struct sysctl_oid * top)2866bf017597SFrançois Tigeot static int i915_sysctl_init(struct drm_device *dev, struct sysctl_ctx_list *ctx,
2867bf017597SFrançois Tigeot struct sysctl_oid *top)
2868bf017597SFrançois Tigeot {
2869bf017597SFrançois Tigeot return drm_add_busid_modesetting(dev, ctx, top);
2870bf017597SFrançois Tigeot }
2871bf017597SFrançois Tigeot
2872f0b54121SFrançois Tigeot static struct drm_driver driver = {
28739edbd4a0SFrançois Tigeot /* Don't use MTRRs here; the Xserver or userspace app should
28749edbd4a0SFrançois Tigeot * deal with them for Intel hardware.
28759edbd4a0SFrançois Tigeot */
28769edbd4a0SFrançois Tigeot .driver_features =
2877*3f2dd94aSFrançois Tigeot DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
2878*3f2dd94aSFrançois Tigeot DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ,
2879a85cb24fSFrançois Tigeot .release = i915_driver_release,
2880ba55f2f5SFrançois Tigeot .open = i915_driver_open,
288179f713b0SFrançois Tigeot .lastclose = i915_driver_lastclose,
2882f0b54121SFrançois Tigeot .postclose = i915_driver_postclose,
2883ba55f2f5SFrançois Tigeot
288471f41f3eSFrançois Tigeot .gem_close_object = i915_gem_close_object,
28854be47400SFrançois Tigeot .gem_free_object_unlocked = i915_gem_free_object,
2886d4d73b30SFrançois Tigeot .gem_vm_ops = &i915_gem_vm_ops,
28872c9916cdSFrançois Tigeot
2888922e7c40SFrançois Tigeot .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
2889922e7c40SFrançois Tigeot .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
2890922e7c40SFrançois Tigeot .gem_prime_export = i915_gem_prime_export,
2891922e7c40SFrançois Tigeot .gem_prime_import = i915_gem_prime_import,
2892922e7c40SFrançois Tigeot
2893f0b54121SFrançois Tigeot .dumb_create = i915_gem_dumb_create,
2894f0b54121SFrançois Tigeot .dumb_map_offset = i915_gem_mmap_gtt,
2895f0b54121SFrançois Tigeot .ioctls = i915_ioctls,
28961487f786SFrançois Tigeot .num_ioctls = ARRAY_SIZE(i915_ioctls),
2897922e7c40SFrançois Tigeot .fops = &i915_driver_fops,
2898f0b54121SFrançois Tigeot .name = DRIVER_NAME,
2899f0b54121SFrançois Tigeot .desc = DRIVER_DESC,
2900f0b54121SFrançois Tigeot .date = DRIVER_DATE,
2901f0b54121SFrançois Tigeot .major = DRIVER_MAJOR,
2902f0b54121SFrançois Tigeot .minor = DRIVER_MINOR,
2903f0b54121SFrançois Tigeot .patchlevel = DRIVER_PATCHLEVEL,
29041487f786SFrançois Tigeot #ifdef __DragonFly__
2905*3f2dd94aSFrançois Tigeot .sysctl_init = i915_sysctl_init,
2906*3f2dd94aSFrançois Tigeot #endif
2907*3f2dd94aSFrançois Tigeot };
2908a85cb24fSFrançois Tigeot
2909a85cb24fSFrançois Tigeot #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
2910a85cb24fSFrançois Tigeot #include "selftests/mock_drm.c"
2911a85cb24fSFrançois Tigeot #endif
2912