1235783Skib/* i915_drv.c -- Intel i915 driver -*- linux-c -*-
2235783Skib * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
3235783Skib */
4235783Skib/*-
5235783Skib * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6235783Skib * All Rights Reserved.
7235783Skib *
8235783Skib * Permission is hereby granted, free of charge, to any person obtaining a
9235783Skib * copy of this software and associated documentation files (the "Software"),
10235783Skib * to deal in the Software without restriction, including without limitation
11235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12235783Skib * and/or sell copies of the Software, and to permit persons to whom the
13235783Skib * Software is furnished to do so, subject to the following conditions:
14235783Skib *
15235783Skib * The above copyright notice and this permission notice (including the next
16235783Skib * paragraph) shall be included in all copies or substantial portions of the
17235783Skib * Software.
18235783Skib *
19235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22235783Skib * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23235783Skib * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24235783Skib * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25235783Skib * OTHER DEALINGS IN THE SOFTWARE.
26235783Skib *
27235783Skib * Authors:
28235783Skib *    Gareth Hughes <gareth@valinux.com>
29235783Skib *
30235783Skib */
31235783Skib
32235783Skib#include <sys/cdefs.h>
33235783Skib__FBSDID("$FreeBSD: releng/10.3/sys/dev/drm2/i915/i915_drv.c 282199 2015-04-28 19:35:05Z dumbbell $");
34235783Skib
35235783Skib#include <dev/drm2/drmP.h>
36235783Skib#include <dev/drm2/drm.h>
37235783Skib#include <dev/drm2/drm_mm.h>
38235783Skib#include <dev/drm2/i915/i915_drm.h>
39235783Skib#include <dev/drm2/i915/i915_drv.h>
40235783Skib#include <dev/drm2/drm_pciids.h>
41235783Skib#include <dev/drm2/i915/intel_drv.h>
42235783Skib
43262861Sjhb#include "fb_if.h"
44262861Sjhb
45235783Skib/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
46235783Skibstatic drm_pci_id_list_t i915_pciidlist[] = {
47235783Skib	i915_PCI_IDS
48235783Skib};
49235783Skib
50235783Skibstatic const struct intel_device_info intel_i830_info = {
51235783Skib	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1,
52235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
53235783Skib};
54235783Skib
55235783Skibstatic const struct intel_device_info intel_845g_info = {
56235783Skib	.gen = 2,
57235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
58235783Skib};
59235783Skib
60235783Skibstatic const struct intel_device_info intel_i85x_info = {
61235783Skib	.gen = 2, .is_i85x = 1, .is_mobile = 1,
62235783Skib	.cursor_needs_physical = 1,
63235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
64235783Skib};
65235783Skib
66235783Skibstatic const struct intel_device_info intel_i865g_info = {
67235783Skib	.gen = 2,
68235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
69235783Skib};
70235783Skib
71235783Skibstatic const struct intel_device_info intel_i915g_info = {
72235783Skib	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
73235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
74235783Skib};
75235783Skibstatic const struct intel_device_info intel_i915gm_info = {
76235783Skib	.gen = 3, .is_mobile = 1,
77235783Skib	.cursor_needs_physical = 1,
78235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
79235783Skib	.supports_tv = 1,
80235783Skib};
81235783Skibstatic const struct intel_device_info intel_i945g_info = {
82235783Skib	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
83235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
84235783Skib};
85235783Skibstatic const struct intel_device_info intel_i945gm_info = {
86235783Skib	.gen = 3, .is_i945gm = 1, .is_mobile = 1,
87235783Skib	.has_hotplug = 1, .cursor_needs_physical = 1,
88235783Skib	.has_overlay = 1, .overlay_needs_physical = 1,
89235783Skib	.supports_tv = 1,
90235783Skib};
91235783Skib
92235783Skibstatic const struct intel_device_info intel_i965g_info = {
93235783Skib	.gen = 4, .is_broadwater = 1,
94235783Skib	.has_hotplug = 1,
95235783Skib	.has_overlay = 1,
96235783Skib};
97235783Skib
98235783Skibstatic const struct intel_device_info intel_i965gm_info = {
99235783Skib	.gen = 4, .is_crestline = 1,
100235783Skib	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
101235783Skib	.has_overlay = 1,
102235783Skib	.supports_tv = 1,
103235783Skib};
104235783Skib
105235783Skibstatic const struct intel_device_info intel_g33_info = {
106235783Skib	.gen = 3, .is_g33 = 1,
107235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
108235783Skib	.has_overlay = 1,
109235783Skib};
110235783Skib
111235783Skibstatic const struct intel_device_info intel_g45_info = {
112235783Skib	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
113235783Skib	.has_pipe_cxsr = 1, .has_hotplug = 1,
114235783Skib	.has_bsd_ring = 1,
115235783Skib};
116235783Skib
117235783Skibstatic const struct intel_device_info intel_gm45_info = {
118235783Skib	.gen = 4, .is_g4x = 1,
119235783Skib	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
120235783Skib	.has_pipe_cxsr = 1, .has_hotplug = 1,
121235783Skib	.supports_tv = 1,
122235783Skib	.has_bsd_ring = 1,
123235783Skib};
124235783Skib
125235783Skibstatic const struct intel_device_info intel_pineview_info = {
126235783Skib	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
127235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
128235783Skib	.has_overlay = 1,
129235783Skib};
130235783Skib
131235783Skibstatic const struct intel_device_info intel_ironlake_d_info = {
132235783Skib	.gen = 5,
133235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
134235783Skib	.has_bsd_ring = 1,
135280369Skib	.has_pch_split = 1,
136235783Skib};
137235783Skib
138235783Skibstatic const struct intel_device_info intel_ironlake_m_info = {
139235783Skib	.gen = 5, .is_mobile = 1,
140235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
141235783Skib	.has_fbc = 0, /* disabled due to buggy hardware */
142235783Skib	.has_bsd_ring = 1,
143280369Skib	.has_pch_split = 1,
144235783Skib};
145235783Skib
146235783Skibstatic const struct intel_device_info intel_sandybridge_d_info = {
147235783Skib	.gen = 6,
148235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
149235783Skib	.has_bsd_ring = 1,
150235783Skib	.has_blt_ring = 1,
151235783Skib	.has_llc = 1,
152280369Skib	.has_pch_split = 1,
153235783Skib};
154235783Skib
155235783Skibstatic const struct intel_device_info intel_sandybridge_m_info = {
156235783Skib	.gen = 6, .is_mobile = 1,
157235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
158235783Skib	.has_fbc = 1,
159235783Skib	.has_bsd_ring = 1,
160235783Skib	.has_blt_ring = 1,
161235783Skib	.has_llc = 1,
162280369Skib	.has_pch_split = 1,
163235783Skib};
164235783Skib
165235783Skibstatic const struct intel_device_info intel_ivybridge_d_info = {
166235783Skib	.is_ivybridge = 1, .gen = 7,
167235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
168235783Skib	.has_bsd_ring = 1,
169235783Skib	.has_blt_ring = 1,
170235783Skib	.has_llc = 1,
171280369Skib	.has_pch_split = 1,
172235783Skib};
173235783Skib
174235783Skibstatic const struct intel_device_info intel_ivybridge_m_info = {
175235783Skib	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
176235783Skib	.need_gfx_hws = 1, .has_hotplug = 1,
177235783Skib	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
178235783Skib	.has_bsd_ring = 1,
179235783Skib	.has_blt_ring = 1,
180235783Skib	.has_llc = 1,
181280369Skib	.has_pch_split = 1,
182235783Skib};
183235783Skib
184280369Skib#if 0
185280369Skibstatic const struct intel_device_info intel_valleyview_m_info = {
186280369Skib	.gen = 7, .is_mobile = 1,
187280369Skib	.need_gfx_hws = 1, .has_hotplug = 1,
188280369Skib	.has_fbc = 0,
189280369Skib	.has_bsd_ring = 1,
190280369Skib	.has_blt_ring = 1,
191280369Skib	.is_valleyview = 1,
192280369Skib};
193280369Skib
194280369Skibstatic const struct intel_device_info intel_valleyview_d_info = {
195280369Skib	.gen = 7,
196280369Skib	.need_gfx_hws = 1, .has_hotplug = 1,
197280369Skib	.has_fbc = 0,
198280369Skib	.has_bsd_ring = 1,
199280369Skib	.has_blt_ring = 1,
200280369Skib	.is_valleyview = 1,
201280369Skib};
202280369Skib#endif
203280369Skib
204280369Skibstatic const struct intel_device_info intel_haswell_d_info = {
205280369Skib	.is_haswell = 1, .gen = 7,
206280369Skib	.need_gfx_hws = 1, .has_hotplug = 1,
207280369Skib	.has_bsd_ring = 1,
208280369Skib	.has_blt_ring = 1,
209280369Skib	.has_llc = 1,
210280369Skib	.has_pch_split = 1,
211280369Skib	.not_supported = 1,
212280369Skib};
213280369Skib
214280369Skibstatic const struct intel_device_info intel_haswell_m_info = {
215280369Skib	.is_haswell = 1, .gen = 7, .is_mobile = 1,
216280369Skib	.need_gfx_hws = 1, .has_hotplug = 1,
217280369Skib	.has_bsd_ring = 1,
218280369Skib	.has_blt_ring = 1,
219280369Skib	.has_llc = 1,
220280369Skib	.has_pch_split = 1,
221280369Skib	.not_supported = 1,
222280369Skib};
223280369Skib
224235783Skib#define INTEL_VGA_DEVICE(id, info_) {		\
225235783Skib	.device = id,				\
226235783Skib	.info = info_,				\
227235783Skib}
228235783Skib
229235783Skibstatic const struct intel_gfx_device_id {
230235783Skib	int device;
231235783Skib	const struct intel_device_info *info;
232235783Skib} pciidlist[] = {		/* aka */
233235783Skib	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
234235783Skib	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
235235783Skib	INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
236235783Skib	INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
237235783Skib	INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
238235783Skib	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
239235783Skib	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
240235783Skib	INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
241235783Skib	INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
242235783Skib	INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
243235783Skib	INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
244235783Skib	INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
245235783Skib	INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
246235783Skib	INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
247235783Skib	INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
248235783Skib	INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
249235783Skib	INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
250235783Skib	INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
251235783Skib	INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
252235783Skib	INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
253235783Skib	INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
254235783Skib	INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
255235783Skib	INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
256235783Skib	INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
257235783Skib	INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
258235783Skib	INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
259235783Skib	INTEL_VGA_DEVICE(0x2e92, &intel_g45_info),
260235783Skib	INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
261235783Skib	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
262235783Skib	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
263235783Skib	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
264235783Skib	INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
265235783Skib	INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
266235783Skib	INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
267235783Skib	INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
268235783Skib	INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
269235783Skib	INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
270235783Skib	INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
271235783Skib	INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */
272235783Skib	INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */
273235783Skib	INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */
274235783Skib	INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */
275235783Skib	INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */
276235783Skib	INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */
277280369Skib	INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */
278280369Skib	INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */
279280369Skib	INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */
280280369Skib	INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */
281280369Skib	INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
282280369Skib	INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
283280369Skib	INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */
284235783Skib	{0, 0}
285235783Skib};
286235783Skib
287280369Skibstatic int i915_enable_unsupported;
288280369Skib
289235783Skibstatic int i915_drm_freeze(struct drm_device *dev)
290235783Skib{
291235783Skib	struct drm_i915_private *dev_priv;
292235783Skib	int error;
293235783Skib
294235783Skib	dev_priv = dev->dev_private;
295235783Skib	drm_kms_helper_poll_disable(dev);
296235783Skib
297235783Skib#if 0
298235783Skib	pci_save_state(dev->pdev);
299235783Skib#endif
300235783Skib
301235783Skib	/* If KMS is active, we do the leavevt stuff here */
302235783Skib	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
303282199Sdumbbell		error = i915_gem_idle(dev);
304235783Skib		if (error) {
305282199Sdumbbell			device_printf(dev->dev,
306235783Skib			    "GEM idle failed, resume might fail\n");
307235783Skib			return (error);
308235783Skib		}
309235783Skib		drm_irq_uninstall(dev);
310235783Skib	}
311235783Skib
312235783Skib	i915_save_state(dev);
313235783Skib
314235783Skib	intel_opregion_fini(dev);
315235783Skib
316235783Skib	/* Modeset on resume, not lid events */
317235783Skib	dev_priv->modeset_on_lid = 0;
318235783Skib
319235783Skib	return 0;
320235783Skib}
321235783Skib
322235783Skibstatic int
323235783Skibi915_suspend(device_t kdev)
324235783Skib{
325235783Skib	struct drm_device *dev;
326235783Skib	int error;
327235783Skib
328235783Skib	dev = device_get_softc(kdev);
329235783Skib	if (dev == NULL || dev->dev_private == NULL) {
330235783Skib		DRM_ERROR("DRM not initialized, aborting suspend.\n");
331282199Sdumbbell		return ENODEV;
332235783Skib	}
333235783Skib
334235783Skib	DRM_DEBUG_KMS("starting suspend\n");
335235783Skib	error = i915_drm_freeze(dev);
336235783Skib	if (error)
337282199Sdumbbell		return (-error);
338235783Skib
339235783Skib	error = bus_generic_suspend(kdev);
340235783Skib	DRM_DEBUG_KMS("finished suspend %d\n", error);
341235783Skib	return (error);
342235783Skib}
343235783Skib
344235783Skibstatic int i915_drm_thaw(struct drm_device *dev)
345235783Skib{
346235783Skib	struct drm_i915_private *dev_priv = dev->dev_private;
347235783Skib	int error = 0;
348235783Skib
349235783Skib	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
350282199Sdumbbell		DRM_LOCK(dev);
351235783Skib		i915_gem_restore_gtt_mappings(dev);
352282199Sdumbbell		DRM_UNLOCK(dev);
353235783Skib	}
354235783Skib
355235783Skib	i915_restore_state(dev);
356235783Skib	intel_opregion_setup(dev);
357235783Skib
358235783Skib	/* KMS EnterVT equivalent */
359235783Skib	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
360280369Skib		if (HAS_PCH_SPLIT(dev))
361280369Skib			ironlake_init_pch_refclk(dev);
362280369Skib
363282199Sdumbbell		DRM_LOCK(dev);
364235783Skib		dev_priv->mm.suspended = 0;
365235783Skib
366235783Skib		error = i915_gem_init_hw(dev);
367280369Skib		DRM_UNLOCK(dev);
368235783Skib
369280369Skib		intel_modeset_init_hw(dev);
370235783Skib		sx_xlock(&dev->mode_config.mutex);
371235783Skib		drm_mode_config_reset(dev);
372235783Skib		sx_xunlock(&dev->mode_config.mutex);
373235783Skib		drm_irq_install(dev);
374235783Skib
375235783Skib		sx_xlock(&dev->mode_config.mutex);
376235783Skib		/* Resume the modeset for every activated CRTC */
377235783Skib		drm_helper_resume_force_mode(dev);
378235783Skib		sx_xunlock(&dev->mode_config.mutex);
379235783Skib	}
380235783Skib
381235783Skib	intel_opregion_init(dev);
382235783Skib
383235783Skib	dev_priv->modeset_on_lid = 0;
384235783Skib
385235783Skib	return error;
386235783Skib}
387235783Skib
388235783Skibstatic int
389235783Skibi915_resume(device_t kdev)
390235783Skib{
391235783Skib	struct drm_device *dev;
392235783Skib	int ret;
393235783Skib
394235783Skib	dev = device_get_softc(kdev);
395235783Skib	DRM_DEBUG_KMS("starting resume\n");
396235783Skib#if 0
397235783Skib	if (pci_enable_device(dev->pdev))
398235783Skib		return -EIO;
399235783Skib
400235783Skib	pci_set_master(dev->pdev);
401235783Skib#endif
402235783Skib
403282199Sdumbbell	ret = i915_drm_thaw(dev);
404235783Skib	if (ret != 0)
405282199Sdumbbell		return (-ret);
406235783Skib
407235783Skib	drm_kms_helper_poll_enable(dev);
408235783Skib	ret = bus_generic_resume(kdev);
409235783Skib	DRM_DEBUG_KMS("finished resume %d\n", ret);
410235783Skib	return (ret);
411235783Skib}
412235783Skib
413235783Skibstatic int
414235783Skibi915_probe(device_t kdev)
415235783Skib{
416280369Skib	const struct intel_device_info *info;
417280369Skib	int error;
418235783Skib
419282199Sdumbbell	error = drm_probe_helper(kdev, i915_pciidlist);
420280369Skib	if (error != 0)
421282199Sdumbbell		return (-error);
422280369Skib	info = i915_get_device_id(pci_get_device(kdev));
423280369Skib	if (info == NULL)
424280369Skib		return (ENXIO);
425280369Skib	return (0);
426235783Skib}
427235783Skib
428235783Skibint i915_modeset;
429235783Skib
430235783Skibstatic int
431235783Skibi915_attach(device_t kdev)
432235783Skib{
433235783Skib
434235783Skib	if (i915_modeset == 1)
435235783Skib		i915_driver_info.driver_features |= DRIVER_MODESET;
436282199Sdumbbell	return (-drm_attach_helper(kdev, i915_pciidlist, &i915_driver_info));
437235783Skib}
438235783Skib
439262861Sjhbstatic struct fb_info *
440262861Sjhbi915_fb_helper_getinfo(device_t kdev)
441262861Sjhb{
442262861Sjhb	struct intel_fbdev *ifbdev;
443262861Sjhb	drm_i915_private_t *dev_priv;
444262861Sjhb	struct drm_device *dev;
445262861Sjhb	struct fb_info *info;
446262861Sjhb
447262861Sjhb	dev = device_get_softc(kdev);
448262861Sjhb	dev_priv = dev->dev_private;
449262861Sjhb	ifbdev = dev_priv->fbdev;
450262861Sjhb	if (ifbdev == NULL)
451262861Sjhb		return (NULL);
452262861Sjhb
453262861Sjhb	info = ifbdev->helper.fbdev;
454262861Sjhb
455262861Sjhb	return (info);
456262861Sjhb}
457262861Sjhb
458235783Skibconst struct intel_device_info *
459235783Skibi915_get_device_id(int device)
460235783Skib{
461235783Skib	const struct intel_gfx_device_id *did;
462235783Skib
463235783Skib	for (did = &pciidlist[0]; did->device != 0; did++) {
464235783Skib		if (did->device != device)
465235783Skib			continue;
466280369Skib		if (did->info->not_supported && !i915_enable_unsupported)
467280369Skib			return (NULL);
468235783Skib		return (did->info);
469235783Skib	}
470235783Skib	return (NULL);
471235783Skib}
472235783Skib
473235783Skibstatic device_method_t i915_methods[] = {
474235783Skib	/* Device interface */
475235783Skib	DEVMETHOD(device_probe,		i915_probe),
476235783Skib	DEVMETHOD(device_attach,	i915_attach),
477235783Skib	DEVMETHOD(device_suspend,	i915_suspend),
478235783Skib	DEVMETHOD(device_resume,	i915_resume),
479282199Sdumbbell	DEVMETHOD(device_detach,	drm_generic_detach),
480262861Sjhb
481262861Sjhb	/* Framebuffer service methods */
482262861Sjhb	DEVMETHOD(fb_getinfo,		i915_fb_helper_getinfo),
483262861Sjhb
484235783Skib	DEVMETHOD_END
485235783Skib};
486235783Skib
487235783Skibstatic driver_t i915_driver = {
488235783Skib	"drmn",
489235783Skib	i915_methods,
490235783Skib	sizeof(struct drm_device)
491235783Skib};
492235783Skib
493235783Skibextern devclass_t drm_devclass;
494235783SkibDRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0,
495235783Skib    SI_ORDER_ANY);
496235783SkibMODULE_DEPEND(i915kms, drmn, 1, 1, 1);
497235783SkibMODULE_DEPEND(i915kms, agp, 1, 1, 1);
498235783SkibMODULE_DEPEND(i915kms, iicbus, 1, 1, 1);
499235783SkibMODULE_DEPEND(i915kms, iic, 1, 1, 1);
500235783SkibMODULE_DEPEND(i915kms, iicbb, 1, 1, 1);
501235783Skib
502235783Skibint intel_iommu_enabled = 0;
503235783SkibTUNABLE_INT("drm.i915.intel_iommu_enabled", &intel_iommu_enabled);
504280369Skibint intel_iommu_gfx_mapped = 0;
505280369SkibTUNABLE_INT("drm.i915.intel_iommu_gfx_mapped", &intel_iommu_gfx_mapped);
506235783Skib
507280369Skibint i915_prefault_disable;
508280369SkibTUNABLE_INT("drm.i915.prefault_disable", &i915_prefault_disable);
509235783Skibint i915_semaphores = -1;
510235783SkibTUNABLE_INT("drm.i915.semaphores", &i915_semaphores);
511235783Skibstatic int i915_try_reset = 1;
512235783SkibTUNABLE_INT("drm.i915.try_reset", &i915_try_reset);
513235783Skibunsigned int i915_lvds_downclock = 0;
514235783SkibTUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock);
515235783Skibint i915_vbt_sdvo_panel_type = -1;
516235783SkibTUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type);
517235783Skibunsigned int i915_powersave = 1;
518235783SkibTUNABLE_INT("drm.i915.powersave", &i915_powersave);
519235783Skibint i915_enable_fbc = 0;
520235783SkibTUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc);
521235783Skibint i915_enable_rc6 = 0;
522235783SkibTUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6);
523280369Skibint i915_lvds_channel_mode;
524280369SkibTUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode);
525235783Skibint i915_panel_use_ssc = -1;
526235783SkibTUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc);
527235783Skibint i915_panel_ignore_lid = 0;
528235783SkibTUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid);
529280369Skibint i915_panel_invert_brightness;
530280369SkibTUNABLE_INT("drm.i915.panel_invert_brightness", &i915_panel_invert_brightness);
531235783Skibint i915_modeset = 1;
532235783SkibTUNABLE_INT("drm.i915.modeset", &i915_modeset);
533235783Skibint i915_enable_ppgtt = -1;
534235783SkibTUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt);
535235783Skibint i915_enable_hangcheck = 1;
536235783SkibTUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck);
537280369SkibTUNABLE_INT("drm.i915.enable_unsupported", &i915_enable_unsupported);
538235783Skib
539235783Skib#define	PCI_VENDOR_INTEL		0x8086
540235783Skib#define INTEL_PCH_DEVICE_ID_MASK	0xff00
541235783Skib#define INTEL_PCH_IBX_DEVICE_ID_TYPE	0x3b00
542235783Skib#define INTEL_PCH_CPT_DEVICE_ID_TYPE	0x1c00
543235783Skib#define INTEL_PCH_PPT_DEVICE_ID_TYPE	0x1e00
544280369Skib#define INTEL_PCH_LPT_DEVICE_ID_TYPE	0x8c00
545235783Skib
546280369Skibvoid intel_detect_pch(struct drm_device *dev)
547235783Skib{
548235783Skib	struct drm_i915_private *dev_priv;
549235783Skib	device_t pch;
550235783Skib	uint32_t id;
551235783Skib
552235783Skib	dev_priv = dev->dev_private;
553235783Skib	pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA);
554235783Skib	if (pch != NULL && pci_get_vendor(pch) == PCI_VENDOR_INTEL) {
555235783Skib		id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
556235783Skib		if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
557235783Skib			dev_priv->pch_type = PCH_IBX;
558280369Skib			dev_priv->num_pch_pll = 2;
559235783Skib			DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
560235783Skib		} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
561235783Skib			dev_priv->pch_type = PCH_CPT;
562280369Skib			dev_priv->num_pch_pll = 2;
563235783Skib			DRM_DEBUG_KMS("Found CougarPoint PCH\n");
564235783Skib		} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
565235783Skib			/* PantherPoint is CPT compatible */
566235783Skib			dev_priv->pch_type = PCH_CPT;
567280369Skib			dev_priv->num_pch_pll = 2;
568235783Skib			DRM_DEBUG_KMS("Found PatherPoint PCH\n");
569280369Skib		} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
570280369Skib			dev_priv->pch_type = PCH_LPT;
571280369Skib			dev_priv->num_pch_pll = 0;
572280369Skib			DRM_DEBUG_KMS("Found LynxPoint PCH\n");
573235783Skib		} else
574235783Skib			DRM_DEBUG_KMS("No PCH detected\n");
575280369Skib		KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS,
576280369Skib		    ("num_pch_pll %d\n", dev_priv->num_pch_pll));
577235783Skib	} else
578235783Skib		DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n");
579235783Skib}
580235783Skib
581280369Skibbool i915_semaphore_is_enabled(struct drm_device *dev)
582280369Skib{
583280369Skib	if (INTEL_INFO(dev)->gen < 6)
584280369Skib		return 0;
585280369Skib
586280369Skib	if (i915_semaphores >= 0)
587280369Skib		return i915_semaphores;
588280369Skib
589280369Skib	/* Enable semaphores on SNB when IO remapping is off */
590280369Skib	if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
591280369Skib		return false;
592280369Skib
593280369Skib	return 1;
594280369Skib}
595280369Skib
596235783Skibvoid
597235783Skib__gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
598235783Skib{
599235783Skib	int count;
600235783Skib
601235783Skib	count = 0;
602235783Skib	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
603240917Smav		DELAY(10);
604235783Skib
605235783Skib	I915_WRITE_NOTRACE(FORCEWAKE, 1);
606235783Skib	POSTING_READ(FORCEWAKE);
607235783Skib
608235783Skib	count = 0;
609235783Skib	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
610240917Smav		DELAY(10);
611235783Skib}
612235783Skib
613235783Skibvoid
614235783Skib__gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
615235783Skib{
616235783Skib	int count;
617235783Skib
618235783Skib	count = 0;
619235783Skib	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
620240917Smav		DELAY(10);
621235783Skib
622280369Skib	I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
623235783Skib	POSTING_READ(FORCEWAKE_MT);
624235783Skib
625235783Skib	count = 0;
626235783Skib	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
627240917Smav		DELAY(10);
628235783Skib}
629235783Skib
630235783Skibvoid
631235783Skibgen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
632235783Skib{
633235783Skib
634235783Skib	mtx_lock(&dev_priv->gt_lock);
635235783Skib	if (dev_priv->forcewake_count++ == 0)
636235783Skib		dev_priv->display.force_wake_get(dev_priv);
637235783Skib	mtx_unlock(&dev_priv->gt_lock);
638235783Skib}
639235783Skib
640235783Skibstatic void
641235783Skibgen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
642235783Skib{
643235783Skib	u32 gtfifodbg;
644235783Skib
645235783Skib	gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
646235783Skib	if ((gtfifodbg & GT_FIFO_CPU_ERROR_MASK) != 0) {
647235783Skib		printf("MMIO read or write has been dropped %x\n", gtfifodbg);
648235783Skib		I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
649235783Skib	}
650235783Skib}
651235783Skib
652235783Skibvoid
653235783Skib__gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
654235783Skib{
655235783Skib
656235783Skib	I915_WRITE_NOTRACE(FORCEWAKE, 0);
657235783Skib	/* The below doubles as a POSTING_READ */
658235783Skib	gen6_gt_check_fifodbg(dev_priv);
659235783Skib}
660235783Skib
661235783Skibvoid
662235783Skib__gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
663235783Skib{
664235783Skib
665280369Skib	I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
666235783Skib	/* The below doubles as a POSTING_READ */
667235783Skib	gen6_gt_check_fifodbg(dev_priv);
668235783Skib}
669235783Skib
670235783Skibvoid
671235783Skibgen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
672235783Skib{
673235783Skib
674235783Skib	mtx_lock(&dev_priv->gt_lock);
675235783Skib	if (--dev_priv->forcewake_count == 0)
676235783Skib 		dev_priv->display.force_wake_put(dev_priv);
677235783Skib	mtx_unlock(&dev_priv->gt_lock);
678235783Skib}
679235783Skib
680235783Skibint
681235783Skib__gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
682235783Skib{
683235783Skib	int ret = 0;
684235783Skib
685235783Skib	if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
686235783Skib		int loop = 500;
687235783Skib		u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
688235783Skib		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
689240917Smav			DELAY(10);
690235783Skib			fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
691235783Skib		}
692235783Skib		if (loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES) {
693235783Skib			printf("%s loop\n", __func__);
694235783Skib			++ret;
695235783Skib		}
696235783Skib		dev_priv->gt_fifo_count = fifo;
697235783Skib	}
698235783Skib	dev_priv->gt_fifo_count--;
699235783Skib
700235783Skib	return (ret);
701235783Skib}
702235783Skib
703280369Skibvoid vlv_force_wake_get(struct drm_i915_private *dev_priv)
704280369Skib{
705280369Skib	int count;
706280369Skib
707280369Skib	count = 0;
708280369Skib
709280369Skib	/* Already awake? */
710280369Skib	if ((I915_READ(0x130094) & 0xa1) == 0xa1)
711280369Skib		return;
712280369Skib
713280369Skib	I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff);
714280369Skib	POSTING_READ(FORCEWAKE_VLV);
715280369Skib
716280369Skib	count = 0;
717280369Skib	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0)
718280369Skib		DELAY(10);
719280369Skib}
720280369Skib
721280369Skibvoid vlv_force_wake_put(struct drm_i915_private *dev_priv)
722280369Skib{
723280369Skib	I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000);
724280369Skib	/* FIXME: confirm VLV behavior with Punit folks */
725280369Skib	POSTING_READ(FORCEWAKE_VLV);
726280369Skib}
727280369Skib
728235783Skibstatic int
729271816Sdumbbelli8xx_do_reset(struct drm_device *dev)
730235783Skib{
731235783Skib	struct drm_i915_private *dev_priv = dev->dev_private;
732235783Skib	int onems;
733235783Skib
734235783Skib	if (IS_I85X(dev))
735235783Skib		return -ENODEV;
736235783Skib
737235783Skib	onems = hz / 1000;
738235783Skib	if (onems == 0)
739235783Skib		onems = 1;
740235783Skib
741235783Skib	I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
742235783Skib	POSTING_READ(D_STATE);
743235783Skib
744235783Skib	if (IS_I830(dev) || IS_845G(dev)) {
745235783Skib		I915_WRITE(DEBUG_RESET_I830,
746235783Skib			   DEBUG_RESET_DISPLAY |
747235783Skib			   DEBUG_RESET_RENDER |
748235783Skib			   DEBUG_RESET_FULL);
749235783Skib		POSTING_READ(DEBUG_RESET_I830);
750235783Skib		pause("i8xxrst1", onems);
751235783Skib
752235783Skib		I915_WRITE(DEBUG_RESET_I830, 0);
753235783Skib		POSTING_READ(DEBUG_RESET_I830);
754235783Skib	}
755235783Skib
756235783Skib	pause("i8xxrst2", onems);
757235783Skib
758235783Skib	I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
759235783Skib	POSTING_READ(D_STATE);
760235783Skib
761235783Skib	return 0;
762235783Skib}
763235783Skib
764235783Skibstatic int
765235783Skibi965_reset_complete(struct drm_device *dev)
766235783Skib{
767235783Skib	u8 gdrst;
768235783Skib
769282199Sdumbbell	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
770280369Skib	return (gdrst & GRDOM_RESET_ENABLE) == 0;
771235783Skib}
772235783Skib
773235783Skibstatic int
774271816Sdumbbelli965_do_reset(struct drm_device *dev)
775235783Skib{
776280369Skib	int ret;
777235783Skib	u8 gdrst;
778235783Skib
779235783Skib	/*
780235783Skib	 * Set the domains we want to reset (GRDOM/bits 2 and 3) as
781235783Skib	 * well as the reset bit (GR/bit 0).  Setting the GR bit
782235783Skib	 * triggers the reset; when done, the hardware will clear it.
783235783Skib	 */
784282199Sdumbbell	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
785282199Sdumbbell	pci_write_config(dev->dev, I965_GDRST,
786271816Sdumbbell	    gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE, 1);
787235783Skib
788280369Skib	ret =  wait_for(i965_reset_complete(dev), 500);
789280369Skib	if (ret)
790280369Skib		return ret;
791280369Skib
792280369Skib	/* We can't reset render&media without also resetting display ... */
793282199Sdumbbell	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
794282199Sdumbbell	pci_write_config(dev->dev, I965_GDRST,
795280369Skib			 gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE, 1);
796280369Skib
797280369Skib 	return wait_for(i965_reset_complete(dev), 500);
798235783Skib}
799235783Skib
800235783Skibstatic int
801271816Sdumbbellironlake_do_reset(struct drm_device *dev)
802235783Skib{
803235783Skib	struct drm_i915_private *dev_priv;
804235783Skib	u32 gdrst;
805280369Skib	int ret;
806235783Skib
807235783Skib	dev_priv = dev->dev_private;
808235783Skib	gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
809271816Sdumbbell	I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
810280369Skib		   gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
811280369Skib	ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
812280369Skib	if (ret)
813280369Skib		return ret;
814280369Skib
815280369Skib	/* We can't reset render&media without also resetting display ... */
816280369Skib	gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
817280369Skib	I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
818280369Skib		   gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE);
819280369Skib 	return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
820235783Skib}
821235783Skib
822235783Skibstatic int
823271816Sdumbbellgen6_do_reset(struct drm_device *dev)
824235783Skib{
825235783Skib	struct drm_i915_private *dev_priv;
826235783Skib	int ret;
827235783Skib
828235783Skib	dev_priv = dev->dev_private;
829235783Skib
830235783Skib	/* Hold gt_lock across reset to prevent any register access
831235783Skib	 * with forcewake not set correctly
832235783Skib	 */
833235783Skib	mtx_lock(&dev_priv->gt_lock);
834235783Skib
835235783Skib	/* Reset the chip */
836235783Skib
837235783Skib	/* GEN6_GDRST is not in the gt power well, no need to check
838235783Skib	 * for fifo space for the write or forcewake the chip for
839235783Skib	 * the read
840235783Skib	 */
841235783Skib	I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
842235783Skib
843235783Skib	/* Spin waiting for the device to ack the reset request */
844235783Skib	ret = _intel_wait_for(dev,
845257311Skib	    (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
846280369Skib	    500, 0, "915rst");
847235783Skib
848235783Skib	/* If reset with a user forcewake, try to restore, otherwise turn it off */
849235783Skib 	if (dev_priv->forcewake_count)
850235783Skib 		dev_priv->display.force_wake_get(dev_priv);
851235783Skib	else
852235783Skib		dev_priv->display.force_wake_put(dev_priv);
853235783Skib
854235783Skib	/* Restore fifo count */
855235783Skib	dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
856235783Skib
857235783Skib	mtx_unlock(&dev_priv->gt_lock);
858235783Skib	return (ret);
859235783Skib}
860235783Skib
861280369Skibint
862280369Skibintel_gpu_reset(struct drm_device *dev)
863271816Sdumbbell{
864271816Sdumbbell	struct drm_i915_private *dev_priv = dev->dev_private;
865271816Sdumbbell	int ret = -ENODEV;
866271816Sdumbbell
867271816Sdumbbell	switch (INTEL_INFO(dev)->gen) {
868271816Sdumbbell	case 7:
869271816Sdumbbell	case 6:
870271816Sdumbbell		ret = gen6_do_reset(dev);
871271816Sdumbbell		break;
872271816Sdumbbell	case 5:
873271816Sdumbbell		ret = ironlake_do_reset(dev);
874271816Sdumbbell		break;
875271816Sdumbbell	case 4:
876271816Sdumbbell		ret = i965_do_reset(dev);
877271816Sdumbbell		break;
878271816Sdumbbell	case 2:
879271816Sdumbbell		ret = i8xx_do_reset(dev);
880271816Sdumbbell		break;
881271816Sdumbbell	}
882271816Sdumbbell
883271816Sdumbbell	/* Also reset the gpu hangman. */
884271816Sdumbbell	if (dev_priv->stop_rings) {
885271816Sdumbbell		DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n");
886271816Sdumbbell		dev_priv->stop_rings = 0;
887271816Sdumbbell		if (ret == -ENODEV) {
888271816Sdumbbell			DRM_ERROR("Reset not implemented, but ignoring "
889271816Sdumbbell				  "error for simulated gpu hangs\n");
890271816Sdumbbell			ret = 0;
891271816Sdumbbell		}
892271816Sdumbbell	}
893271816Sdumbbell
894271816Sdumbbell	return ret;
895271816Sdumbbell}
896271816Sdumbbell
897280369Skibint i915_reset(struct drm_device *dev)
898235783Skib{
899235783Skib	drm_i915_private_t *dev_priv = dev->dev_private;
900235783Skib	int ret;
901235783Skib
902235783Skib	if (!i915_try_reset)
903235783Skib		return (0);
904235783Skib
905235783Skib	if (!sx_try_xlock(&dev->dev_struct_lock))
906235783Skib		return (-EBUSY);
907235783Skib
908280369Skib	dev_priv->stop_rings = 0;
909280369Skib
910235783Skib	i915_gem_reset(dev);
911235783Skib
912235783Skib	ret = -ENODEV;
913280369Skib	if (time_second - dev_priv->last_gpu_reset < 5)
914235783Skib		DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
915280369Skib	else
916271816Sdumbbell		ret = intel_gpu_reset(dev);
917271816Sdumbbell
918235783Skib	dev_priv->last_gpu_reset = time_second;
919235783Skib	if (ret) {
920235783Skib		DRM_ERROR("Failed to reset chip.\n");
921235783Skib		DRM_UNLOCK(dev);
922235783Skib		return (ret);
923235783Skib	}
924235783Skib
925235783Skib	if (drm_core_check_feature(dev, DRIVER_MODESET) ||
926235783Skib	    !dev_priv->mm.suspended) {
927280369Skib		struct intel_ring_buffer *ring;
928280369Skib		int i;
929280369Skib
930235783Skib		dev_priv->mm.suspended = 0;
931235783Skib
932235783Skib		i915_gem_init_swizzling(dev);
933235783Skib
934280369Skib		for_each_ring(ring, dev_priv, i)
935280369Skib			ring->init(ring);
936235783Skib
937271816Sdumbbell		i915_gem_context_init(dev);
938235783Skib		i915_gem_init_ppgtt(dev);
939235783Skib
940280369Skib		DRM_UNLOCK(dev);
941280369Skib
942280369Skib		if (drm_core_check_feature(dev, DRIVER_MODESET))
943280369Skib			intel_modeset_init_hw(dev);
944280369Skib
945235783Skib		drm_irq_uninstall(dev);
946235783Skib		drm_irq_install(dev);
947280369Skib	} else
948280369Skib		DRM_UNLOCK(dev);
949235783Skib
950235783Skib	return (0);
951235783Skib}
952235783Skib
953280369Skib/* We give fast paths for the really cool registers */
954280369Skib#define NEEDS_FORCE_WAKE(dev_priv, reg) \
955280369Skib       (((dev_priv)->info->gen >= 6) && \
956280369Skib        ((reg) < 0x40000) &&            \
957280369Skib        ((reg) != FORCEWAKE)) && \
958280369Skib       (!IS_VALLEYVIEW((dev_priv)->dev))
959280369Skib
960235783Skib#define __i915_read(x, y) \
961235783Skibu##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
962235783Skib	u##x val = 0; \
963235783Skib	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
964235783Skib		mtx_lock(&dev_priv->gt_lock); \
965235783Skib		if (dev_priv->forcewake_count == 0) \
966235783Skib			dev_priv->display.force_wake_get(dev_priv); \
967235783Skib		val = DRM_READ##y(dev_priv->mmio_map, reg);	\
968235783Skib		if (dev_priv->forcewake_count == 0) \
969235783Skib			dev_priv->display.force_wake_put(dev_priv); \
970235783Skib		mtx_unlock(&dev_priv->gt_lock); \
971235783Skib	} else { \
972235783Skib		val = DRM_READ##y(dev_priv->mmio_map, reg);	\
973235783Skib	} \
974235783Skib	trace_i915_reg_rw(false, reg, val, sizeof(val)); \
975235783Skib	return val; \
976235783Skib}
977235783Skib
978235783Skib__i915_read(8, 8)
979235783Skib__i915_read(16, 16)
980235783Skib__i915_read(32, 32)
981235783Skib__i915_read(64, 64)
982235783Skib#undef __i915_read
983235783Skib
984235783Skib#define __i915_write(x, y) \
985235783Skibvoid i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
986235783Skib	u32 __fifo_ret = 0; \
987235783Skib	trace_i915_reg_rw(true, reg, val, sizeof(val)); \
988235783Skib	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
989235783Skib		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
990235783Skib	} \
991235783Skib	DRM_WRITE##y(dev_priv->mmio_map, reg, val); \
992235783Skib	if (__predict_false(__fifo_ret)) { \
993235783Skib		gen6_gt_check_fifodbg(dev_priv); \
994235783Skib	} \
995235783Skib}
996235783Skib__i915_write(8, 8)
997235783Skib__i915_write(16, 16)
998235783Skib__i915_write(32, 32)
999235783Skib__i915_write(64, 64)
1000235783Skib#undef __i915_write
1001