i915_drv.c revision 282199
1169689Skan/* i915_drv.c -- Intel i915 driver -*- linux-c -*-
2169689Skan * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
3169689Skan */
4169689Skan/*-
5169689Skan * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6169689Skan * All Rights Reserved.
7169689Skan *
8169689Skan * Permission is hereby granted, free of charge, to any person obtaining a
9169689Skan * copy of this software and associated documentation files (the "Software"),
10169689Skan * to deal in the Software without restriction, including without limitation
11169689Skan * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12169689Skan * and/or sell copies of the Software, and to permit persons to whom the
13169689Skan * Software is furnished to do so, subject to the following conditions:
14169689Skan *
15169689Skan * The above copyright notice and this permission notice (including the next
16169689Skan * paragraph) shall be included in all copies or substantial portions of the
17169689Skan * Software.
18169689Skan *
19169689Skan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20169689Skan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21169689Skan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22169689Skan * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23169689Skan * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24169689Skan * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25169689Skan * OTHER DEALINGS IN THE SOFTWARE.
26169689Skan *
27169689Skan * Authors:
28169689Skan *    Gareth Hughes <gareth@valinux.com>
29169689Skan *
30169689Skan */
31169689Skan
32169689Skan#include <sys/cdefs.h>
33169689Skan__FBSDID("$FreeBSD: stable/10/sys/dev/drm2/i915/i915_drv.c 282199 2015-04-28 19:35:05Z dumbbell $");
34169689Skan
35169689Skan#include <dev/drm2/drmP.h>
36169689Skan#include <dev/drm2/drm.h>
37169689Skan#include <dev/drm2/drm_mm.h>
38169689Skan#include <dev/drm2/i915/i915_drm.h>
39169689Skan#include <dev/drm2/i915/i915_drv.h>
40169689Skan#include <dev/drm2/drm_pciids.h>
41169689Skan#include <dev/drm2/i915/intel_drv.h>
42169689Skan
43169689Skan#include "fb_if.h"
44169689Skan
45169689Skan/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
46169689Skanstatic drm_pci_id_list_t i915_pciidlist[] = {
47169689Skan	i915_PCI_IDS
48169689Skan};
49169689Skan
50169689Skanstatic const struct intel_device_info intel_i830_info = {
51169689Skan	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1,
52169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
53169689Skan};
54169689Skan
55169689Skanstatic const struct intel_device_info intel_845g_info = {
56169689Skan	.gen = 2,
57169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
58169689Skan};
59169689Skan
60169689Skanstatic const struct intel_device_info intel_i85x_info = {
61169689Skan	.gen = 2, .is_i85x = 1, .is_mobile = 1,
62169689Skan	.cursor_needs_physical = 1,
63169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
64169689Skan};
65169689Skan
66169689Skanstatic const struct intel_device_info intel_i865g_info = {
67169689Skan	.gen = 2,
68169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
69169689Skan};
70169689Skan
71169689Skanstatic const struct intel_device_info intel_i915g_info = {
72169689Skan	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
73169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
74169689Skan};
75169689Skanstatic const struct intel_device_info intel_i915gm_info = {
76169689Skan	.gen = 3, .is_mobile = 1,
77169689Skan	.cursor_needs_physical = 1,
78169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
79169689Skan	.supports_tv = 1,
80169689Skan};
81169689Skanstatic const struct intel_device_info intel_i945g_info = {
82169689Skan	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
83169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
84169689Skan};
85169689Skanstatic const struct intel_device_info intel_i945gm_info = {
86169689Skan	.gen = 3, .is_i945gm = 1, .is_mobile = 1,
87169689Skan	.has_hotplug = 1, .cursor_needs_physical = 1,
88169689Skan	.has_overlay = 1, .overlay_needs_physical = 1,
89169689Skan	.supports_tv = 1,
90169689Skan};
91169689Skan
92169689Skanstatic const struct intel_device_info intel_i965g_info = {
93169689Skan	.gen = 4, .is_broadwater = 1,
94169689Skan	.has_hotplug = 1,
95169689Skan	.has_overlay = 1,
96169689Skan};
97169689Skan
98169689Skanstatic const struct intel_device_info intel_i965gm_info = {
99169689Skan	.gen = 4, .is_crestline = 1,
100169689Skan	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
101169689Skan	.has_overlay = 1,
102169689Skan	.supports_tv = 1,
103169689Skan};
104169689Skan
105169689Skanstatic const struct intel_device_info intel_g33_info = {
106169689Skan	.gen = 3, .is_g33 = 1,
107169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
108169689Skan	.has_overlay = 1,
109169689Skan};
110169689Skan
111169689Skanstatic const struct intel_device_info intel_g45_info = {
112169689Skan	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
113169689Skan	.has_pipe_cxsr = 1, .has_hotplug = 1,
114169689Skan	.has_bsd_ring = 1,
115169689Skan};
116169689Skan
117169689Skanstatic const struct intel_device_info intel_gm45_info = {
118169689Skan	.gen = 4, .is_g4x = 1,
119169689Skan	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
120169689Skan	.has_pipe_cxsr = 1, .has_hotplug = 1,
121169689Skan	.supports_tv = 1,
122169689Skan	.has_bsd_ring = 1,
123169689Skan};
124169689Skan
125169689Skanstatic const struct intel_device_info intel_pineview_info = {
126169689Skan	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
127169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
128169689Skan	.has_overlay = 1,
129169689Skan};
130169689Skan
131169689Skanstatic const struct intel_device_info intel_ironlake_d_info = {
132169689Skan	.gen = 5,
133169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
134169689Skan	.has_bsd_ring = 1,
135169689Skan	.has_pch_split = 1,
136169689Skan};
137169689Skan
138169689Skanstatic const struct intel_device_info intel_ironlake_m_info = {
139169689Skan	.gen = 5, .is_mobile = 1,
140169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
141169689Skan	.has_fbc = 0, /* disabled due to buggy hardware */
142169689Skan	.has_bsd_ring = 1,
143169689Skan	.has_pch_split = 1,
144169689Skan};
145169689Skan
146169689Skanstatic const struct intel_device_info intel_sandybridge_d_info = {
147169689Skan	.gen = 6,
148169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
149169689Skan	.has_bsd_ring = 1,
150169689Skan	.has_blt_ring = 1,
151169689Skan	.has_llc = 1,
152169689Skan	.has_pch_split = 1,
153169689Skan};
154169689Skan
155169689Skanstatic const struct intel_device_info intel_sandybridge_m_info = {
156169689Skan	.gen = 6, .is_mobile = 1,
157169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
158169689Skan	.has_fbc = 1,
159169689Skan	.has_bsd_ring = 1,
160169689Skan	.has_blt_ring = 1,
161169689Skan	.has_llc = 1,
162169689Skan	.has_pch_split = 1,
163169689Skan};
164169689Skan
165169689Skanstatic const struct intel_device_info intel_ivybridge_d_info = {
166169689Skan	.is_ivybridge = 1, .gen = 7,
167169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
168169689Skan	.has_bsd_ring = 1,
169169689Skan	.has_blt_ring = 1,
170169689Skan	.has_llc = 1,
171169689Skan	.has_pch_split = 1,
172169689Skan};
173169689Skan
174169689Skanstatic const struct intel_device_info intel_ivybridge_m_info = {
175169689Skan	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
176169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
177169689Skan	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
178169689Skan	.has_bsd_ring = 1,
179169689Skan	.has_blt_ring = 1,
180169689Skan	.has_llc = 1,
181169689Skan	.has_pch_split = 1,
182169689Skan};
183169689Skan
184169689Skan#if 0
185169689Skanstatic const struct intel_device_info intel_valleyview_m_info = {
186169689Skan	.gen = 7, .is_mobile = 1,
187169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
188169689Skan	.has_fbc = 0,
189169689Skan	.has_bsd_ring = 1,
190169689Skan	.has_blt_ring = 1,
191169689Skan	.is_valleyview = 1,
192169689Skan};
193169689Skan
194169689Skanstatic const struct intel_device_info intel_valleyview_d_info = {
195169689Skan	.gen = 7,
196169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
197169689Skan	.has_fbc = 0,
198169689Skan	.has_bsd_ring = 1,
199169689Skan	.has_blt_ring = 1,
200169689Skan	.is_valleyview = 1,
201169689Skan};
202169689Skan#endif
203169689Skan
204169689Skanstatic const struct intel_device_info intel_haswell_d_info = {
205169689Skan	.is_haswell = 1, .gen = 7,
206169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
207169689Skan	.has_bsd_ring = 1,
208169689Skan	.has_blt_ring = 1,
209169689Skan	.has_llc = 1,
210169689Skan	.has_pch_split = 1,
211169689Skan	.not_supported = 1,
212169689Skan};
213169689Skan
214169689Skanstatic const struct intel_device_info intel_haswell_m_info = {
215169689Skan	.is_haswell = 1, .gen = 7, .is_mobile = 1,
216169689Skan	.need_gfx_hws = 1, .has_hotplug = 1,
217169689Skan	.has_bsd_ring = 1,
218169689Skan	.has_blt_ring = 1,
219169689Skan	.has_llc = 1,
220169689Skan	.has_pch_split = 1,
221169689Skan	.not_supported = 1,
222169689Skan};
223169689Skan
224169689Skan#define INTEL_VGA_DEVICE(id, info_) {		\
225169689Skan	.device = id,				\
226169689Skan	.info = info_,				\
227169689Skan}
228169689Skan
229169689Skanstatic const struct intel_gfx_device_id {
230169689Skan	int device;
231169689Skan	const struct intel_device_info *info;
232169689Skan} pciidlist[] = {		/* aka */
233169689Skan	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
234169689Skan	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
235169689Skan	INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
236169689Skan	INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
237169689Skan	INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
238169689Skan	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
239169689Skan	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
240169689Skan	INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
241169689Skan	INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
242169689Skan	INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
243169689Skan	INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
244169689Skan	INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
245169689Skan	INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
246169689Skan	INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
247169689Skan	INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
248169689Skan	INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
249169689Skan	INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
250169689Skan	INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
251169689Skan	INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
252169689Skan	INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
253169689Skan	INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
254169689Skan	INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
255169689Skan	INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
256169689Skan	INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
257169689Skan	INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
258169689Skan	INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
259169689Skan	INTEL_VGA_DEVICE(0x2e92, &intel_g45_info),
260169689Skan	INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
261169689Skan	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
262169689Skan	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
263169689Skan	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
264169689Skan	INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
265169689Skan	INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
266169689Skan	INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
267169689Skan	INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
268169689Skan	INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
269169689Skan	INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
270169689Skan	INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
271169689Skan	INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */
272169689Skan	INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */
273169689Skan	INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */
274169689Skan	INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */
275169689Skan	INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */
276169689Skan	INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */
277169689Skan	INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */
278169689Skan	INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */
279169689Skan	INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */
280169689Skan	INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */
281169689Skan	INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
282169689Skan	INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
283169689Skan	INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */
284169689Skan	{0, 0}
285169689Skan};
286169689Skan
287169689Skanstatic int i915_enable_unsupported;
288169689Skan
289169689Skanstatic int i915_drm_freeze(struct drm_device *dev)
290169689Skan{
291169689Skan	struct drm_i915_private *dev_priv;
292169689Skan	int error;
293169689Skan
294169689Skan	dev_priv = dev->dev_private;
295169689Skan	drm_kms_helper_poll_disable(dev);
296169689Skan
297169689Skan#if 0
298169689Skan	pci_save_state(dev->pdev);
299169689Skan#endif
300169689Skan
301169689Skan	/* If KMS is active, we do the leavevt stuff here */
302169689Skan	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
303169689Skan		error = i915_gem_idle(dev);
304169689Skan		if (error) {
305169689Skan			device_printf(dev->dev,
306169689Skan			    "GEM idle failed, resume might fail\n");
307169689Skan			return (error);
308169689Skan		}
309169689Skan		drm_irq_uninstall(dev);
310169689Skan	}
311169689Skan
312169689Skan	i915_save_state(dev);
313169689Skan
314169689Skan	intel_opregion_fini(dev);
315169689Skan
316169689Skan	/* Modeset on resume, not lid events */
317169689Skan	dev_priv->modeset_on_lid = 0;
318169689Skan
319169689Skan	return 0;
320169689Skan}
321169689Skan
322169689Skanstatic int
323169689Skani915_suspend(device_t kdev)
324169689Skan{
325169689Skan	struct drm_device *dev;
326169689Skan	int error;
327169689Skan
328169689Skan	dev = device_get_softc(kdev);
329169689Skan	if (dev == NULL || dev->dev_private == NULL) {
330169689Skan		DRM_ERROR("DRM not initialized, aborting suspend.\n");
331169689Skan		return ENODEV;
332169689Skan	}
333169689Skan
334169689Skan	DRM_DEBUG_KMS("starting suspend\n");
335169689Skan	error = i915_drm_freeze(dev);
336169689Skan	if (error)
337169689Skan		return (-error);
338169689Skan
339169689Skan	error = bus_generic_suspend(kdev);
340169689Skan	DRM_DEBUG_KMS("finished suspend %d\n", error);
341169689Skan	return (error);
342169689Skan}
343169689Skan
344169689Skanstatic int i915_drm_thaw(struct drm_device *dev)
345169689Skan{
346169689Skan	struct drm_i915_private *dev_priv = dev->dev_private;
347169689Skan	int error = 0;
348169689Skan
349169689Skan	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
350169689Skan		DRM_LOCK(dev);
351169689Skan		i915_gem_restore_gtt_mappings(dev);
352169689Skan		DRM_UNLOCK(dev);
353169689Skan	}
354169689Skan
355169689Skan	i915_restore_state(dev);
356169689Skan	intel_opregion_setup(dev);
357169689Skan
358169689Skan	/* KMS EnterVT equivalent */
359169689Skan	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
360169689Skan		if (HAS_PCH_SPLIT(dev))
361169689Skan			ironlake_init_pch_refclk(dev);
362169689Skan
363169689Skan		DRM_LOCK(dev);
364169689Skan		dev_priv->mm.suspended = 0;
365169689Skan
366169689Skan		error = i915_gem_init_hw(dev);
367169689Skan		DRM_UNLOCK(dev);
368169689Skan
369169689Skan		intel_modeset_init_hw(dev);
370169689Skan		sx_xlock(&dev->mode_config.mutex);
371169689Skan		drm_mode_config_reset(dev);
372169689Skan		sx_xunlock(&dev->mode_config.mutex);
373169689Skan		drm_irq_install(dev);
374169689Skan
375169689Skan		sx_xlock(&dev->mode_config.mutex);
376169689Skan		/* Resume the modeset for every activated CRTC */
377169689Skan		drm_helper_resume_force_mode(dev);
378169689Skan		sx_xunlock(&dev->mode_config.mutex);
379169689Skan	}
380169689Skan
381169689Skan	intel_opregion_init(dev);
382169689Skan
383169689Skan	dev_priv->modeset_on_lid = 0;
384169689Skan
385169689Skan	return error;
386169689Skan}
387169689Skan
388169689Skanstatic int
389169689Skani915_resume(device_t kdev)
390169689Skan{
391169689Skan	struct drm_device *dev;
392169689Skan	int ret;
393169689Skan
394169689Skan	dev = device_get_softc(kdev);
395169689Skan	DRM_DEBUG_KMS("starting resume\n");
396169689Skan#if 0
397169689Skan	if (pci_enable_device(dev->pdev))
398169689Skan		return -EIO;
399169689Skan
400169689Skan	pci_set_master(dev->pdev);
401169689Skan#endif
402169689Skan
403169689Skan	ret = i915_drm_thaw(dev);
404169689Skan	if (ret != 0)
405169689Skan		return (-ret);
406169689Skan
407169689Skan	drm_kms_helper_poll_enable(dev);
408169689Skan	ret = bus_generic_resume(kdev);
409169689Skan	DRM_DEBUG_KMS("finished resume %d\n", ret);
410169689Skan	return (ret);
411169689Skan}
412169689Skan
413169689Skanstatic int
414169689Skani915_probe(device_t kdev)
415169689Skan{
416169689Skan	const struct intel_device_info *info;
417169689Skan	int error;
418169689Skan
419169689Skan	error = drm_probe_helper(kdev, i915_pciidlist);
420169689Skan	if (error != 0)
421169689Skan		return (-error);
422169689Skan	info = i915_get_device_id(pci_get_device(kdev));
423169689Skan	if (info == NULL)
424169689Skan		return (ENXIO);
425169689Skan	return (0);
426169689Skan}
427169689Skan
428169689Skanint i915_modeset;
429169689Skan
430169689Skanstatic int
431169689Skani915_attach(device_t kdev)
432169689Skan{
433169689Skan
434169689Skan	if (i915_modeset == 1)
435169689Skan		i915_driver_info.driver_features |= DRIVER_MODESET;
436169689Skan	return (-drm_attach_helper(kdev, i915_pciidlist, &i915_driver_info));
437169689Skan}
438169689Skan
439169689Skanstatic struct fb_info *
440169689Skani915_fb_helper_getinfo(device_t kdev)
441169689Skan{
442169689Skan	struct intel_fbdev *ifbdev;
443169689Skan	drm_i915_private_t *dev_priv;
444169689Skan	struct drm_device *dev;
445169689Skan	struct fb_info *info;
446169689Skan
447169689Skan	dev = device_get_softc(kdev);
448169689Skan	dev_priv = dev->dev_private;
449169689Skan	ifbdev = dev_priv->fbdev;
450169689Skan	if (ifbdev == NULL)
451169689Skan		return (NULL);
452169689Skan
453169689Skan	info = ifbdev->helper.fbdev;
454169689Skan
455169689Skan	return (info);
456169689Skan}
457169689Skan
458169689Skanconst struct intel_device_info *
459169689Skani915_get_device_id(int device)
460169689Skan{
461169689Skan	const struct intel_gfx_device_id *did;
462169689Skan
463169689Skan	for (did = &pciidlist[0]; did->device != 0; did++) {
464169689Skan		if (did->device != device)
465169689Skan			continue;
466169689Skan		if (did->info->not_supported && !i915_enable_unsupported)
467169689Skan			return (NULL);
468169689Skan		return (did->info);
469169689Skan	}
470169689Skan	return (NULL);
471169689Skan}
472169689Skan
473169689Skanstatic device_method_t i915_methods[] = {
474169689Skan	/* Device interface */
475169689Skan	DEVMETHOD(device_probe,		i915_probe),
476169689Skan	DEVMETHOD(device_attach,	i915_attach),
477169689Skan	DEVMETHOD(device_suspend,	i915_suspend),
478169689Skan	DEVMETHOD(device_resume,	i915_resume),
479169689Skan	DEVMETHOD(device_detach,	drm_generic_detach),
480169689Skan
481169689Skan	/* Framebuffer service methods */
482169689Skan	DEVMETHOD(fb_getinfo,		i915_fb_helper_getinfo),
483169689Skan
484169689Skan	DEVMETHOD_END
485169689Skan};
486169689Skan
487169689Skanstatic driver_t i915_driver = {
488169689Skan	"drmn",
489169689Skan	i915_methods,
490169689Skan	sizeof(struct drm_device)
491169689Skan};
492169689Skan
493169689Skanextern devclass_t drm_devclass;
494169689SkanDRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0,
495169689Skan    SI_ORDER_ANY);
496169689SkanMODULE_DEPEND(i915kms, drmn, 1, 1, 1);
497169689SkanMODULE_DEPEND(i915kms, agp, 1, 1, 1);
498169689SkanMODULE_DEPEND(i915kms, iicbus, 1, 1, 1);
499169689SkanMODULE_DEPEND(i915kms, iic, 1, 1, 1);
500169689SkanMODULE_DEPEND(i915kms, iicbb, 1, 1, 1);
501169689Skan
502169689Skanint intel_iommu_enabled = 0;
503169689SkanTUNABLE_INT("drm.i915.intel_iommu_enabled", &intel_iommu_enabled);
504169689Skanint intel_iommu_gfx_mapped = 0;
505169689SkanTUNABLE_INT("drm.i915.intel_iommu_gfx_mapped", &intel_iommu_gfx_mapped);
506169689Skan
507169689Skanint i915_prefault_disable;
508169689SkanTUNABLE_INT("drm.i915.prefault_disable", &i915_prefault_disable);
509169689Skanint i915_semaphores = -1;
510169689SkanTUNABLE_INT("drm.i915.semaphores", &i915_semaphores);
511169689Skanstatic int i915_try_reset = 1;
512169689SkanTUNABLE_INT("drm.i915.try_reset", &i915_try_reset);
513169689Skanunsigned int i915_lvds_downclock = 0;
514169689SkanTUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock);
515169689Skanint i915_vbt_sdvo_panel_type = -1;
516169689SkanTUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type);
517169689Skanunsigned int i915_powersave = 1;
518169689SkanTUNABLE_INT("drm.i915.powersave", &i915_powersave);
519169689Skanint i915_enable_fbc = 0;
520169689SkanTUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc);
521169689Skanint i915_enable_rc6 = 0;
522169689SkanTUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6);
523169689Skanint i915_lvds_channel_mode;
524169689SkanTUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode);
525169689Skanint i915_panel_use_ssc = -1;
526169689SkanTUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc);
527169689Skanint i915_panel_ignore_lid = 0;
528169689SkanTUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid);
529169689Skanint i915_panel_invert_brightness;
530169689SkanTUNABLE_INT("drm.i915.panel_invert_brightness", &i915_panel_invert_brightness);
531169689Skanint i915_modeset = 1;
532169689SkanTUNABLE_INT("drm.i915.modeset", &i915_modeset);
533169689Skanint i915_enable_ppgtt = -1;
534169689SkanTUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt);
535169689Skanint i915_enable_hangcheck = 1;
536169689SkanTUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck);
537169689SkanTUNABLE_INT("drm.i915.enable_unsupported", &i915_enable_unsupported);
538169689Skan
539169689Skan#define	PCI_VENDOR_INTEL		0x8086
540169689Skan#define INTEL_PCH_DEVICE_ID_MASK	0xff00
541169689Skan#define INTEL_PCH_IBX_DEVICE_ID_TYPE	0x3b00
542169689Skan#define INTEL_PCH_CPT_DEVICE_ID_TYPE	0x1c00
543169689Skan#define INTEL_PCH_PPT_DEVICE_ID_TYPE	0x1e00
544169689Skan#define INTEL_PCH_LPT_DEVICE_ID_TYPE	0x8c00
545169689Skan
546169689Skanvoid intel_detect_pch(struct drm_device *dev)
547169689Skan{
548169689Skan	struct drm_i915_private *dev_priv;
549169689Skan	device_t pch;
550169689Skan	uint32_t id;
551169689Skan
552169689Skan	dev_priv = dev->dev_private;
553169689Skan	pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA);
554169689Skan	if (pch != NULL && pci_get_vendor(pch) == PCI_VENDOR_INTEL) {
555169689Skan		id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
556169689Skan		if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
557169689Skan			dev_priv->pch_type = PCH_IBX;
558169689Skan			dev_priv->num_pch_pll = 2;
559169689Skan			DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
560169689Skan		} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
561169689Skan			dev_priv->pch_type = PCH_CPT;
562169689Skan			dev_priv->num_pch_pll = 2;
563169689Skan			DRM_DEBUG_KMS("Found CougarPoint PCH\n");
564169689Skan		} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
565169689Skan			/* PantherPoint is CPT compatible */
566169689Skan			dev_priv->pch_type = PCH_CPT;
567169689Skan			dev_priv->num_pch_pll = 2;
568169689Skan			DRM_DEBUG_KMS("Found PatherPoint PCH\n");
569169689Skan		} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
570169689Skan			dev_priv->pch_type = PCH_LPT;
571169689Skan			dev_priv->num_pch_pll = 0;
572169689Skan			DRM_DEBUG_KMS("Found LynxPoint PCH\n");
573169689Skan		} else
574169689Skan			DRM_DEBUG_KMS("No PCH detected\n");
575169689Skan		KASSERT(dev_priv->num_pch_pll <= I915_NUM_PLLS,
576169689Skan		    ("num_pch_pll %d\n", dev_priv->num_pch_pll));
577169689Skan	} else
578169689Skan		DRM_DEBUG_KMS("No Intel PCI-ISA bridge found\n");
579169689Skan}
580169689Skan
581169689Skanbool i915_semaphore_is_enabled(struct drm_device *dev)
582169689Skan{
583169689Skan	if (INTEL_INFO(dev)->gen < 6)
584169689Skan		return 0;
585169689Skan
586169689Skan	if (i915_semaphores >= 0)
587169689Skan		return i915_semaphores;
588169689Skan
589169689Skan	/* Enable semaphores on SNB when IO remapping is off */
590169689Skan	if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
591169689Skan		return false;
592169689Skan
593169689Skan	return 1;
594169689Skan}
595169689Skan
596169689Skanvoid
597169689Skan__gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
598169689Skan{
599169689Skan	int count;
600169689Skan
601169689Skan	count = 0;
602169689Skan	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
603169689Skan		DELAY(10);
604169689Skan
605169689Skan	I915_WRITE_NOTRACE(FORCEWAKE, 1);
606169689Skan	POSTING_READ(FORCEWAKE);
607169689Skan
608169689Skan	count = 0;
609169689Skan	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
610169689Skan		DELAY(10);
611169689Skan}
612169689Skan
613169689Skanvoid
614169689Skan__gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
615169689Skan{
616169689Skan	int count;
617169689Skan
618169689Skan	count = 0;
619169689Skan	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
620169689Skan		DELAY(10);
621169689Skan
622169689Skan	I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
623169689Skan	POSTING_READ(FORCEWAKE_MT);
624169689Skan
625169689Skan	count = 0;
626169689Skan	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
627169689Skan		DELAY(10);
628169689Skan}
629169689Skan
630169689Skanvoid
631169689Skangen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
632169689Skan{
633169689Skan
634169689Skan	mtx_lock(&dev_priv->gt_lock);
635169689Skan	if (dev_priv->forcewake_count++ == 0)
636169689Skan		dev_priv->display.force_wake_get(dev_priv);
637169689Skan	mtx_unlock(&dev_priv->gt_lock);
638169689Skan}
639169689Skan
640169689Skanstatic void
641169689Skangen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
642169689Skan{
643169689Skan	u32 gtfifodbg;
644169689Skan
645169689Skan	gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
646169689Skan	if ((gtfifodbg & GT_FIFO_CPU_ERROR_MASK) != 0) {
647169689Skan		printf("MMIO read or write has been dropped %x\n", gtfifodbg);
648169689Skan		I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
649169689Skan	}
650169689Skan}
651169689Skan
652169689Skanvoid
653169689Skan__gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
654169689Skan{
655169689Skan
656169689Skan	I915_WRITE_NOTRACE(FORCEWAKE, 0);
657169689Skan	/* The below doubles as a POSTING_READ */
658169689Skan	gen6_gt_check_fifodbg(dev_priv);
659169689Skan}
660169689Skan
661169689Skanvoid
662169689Skan__gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
663169689Skan{
664169689Skan
665169689Skan	I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
666169689Skan	/* The below doubles as a POSTING_READ */
667169689Skan	gen6_gt_check_fifodbg(dev_priv);
668169689Skan}
669169689Skan
670169689Skanvoid
671169689Skangen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
672169689Skan{
673169689Skan
674169689Skan	mtx_lock(&dev_priv->gt_lock);
675169689Skan	if (--dev_priv->forcewake_count == 0)
676169689Skan 		dev_priv->display.force_wake_put(dev_priv);
677169689Skan	mtx_unlock(&dev_priv->gt_lock);
678169689Skan}
679169689Skan
680169689Skanint
681169689Skan__gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
682169689Skan{
683169689Skan	int ret = 0;
684169689Skan
685169689Skan	if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
686169689Skan		int loop = 500;
687169689Skan		u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
688169689Skan		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
689169689Skan			DELAY(10);
690169689Skan			fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
691169689Skan		}
692169689Skan		if (loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES) {
693169689Skan			printf("%s loop\n", __func__);
694169689Skan			++ret;
695169689Skan		}
696169689Skan		dev_priv->gt_fifo_count = fifo;
697169689Skan	}
698169689Skan	dev_priv->gt_fifo_count--;
699169689Skan
700169689Skan	return (ret);
701169689Skan}
702169689Skan
703169689Skanvoid vlv_force_wake_get(struct drm_i915_private *dev_priv)
704169689Skan{
705169689Skan	int count;
706169689Skan
707169689Skan	count = 0;
708169689Skan
709169689Skan	/* Already awake? */
710169689Skan	if ((I915_READ(0x130094) & 0xa1) == 0xa1)
711169689Skan		return;
712169689Skan
713169689Skan	I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff);
714169689Skan	POSTING_READ(FORCEWAKE_VLV);
715169689Skan
716169689Skan	count = 0;
717169689Skan	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0)
718169689Skan		DELAY(10);
719169689Skan}
720169689Skan
721169689Skanvoid vlv_force_wake_put(struct drm_i915_private *dev_priv)
722169689Skan{
723169689Skan	I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000);
724169689Skan	/* FIXME: confirm VLV behavior with Punit folks */
725169689Skan	POSTING_READ(FORCEWAKE_VLV);
726169689Skan}
727169689Skan
728169689Skanstatic int
729169689Skani8xx_do_reset(struct drm_device *dev)
730169689Skan{
731169689Skan	struct drm_i915_private *dev_priv = dev->dev_private;
732169689Skan	int onems;
733169689Skan
734169689Skan	if (IS_I85X(dev))
735169689Skan		return -ENODEV;
736169689Skan
737169689Skan	onems = hz / 1000;
738169689Skan	if (onems == 0)
739169689Skan		onems = 1;
740169689Skan
741169689Skan	I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
742169689Skan	POSTING_READ(D_STATE);
743169689Skan
744169689Skan	if (IS_I830(dev) || IS_845G(dev)) {
745169689Skan		I915_WRITE(DEBUG_RESET_I830,
746169689Skan			   DEBUG_RESET_DISPLAY |
747169689Skan			   DEBUG_RESET_RENDER |
748169689Skan			   DEBUG_RESET_FULL);
749169689Skan		POSTING_READ(DEBUG_RESET_I830);
750169689Skan		pause("i8xxrst1", onems);
751169689Skan
752169689Skan		I915_WRITE(DEBUG_RESET_I830, 0);
753169689Skan		POSTING_READ(DEBUG_RESET_I830);
754169689Skan	}
755169689Skan
756169689Skan	pause("i8xxrst2", onems);
757169689Skan
758169689Skan	I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
759169689Skan	POSTING_READ(D_STATE);
760169689Skan
761169689Skan	return 0;
762169689Skan}
763169689Skan
764169689Skanstatic int
765169689Skani965_reset_complete(struct drm_device *dev)
766169689Skan{
767169689Skan	u8 gdrst;
768169689Skan
769169689Skan	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
770169689Skan	return (gdrst & GRDOM_RESET_ENABLE) == 0;
771169689Skan}
772169689Skan
773169689Skanstatic int
774169689Skani965_do_reset(struct drm_device *dev)
775169689Skan{
776169689Skan	int ret;
777169689Skan	u8 gdrst;
778169689Skan
779169689Skan	/*
780169689Skan	 * Set the domains we want to reset (GRDOM/bits 2 and 3) as
781169689Skan	 * well as the reset bit (GR/bit 0).  Setting the GR bit
782169689Skan	 * triggers the reset; when done, the hardware will clear it.
783169689Skan	 */
784169689Skan	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
785169689Skan	pci_write_config(dev->dev, I965_GDRST,
786169689Skan	    gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE, 1);
787169689Skan
788169689Skan	ret =  wait_for(i965_reset_complete(dev), 500);
789169689Skan	if (ret)
790169689Skan		return ret;
791169689Skan
792169689Skan	/* We can't reset render&media without also resetting display ... */
793169689Skan	gdrst = pci_read_config(dev->dev, I965_GDRST, 1);
794169689Skan	pci_write_config(dev->dev, I965_GDRST,
795169689Skan			 gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE, 1);
796169689Skan
797169689Skan 	return wait_for(i965_reset_complete(dev), 500);
798169689Skan}
799169689Skan
800169689Skanstatic int
801169689Skanironlake_do_reset(struct drm_device *dev)
802169689Skan{
803169689Skan	struct drm_i915_private *dev_priv;
804169689Skan	u32 gdrst;
805169689Skan	int ret;
806169689Skan
807169689Skan	dev_priv = dev->dev_private;
808169689Skan	gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
809169689Skan	I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
810169689Skan		   gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE);
811169689Skan	ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
812169689Skan	if (ret)
813169689Skan		return ret;
814169689Skan
815169689Skan	/* We can't reset render&media without also resetting display ... */
816169689Skan	gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
817169689Skan	I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR,
818169689Skan		   gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE);
819169689Skan 	return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
820169689Skan}
821169689Skan
822169689Skanstatic int
823169689Skangen6_do_reset(struct drm_device *dev)
824169689Skan{
825169689Skan	struct drm_i915_private *dev_priv;
826169689Skan	int ret;
827169689Skan
828169689Skan	dev_priv = dev->dev_private;
829169689Skan
830169689Skan	/* Hold gt_lock across reset to prevent any register access
831169689Skan	 * with forcewake not set correctly
832169689Skan	 */
833169689Skan	mtx_lock(&dev_priv->gt_lock);
834169689Skan
835169689Skan	/* Reset the chip */
836169689Skan
837169689Skan	/* GEN6_GDRST is not in the gt power well, no need to check
838169689Skan	 * for fifo space for the write or forcewake the chip for
839169689Skan	 * the read
840169689Skan	 */
841169689Skan	I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
842169689Skan
843169689Skan	/* Spin waiting for the device to ack the reset request */
844169689Skan	ret = _intel_wait_for(dev,
845169689Skan	    (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0,
846169689Skan	    500, 0, "915rst");
847169689Skan
848169689Skan	/* If reset with a user forcewake, try to restore, otherwise turn it off */
849169689Skan 	if (dev_priv->forcewake_count)
850169689Skan 		dev_priv->display.force_wake_get(dev_priv);
851169689Skan	else
852169689Skan		dev_priv->display.force_wake_put(dev_priv);
853169689Skan
854169689Skan	/* Restore fifo count */
855169689Skan	dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
856169689Skan
857169689Skan	mtx_unlock(&dev_priv->gt_lock);
858169689Skan	return (ret);
859169689Skan}
860169689Skan
861169689Skanint
862169689Skanintel_gpu_reset(struct drm_device *dev)
863169689Skan{
864169689Skan	struct drm_i915_private *dev_priv = dev->dev_private;
865169689Skan	int ret = -ENODEV;
866169689Skan
867169689Skan	switch (INTEL_INFO(dev)->gen) {
868169689Skan	case 7:
869169689Skan	case 6:
870169689Skan		ret = gen6_do_reset(dev);
871169689Skan		break;
872169689Skan	case 5:
873169689Skan		ret = ironlake_do_reset(dev);
874169689Skan		break;
875169689Skan	case 4:
876169689Skan		ret = i965_do_reset(dev);
877169689Skan		break;
878169689Skan	case 2:
879169689Skan		ret = i8xx_do_reset(dev);
880169689Skan		break;
881169689Skan	}
882169689Skan
883169689Skan	/* Also reset the gpu hangman. */
884169689Skan	if (dev_priv->stop_rings) {
885169689Skan		DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n");
886169689Skan		dev_priv->stop_rings = 0;
887169689Skan		if (ret == -ENODEV) {
888169689Skan			DRM_ERROR("Reset not implemented, but ignoring "
889169689Skan				  "error for simulated gpu hangs\n");
890169689Skan			ret = 0;
891169689Skan		}
892169689Skan	}
893169689Skan
894169689Skan	return ret;
895169689Skan}
896169689Skan
897169689Skanint i915_reset(struct drm_device *dev)
898169689Skan{
899169689Skan	drm_i915_private_t *dev_priv = dev->dev_private;
900169689Skan	int ret;
901169689Skan
902169689Skan	if (!i915_try_reset)
903169689Skan		return (0);
904169689Skan
905169689Skan	if (!sx_try_xlock(&dev->dev_struct_lock))
906169689Skan		return (-EBUSY);
907169689Skan
908169689Skan	dev_priv->stop_rings = 0;
909169689Skan
910169689Skan	i915_gem_reset(dev);
911169689Skan
912169689Skan	ret = -ENODEV;
913169689Skan	if (time_second - dev_priv->last_gpu_reset < 5)
914169689Skan		DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
915169689Skan	else
916169689Skan		ret = intel_gpu_reset(dev);
917169689Skan
918169689Skan	dev_priv->last_gpu_reset = time_second;
919169689Skan	if (ret) {
920169689Skan		DRM_ERROR("Failed to reset chip.\n");
921169689Skan		DRM_UNLOCK(dev);
922169689Skan		return (ret);
923169689Skan	}
924169689Skan
925169689Skan	if (drm_core_check_feature(dev, DRIVER_MODESET) ||
926169689Skan	    !dev_priv->mm.suspended) {
927169689Skan		struct intel_ring_buffer *ring;
928169689Skan		int i;
929169689Skan
930169689Skan		dev_priv->mm.suspended = 0;
931169689Skan
932169689Skan		i915_gem_init_swizzling(dev);
933169689Skan
934169689Skan		for_each_ring(ring, dev_priv, i)
935169689Skan			ring->init(ring);
936169689Skan
937169689Skan		i915_gem_context_init(dev);
938169689Skan		i915_gem_init_ppgtt(dev);
939169689Skan
940169689Skan		DRM_UNLOCK(dev);
941169689Skan
942169689Skan		if (drm_core_check_feature(dev, DRIVER_MODESET))
943169689Skan			intel_modeset_init_hw(dev);
944169689Skan
945169689Skan		drm_irq_uninstall(dev);
946169689Skan		drm_irq_install(dev);
947169689Skan	} else
948169689Skan		DRM_UNLOCK(dev);
949169689Skan
950169689Skan	return (0);
951169689Skan}
952169689Skan
953169689Skan/* We give fast paths for the really cool registers */
954169689Skan#define NEEDS_FORCE_WAKE(dev_priv, reg) \
955169689Skan       (((dev_priv)->info->gen >= 6) && \
956169689Skan        ((reg) < 0x40000) &&            \
957169689Skan        ((reg) != FORCEWAKE)) && \
958169689Skan       (!IS_VALLEYVIEW((dev_priv)->dev))
959169689Skan
960169689Skan#define __i915_read(x, y) \
961169689Skanu##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
962169689Skan	u##x val = 0; \
963169689Skan	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
964169689Skan		mtx_lock(&dev_priv->gt_lock); \
965169689Skan		if (dev_priv->forcewake_count == 0) \
966169689Skan			dev_priv->display.force_wake_get(dev_priv); \
967169689Skan		val = DRM_READ##y(dev_priv->mmio_map, reg);	\
968169689Skan		if (dev_priv->forcewake_count == 0) \
969169689Skan			dev_priv->display.force_wake_put(dev_priv); \
970169689Skan		mtx_unlock(&dev_priv->gt_lock); \
971169689Skan	} else { \
972169689Skan		val = DRM_READ##y(dev_priv->mmio_map, reg);	\
973169689Skan	} \
974169689Skan	trace_i915_reg_rw(false, reg, val, sizeof(val)); \
975169689Skan	return val; \
976169689Skan}
977169689Skan
978169689Skan__i915_read(8, 8)
979169689Skan__i915_read(16, 16)
980169689Skan__i915_read(32, 32)
981169689Skan__i915_read(64, 64)
982169689Skan#undef __i915_read
983169689Skan
984169689Skan#define __i915_write(x, y) \
985169689Skanvoid i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
986169689Skan	u32 __fifo_ret = 0; \
987169689Skan	trace_i915_reg_rw(true, reg, val, sizeof(val)); \
988169689Skan	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
989169689Skan		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
990169689Skan	} \
991169689Skan	DRM_WRITE##y(dev_priv->mmio_map, reg, val); \
992169689Skan	if (__predict_false(__fifo_ret)) { \
993169689Skan		gen6_gt_check_fifodbg(dev_priv); \
994169689Skan	} \
995169689Skan}
996169689Skan__i915_write(8, 8)
997169689Skan__i915_write(16, 16)
998169689Skan__i915_write(32, 32)
999169689Skan__i915_write(64, 64)
1000169689Skan#undef __i915_write
1001169689Skan