1c4a9e910SFrançois Tigeot /* i915_drv.c -- Intel i915 driver -*- linux-c -*- 2c4a9e910SFrançois Tigeot * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com 3c4a9e910SFrançois Tigeot */ 4c4a9e910SFrançois Tigeot /*- 5c4a9e910SFrançois Tigeot * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6c4a9e910SFrançois Tigeot * All Rights Reserved. 7c4a9e910SFrançois Tigeot * 8c4a9e910SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 9c4a9e910SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 10c4a9e910SFrançois Tigeot * to deal in the Software without restriction, including without limitation 11c4a9e910SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12c4a9e910SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 13c4a9e910SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 14c4a9e910SFrançois Tigeot * 15c4a9e910SFrançois Tigeot * The above copyright notice and this permission notice (including the next 16c4a9e910SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 17c4a9e910SFrançois Tigeot * Software. 18c4a9e910SFrançois Tigeot * 19c4a9e910SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20c4a9e910SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21c4a9e910SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22c4a9e910SFrançois Tigeot * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23c4a9e910SFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24c4a9e910SFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25c4a9e910SFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE. 26c4a9e910SFrançois Tigeot * 27c4a9e910SFrançois Tigeot * Authors: 28c4a9e910SFrançois Tigeot * Gareth Hughes <gareth@valinux.com> 29c4a9e910SFrançois Tigeot * 30e3adcf8fSFrançois Tigeot * $FreeBSD: src/sys/dev/drm2/i915/i915_drv.c,v 1.1 2012/05/22 11:07:44 kib Exp $ 31c4a9e910SFrançois Tigeot */ 32c4a9e910SFrançois Tigeot 3318e26a6dSFrançois Tigeot #include <drm/drmP.h> 345c6c6f23SFrançois Tigeot #include <drm/i915_drm.h> 35c4a9e910SFrançois Tigeot #include "i915_drv.h" 3618e26a6dSFrançois Tigeot #include <drm/drm_pciids.h> 37e3adcf8fSFrançois Tigeot #include "intel_drv.h" 38c4a9e910SFrançois Tigeot 3919df918dSFrançois Tigeot /* "Specify LVDS channel mode " 4019df918dSFrançois Tigeot "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)" */ 4119df918dSFrançois Tigeot int i915_lvds_channel_mode __read_mostly = 0; 4219df918dSFrançois Tigeot TUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode); 4319df918dSFrançois Tigeot 44*f0b54121SFrançois Tigeot static struct drm_driver driver; 45*f0b54121SFrançois Tigeot 46e9243325SFrançois Tigeot #define INTEL_VGA_DEVICE(id, info_) { \ 47e9243325SFrançois Tigeot .device = id, \ 48e9243325SFrançois Tigeot .info = info_, \ 49e9243325SFrançois Tigeot } 50e9243325SFrançois Tigeot 51e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i830_info = { 52e3adcf8fSFrançois Tigeot .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, 53e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 54e3adcf8fSFrançois Tigeot }; 55c4a9e910SFrançois Tigeot 56e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_845g_info = { 57e3adcf8fSFrançois Tigeot .gen = 2, 58e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 59e3adcf8fSFrançois Tigeot }; 60e3adcf8fSFrançois Tigeot 61e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i85x_info = { 62e3adcf8fSFrançois Tigeot .gen = 2, .is_i85x = 1, .is_mobile = 1, 63e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 64e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 65e3adcf8fSFrançois Tigeot }; 66e3adcf8fSFrançois Tigeot 67e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i865g_info = { 68e3adcf8fSFrançois Tigeot .gen = 2, 69e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 70e3adcf8fSFrançois Tigeot }; 71e3adcf8fSFrançois Tigeot 72e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915g_info = { 73e3adcf8fSFrançois Tigeot .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, 74e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 75e3adcf8fSFrançois Tigeot }; 76e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915gm_info = { 77e3adcf8fSFrançois Tigeot .gen = 3, .is_mobile = 1, 78e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 79e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 80e3adcf8fSFrançois Tigeot .supports_tv = 1, 81e3adcf8fSFrançois Tigeot }; 82e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945g_info = { 83e3adcf8fSFrançois Tigeot .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, 84e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 85e3adcf8fSFrançois Tigeot }; 86e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945gm_info = { 87e3adcf8fSFrançois Tigeot .gen = 3, .is_i945gm = 1, .is_mobile = 1, 88e3adcf8fSFrançois Tigeot .has_hotplug = 1, .cursor_needs_physical = 1, 89e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 90e3adcf8fSFrançois Tigeot .supports_tv = 1, 91e3adcf8fSFrançois Tigeot }; 92e3adcf8fSFrançois Tigeot 93e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965g_info = { 94e3adcf8fSFrançois Tigeot .gen = 4, .is_broadwater = 1, 95e3adcf8fSFrançois Tigeot .has_hotplug = 1, 96e3adcf8fSFrançois Tigeot .has_overlay = 1, 97e3adcf8fSFrançois Tigeot }; 98e3adcf8fSFrançois Tigeot 99e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965gm_info = { 100e3adcf8fSFrançois Tigeot .gen = 4, .is_crestline = 1, 101e3adcf8fSFrançois Tigeot .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, 102e3adcf8fSFrançois Tigeot .has_overlay = 1, 103e3adcf8fSFrançois Tigeot .supports_tv = 1, 104e3adcf8fSFrançois Tigeot }; 105e3adcf8fSFrançois Tigeot 106e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g33_info = { 107e3adcf8fSFrançois Tigeot .gen = 3, .is_g33 = 1, 108e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 109e3adcf8fSFrançois Tigeot .has_overlay = 1, 110e3adcf8fSFrançois Tigeot }; 111e3adcf8fSFrançois Tigeot 112e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g45_info = { 113e3adcf8fSFrançois Tigeot .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, 114e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 115e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 116e3adcf8fSFrançois Tigeot }; 117e3adcf8fSFrançois Tigeot 118e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_gm45_info = { 119e3adcf8fSFrançois Tigeot .gen = 4, .is_g4x = 1, 120e3adcf8fSFrançois Tigeot .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, 121e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 122e3adcf8fSFrançois Tigeot .supports_tv = 1, 123e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 124e3adcf8fSFrançois Tigeot }; 125e3adcf8fSFrançois Tigeot 126e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_pineview_info = { 127e3adcf8fSFrançois Tigeot .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, 128e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 129e3adcf8fSFrançois Tigeot .has_overlay = 1, 130e3adcf8fSFrançois Tigeot }; 131e3adcf8fSFrançois Tigeot 132e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_d_info = { 133e3adcf8fSFrançois Tigeot .gen = 5, 134e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 135e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 136e3adcf8fSFrançois Tigeot }; 137e3adcf8fSFrançois Tigeot 138e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_m_info = { 139e3adcf8fSFrançois Tigeot .gen = 5, .is_mobile = 1, 140e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 14100dca1bbSFrançois Tigeot .has_fbc = 1, 142e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 143e3adcf8fSFrançois Tigeot }; 144e3adcf8fSFrançois Tigeot 145e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_d_info = { 146e3adcf8fSFrançois Tigeot .gen = 6, 147e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 148e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 149e3adcf8fSFrançois Tigeot .has_blt_ring = 1, 150e3adcf8fSFrançois Tigeot .has_llc = 1, 151e9243325SFrançois Tigeot .has_force_wake = 1, 152e3adcf8fSFrançois Tigeot }; 153e3adcf8fSFrançois Tigeot 154e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_m_info = { 155e3adcf8fSFrançois Tigeot .gen = 6, .is_mobile = 1, 156e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 157e3adcf8fSFrançois Tigeot .has_fbc = 1, 158e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 159e3adcf8fSFrançois Tigeot .has_blt_ring = 1, 160e3adcf8fSFrançois Tigeot .has_llc = 1, 161e9243325SFrançois Tigeot .has_force_wake = 1, 162e3adcf8fSFrançois Tigeot }; 163e3adcf8fSFrançois Tigeot 164e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_d_info = { 165e3adcf8fSFrançois Tigeot .is_ivybridge = 1, .gen = 7, 166e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 167e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 168e3adcf8fSFrançois Tigeot .has_blt_ring = 1, 169e3adcf8fSFrançois Tigeot .has_llc = 1, 170e9243325SFrançois Tigeot .has_force_wake = 1, 171e3adcf8fSFrançois Tigeot }; 172e3adcf8fSFrançois Tigeot 173e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_m_info = { 174e3adcf8fSFrançois Tigeot .is_ivybridge = 1, .gen = 7, .is_mobile = 1, 175e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 176e3adcf8fSFrançois Tigeot .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ 177e3adcf8fSFrançois Tigeot .has_bsd_ring = 1, 178e3adcf8fSFrançois Tigeot .has_blt_ring = 1, 179e3adcf8fSFrançois Tigeot .has_llc = 1, 180e9243325SFrançois Tigeot .has_force_wake = 1, 181e3adcf8fSFrançois Tigeot }; 182e3adcf8fSFrançois Tigeot 183e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_m_info = { 184e9243325SFrançois Tigeot .gen = 7, .is_mobile = 1, 185e9243325SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 186e9243325SFrançois Tigeot .has_fbc = 0, 187e9243325SFrançois Tigeot .has_bsd_ring = 1, 188e9243325SFrançois Tigeot .has_blt_ring = 1, 189e9243325SFrançois Tigeot .is_valleyview = 1, 190e9243325SFrançois Tigeot }; 191e9243325SFrançois Tigeot 192e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_d_info = { 193e9243325SFrançois Tigeot .gen = 7, 194e9243325SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 195e9243325SFrançois Tigeot .has_fbc = 0, 196e9243325SFrançois Tigeot .has_bsd_ring = 1, 197e9243325SFrançois Tigeot .has_blt_ring = 1, 198e9243325SFrançois Tigeot .is_valleyview = 1, 199e9243325SFrançois Tigeot }; 200e9243325SFrançois Tigeot 201e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_d_info = { 202e9243325SFrançois Tigeot .is_haswell = 1, .gen = 7, 203e9243325SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 204e9243325SFrançois Tigeot .has_bsd_ring = 1, 205e9243325SFrançois Tigeot .has_blt_ring = 1, 206e9243325SFrançois Tigeot .has_llc = 1, 207e9243325SFrançois Tigeot .has_force_wake = 1, 208e9243325SFrançois Tigeot }; 209e9243325SFrançois Tigeot 210e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_m_info = { 211e9243325SFrançois Tigeot .is_haswell = 1, .gen = 7, .is_mobile = 1, 212e9243325SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 213e9243325SFrançois Tigeot .has_bsd_ring = 1, 214e9243325SFrançois Tigeot .has_blt_ring = 1, 215e9243325SFrançois Tigeot .has_llc = 1, 216e9243325SFrançois Tigeot .has_force_wake = 1, 217e9243325SFrançois Tigeot }; 218e3adcf8fSFrançois Tigeot 219e3adcf8fSFrançois Tigeot static const struct intel_gfx_device_id { 220e3adcf8fSFrançois Tigeot int device; 221e3adcf8fSFrançois Tigeot const struct intel_device_info *info; 222e3adcf8fSFrançois Tigeot } pciidlist[] = { /* aka */ 223e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ 224e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ 225e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ 226e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), 227e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ 228e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ 229e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ 230e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ 231e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ 232e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ 233e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ 234e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ 235e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ 236e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ 237e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ 238e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ 239e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ 240e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ 241e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ 242e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ 243e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ 244e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ 245e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ 246e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ 247e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ 248e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ 249e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ 250e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), 251e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), 252e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), 253e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), 254e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), 255e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), 256e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), 257e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), 258e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), 259e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), 260e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), 261e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ 262e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ 263e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ 264e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ 265e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ 266e3adcf8fSFrançois Tigeot INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ 267e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ 268e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ 269e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ 270e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ 271e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ 272e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ 273e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ 274e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ 275e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ 276e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ 277e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ 278e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ 279e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ 280e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ 281e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ 282e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ 283e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ 284e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ 285e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ 286e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ 287e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ 288e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ 289e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ 290e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ 291e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ 292e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ 293e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ 294e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */ 295e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */ 296e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ 297e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */ 298e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */ 299e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ 300e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ 301e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ 302e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ 303e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), 304e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), 305e9243325SFrançois Tigeot INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), 306e3adcf8fSFrançois Tigeot {0, 0} 307e3adcf8fSFrançois Tigeot }; 308e3adcf8fSFrançois Tigeot 309e9243325SFrançois Tigeot #define PCI_VENDOR_INTEL 0x8086 310e9243325SFrançois Tigeot 311e9243325SFrançois Tigeot void intel_detect_pch(struct drm_device *dev) 312e9243325SFrançois Tigeot { 313e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 314e9243325SFrançois Tigeot device_t pch; 315e9243325SFrançois Tigeot 316e9243325SFrançois Tigeot /* 317e9243325SFrançois Tigeot * The reason to probe ISA bridge instead of Dev31:Fun0 is to 318e9243325SFrançois Tigeot * make graphics device passthrough work easy for VMM, that only 319e9243325SFrançois Tigeot * need to expose ISA bridge to let driver know the real hardware 320e9243325SFrançois Tigeot * underneath. This is a requirement from virtualization team. 321e9243325SFrançois Tigeot */ 322e9243325SFrançois Tigeot pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA); 323e9243325SFrançois Tigeot if (pch) { 324e9243325SFrançois Tigeot if (pci_get_vendor(pch) == PCI_VENDOR_INTEL) { 325e9243325SFrançois Tigeot unsigned short id; 326e9243325SFrançois Tigeot id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; 327e9243325SFrançois Tigeot dev_priv->pch_id = id; 328e9243325SFrançois Tigeot 329e9243325SFrançois Tigeot if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { 330e9243325SFrançois Tigeot dev_priv->pch_type = PCH_IBX; 331e9243325SFrançois Tigeot dev_priv->num_pch_pll = 2; 332e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); 333e9243325SFrançois Tigeot WARN_ON(!IS_GEN5(dev)); 334e9243325SFrançois Tigeot } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { 335e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 336e9243325SFrançois Tigeot dev_priv->num_pch_pll = 2; 337e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found CougarPoint PCH\n"); 338e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 339e9243325SFrançois Tigeot } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { 340e9243325SFrançois Tigeot /* PantherPoint is CPT compatible */ 341e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 342e9243325SFrançois Tigeot dev_priv->num_pch_pll = 2; 343e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found PatherPoint PCH\n"); 344e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 345e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { 346e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 347e9243325SFrançois Tigeot dev_priv->num_pch_pll = 0; 348e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint PCH\n"); 349e9243325SFrançois Tigeot WARN_ON(!IS_HASWELL(dev)); 350e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { 351e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 352e9243325SFrançois Tigeot dev_priv->num_pch_pll = 0; 353e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); 354e9243325SFrançois Tigeot WARN_ON(!IS_HASWELL(dev)); 355e9243325SFrançois Tigeot } 356e9243325SFrançois Tigeot BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS); 357e9243325SFrançois Tigeot } 358e9243325SFrançois Tigeot #if 0 359e9243325SFrançois Tigeot pci_dev_put(pch); 360e9243325SFrançois Tigeot #endif 361e9243325SFrançois Tigeot } 362e9243325SFrançois Tigeot } 363e9243325SFrançois Tigeot 3643d4007e0SFrançois Tigeot bool i915_semaphore_is_enabled(struct drm_device *dev) 3653d4007e0SFrançois Tigeot { 3663d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen < 6) 3673d4007e0SFrançois Tigeot return 0; 3683d4007e0SFrançois Tigeot 3693d4007e0SFrançois Tigeot if (i915_semaphores >= 0) 3703d4007e0SFrançois Tigeot return i915_semaphores; 3713d4007e0SFrançois Tigeot 3723d4007e0SFrançois Tigeot #ifdef CONFIG_INTEL_IOMMU 3733d4007e0SFrançois Tigeot /* Enable semaphores on SNB when IO remapping is off */ 3743d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) 3753d4007e0SFrançois Tigeot return false; 3763d4007e0SFrançois Tigeot #endif 3773d4007e0SFrançois Tigeot 3783d4007e0SFrançois Tigeot return 1; 3793d4007e0SFrançois Tigeot } 3803d4007e0SFrançois Tigeot 381e3adcf8fSFrançois Tigeot static int i915_drm_freeze(struct drm_device *dev) 382e3adcf8fSFrançois Tigeot { 383e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 384e3adcf8fSFrançois Tigeot 385e3adcf8fSFrançois Tigeot drm_kms_helper_poll_disable(dev); 386e3adcf8fSFrançois Tigeot 387e3adcf8fSFrançois Tigeot #if 0 388e3adcf8fSFrançois Tigeot pci_save_state(dev->pdev); 389e3adcf8fSFrançois Tigeot #endif 390e3adcf8fSFrançois Tigeot 391e3adcf8fSFrançois Tigeot /* If KMS is active, we do the leavevt stuff here */ 392e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) { 393e9243325SFrançois Tigeot int error = i915_gem_idle(dev); 394e3adcf8fSFrançois Tigeot if (error) { 3956df74fa7SFrançois Tigeot device_printf(dev->dev, 396e9243325SFrançois Tigeot "GEM idle failed, resume might fail"); 397e9243325SFrançois Tigeot return error; 398e3adcf8fSFrançois Tigeot } 399e9243325SFrançois Tigeot cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); 400e9243325SFrançois Tigeot 401e9243325SFrançois Tigeot #if 0 402e9243325SFrançois Tigeot intel_modeset_disable(dev); 403e9243325SFrançois Tigeot #endif 404e9243325SFrançois Tigeot 405e3adcf8fSFrançois Tigeot drm_irq_uninstall(dev); 406e3adcf8fSFrançois Tigeot } 407e3adcf8fSFrançois Tigeot 408e3adcf8fSFrançois Tigeot i915_save_state(dev); 409e3adcf8fSFrançois Tigeot 410e3adcf8fSFrançois Tigeot intel_opregion_fini(dev); 411e3adcf8fSFrançois Tigeot 412e3adcf8fSFrançois Tigeot /* Modeset on resume, not lid events */ 413e3adcf8fSFrançois Tigeot dev_priv->modeset_on_lid = 0; 414e3adcf8fSFrançois Tigeot 415e3adcf8fSFrançois Tigeot return 0; 416e3adcf8fSFrançois Tigeot } 417e3adcf8fSFrançois Tigeot 418e3adcf8fSFrançois Tigeot static int 419e3adcf8fSFrançois Tigeot i915_suspend(device_t kdev) 420e3adcf8fSFrançois Tigeot { 421e3adcf8fSFrançois Tigeot struct drm_device *dev; 422e3adcf8fSFrançois Tigeot int error; 423e3adcf8fSFrançois Tigeot 424e3adcf8fSFrançois Tigeot dev = device_get_softc(kdev); 425e3adcf8fSFrançois Tigeot if (dev == NULL || dev->dev_private == NULL) { 426c4a9e910SFrançois Tigeot DRM_ERROR("DRM not initialized, aborting suspend.\n"); 427c4a9e910SFrançois Tigeot return -ENODEV; 428c4a9e910SFrançois Tigeot } 429c4a9e910SFrançois Tigeot 430e3adcf8fSFrançois Tigeot DRM_DEBUG_KMS("starting suspend\n"); 431e3adcf8fSFrançois Tigeot error = i915_drm_freeze(dev); 432e3adcf8fSFrançois Tigeot if (error) 433e3adcf8fSFrançois Tigeot return (error); 434c4a9e910SFrançois Tigeot 435e3adcf8fSFrançois Tigeot error = bus_generic_suspend(kdev); 436e3adcf8fSFrançois Tigeot DRM_DEBUG_KMS("finished suspend %d\n", error); 437e3adcf8fSFrançois Tigeot return (error); 438c4a9e910SFrançois Tigeot } 439c4a9e910SFrançois Tigeot 440e3adcf8fSFrançois Tigeot static int i915_drm_thaw(struct drm_device *dev) 441c4a9e910SFrançois Tigeot { 442e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 443e3adcf8fSFrançois Tigeot int error = 0; 444c4a9e910SFrançois Tigeot 44519df918dSFrançois Tigeot intel_gt_reset(dev); 44619df918dSFrançois Tigeot 447e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) { 44819df918dSFrançois Tigeot DRM_LOCK(dev); 449e3adcf8fSFrançois Tigeot i915_gem_restore_gtt_mappings(dev); 45019df918dSFrançois Tigeot DRM_UNLOCK(dev); 451e3adcf8fSFrançois Tigeot } 452e3adcf8fSFrançois Tigeot 453c4a9e910SFrançois Tigeot i915_restore_state(dev); 454e3adcf8fSFrançois Tigeot intel_opregion_setup(dev); 455c4a9e910SFrançois Tigeot 456e3adcf8fSFrançois Tigeot /* KMS EnterVT equivalent */ 457e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) { 45819df918dSFrançois Tigeot intel_init_pch_refclk(dev); 45919df918dSFrançois Tigeot 46019df918dSFrançois Tigeot DRM_LOCK(dev); 461e3adcf8fSFrançois Tigeot dev_priv->mm.suspended = 0; 462e3adcf8fSFrançois Tigeot 463e3adcf8fSFrançois Tigeot error = i915_gem_init_hw(dev); 464e3adcf8fSFrançois Tigeot DRM_UNLOCK(dev); 46519df918dSFrançois Tigeot 46619df918dSFrançois Tigeot intel_modeset_init_hw(dev); 46719df918dSFrançois Tigeot intel_modeset_setup_hw_state(dev, false); 468e3adcf8fSFrançois Tigeot drm_irq_install(dev); 469c4a9e910SFrançois Tigeot } 470c4a9e910SFrançois Tigeot 471e3adcf8fSFrançois Tigeot intel_opregion_init(dev); 472e3adcf8fSFrançois Tigeot 473e3adcf8fSFrançois Tigeot dev_priv->modeset_on_lid = 0; 474e3adcf8fSFrançois Tigeot 47519df918dSFrançois Tigeot #if 0 47619df918dSFrançois Tigeot console_lock(); 47719df918dSFrançois Tigeot intel_fbdev_set_suspend(dev, 0); 47819df918dSFrançois Tigeot console_unlock(); 47919df918dSFrançois Tigeot #endif 480e3adcf8fSFrançois Tigeot return error; 481e3adcf8fSFrançois Tigeot } 482e3adcf8fSFrançois Tigeot 483e3adcf8fSFrançois Tigeot static int 484e3adcf8fSFrançois Tigeot i915_resume(device_t kdev) 485c4a9e910SFrançois Tigeot { 486e3adcf8fSFrançois Tigeot struct drm_device *dev; 487e3adcf8fSFrançois Tigeot int ret; 488c4a9e910SFrançois Tigeot 489e3adcf8fSFrançois Tigeot dev = device_get_softc(kdev); 490e3adcf8fSFrançois Tigeot DRM_DEBUG_KMS("starting resume\n"); 491e3adcf8fSFrançois Tigeot #if 0 492e3adcf8fSFrançois Tigeot if (pci_enable_device(dev->pdev)) 493e3adcf8fSFrançois Tigeot return -EIO; 494c4a9e910SFrançois Tigeot 495e3adcf8fSFrançois Tigeot pci_set_master(dev->pdev); 496e3adcf8fSFrançois Tigeot #endif 497c4a9e910SFrançois Tigeot 498e3adcf8fSFrançois Tigeot ret = -i915_drm_thaw(dev); 499e3adcf8fSFrançois Tigeot if (ret != 0) 500e3adcf8fSFrançois Tigeot return (ret); 501e3adcf8fSFrançois Tigeot 502e3adcf8fSFrançois Tigeot drm_kms_helper_poll_enable(dev); 503e3adcf8fSFrançois Tigeot ret = bus_generic_resume(kdev); 504e3adcf8fSFrançois Tigeot DRM_DEBUG_KMS("finished resume %d\n", ret); 505e3adcf8fSFrançois Tigeot return (ret); 506c4a9e910SFrançois Tigeot } 507c4a9e910SFrançois Tigeot 50862e5f8e8SFrançois Tigeot /* XXX Hack for the old *BSD drm code base 50962e5f8e8SFrançois Tigeot * The device id field is set at probe time */ 51062e5f8e8SFrançois Tigeot static drm_pci_id_list_t i915_attach_list[] = { 51162e5f8e8SFrançois Tigeot {0x8086, 0, 0, "Intel i915 GPU"}, 51262e5f8e8SFrançois Tigeot {0, 0, 0, NULL} 51362e5f8e8SFrançois Tigeot }; 51462e5f8e8SFrançois Tigeot 515c4a9e910SFrançois Tigeot static int 516c4a9e910SFrançois Tigeot i915_probe(device_t kdev) 517c4a9e910SFrançois Tigeot { 51862e5f8e8SFrançois Tigeot int device, i = 0; 519e3adcf8fSFrançois Tigeot 52062e5f8e8SFrançois Tigeot if (pci_get_class(kdev) != PCIC_DISPLAY) 52162e5f8e8SFrançois Tigeot return ENXIO; 52262e5f8e8SFrançois Tigeot 52362e5f8e8SFrançois Tigeot if (pci_get_vendor(kdev) != PCI_VENDOR_INTEL) 52462e5f8e8SFrançois Tigeot return ENXIO; 52562e5f8e8SFrançois Tigeot 52662e5f8e8SFrançois Tigeot device = pci_get_device(kdev); 52762e5f8e8SFrançois Tigeot 52862e5f8e8SFrançois Tigeot for (i = 0; pciidlist[i].device != 0; i++) { 52962e5f8e8SFrançois Tigeot if (pciidlist[i].device == device) { 53062e5f8e8SFrançois Tigeot i915_attach_list[0].device = device; 53162e5f8e8SFrançois Tigeot return 0; 53262e5f8e8SFrançois Tigeot } 53362e5f8e8SFrançois Tigeot } 53462e5f8e8SFrançois Tigeot 53562e5f8e8SFrançois Tigeot return ENXIO; 536c4a9e910SFrançois Tigeot } 537c4a9e910SFrançois Tigeot 538e3adcf8fSFrançois Tigeot int i915_modeset; 539e3adcf8fSFrançois Tigeot 540*f0b54121SFrançois Tigeot /* static int __init i915_init(void) */ 541c4a9e910SFrançois Tigeot static int 542c4a9e910SFrançois Tigeot i915_attach(device_t kdev) 543c4a9e910SFrançois Tigeot { 544e3adcf8fSFrançois Tigeot struct drm_device *dev; 545c4a9e910SFrançois Tigeot 546e3adcf8fSFrançois Tigeot dev = device_get_softc(kdev); 547*f0b54121SFrançois Tigeot 548*f0b54121SFrançois Tigeot driver.num_ioctls = i915_max_ioctl; 549*f0b54121SFrançois Tigeot 550e3adcf8fSFrançois Tigeot if (i915_modeset == 1) 551*f0b54121SFrançois Tigeot driver.driver_features |= DRIVER_MODESET; 552*f0b54121SFrançois Tigeot 553*f0b54121SFrançois Tigeot dev->driver = &driver; 55462e5f8e8SFrançois Tigeot return (drm_attach(kdev, i915_attach_list)); 555c4a9e910SFrançois Tigeot } 556c4a9e910SFrançois Tigeot 557e3adcf8fSFrançois Tigeot const struct intel_device_info * 558e3adcf8fSFrançois Tigeot i915_get_device_id(int device) 559c4a9e910SFrançois Tigeot { 560e3adcf8fSFrançois Tigeot const struct intel_gfx_device_id *did; 561c4a9e910SFrançois Tigeot 562e3adcf8fSFrançois Tigeot for (did = &pciidlist[0]; did->device != 0; did++) { 563e3adcf8fSFrançois Tigeot if (did->device != device) 564e3adcf8fSFrançois Tigeot continue; 565e3adcf8fSFrançois Tigeot return (did->info); 566e3adcf8fSFrançois Tigeot } 567e3adcf8fSFrançois Tigeot return (NULL); 568c4a9e910SFrançois Tigeot } 569c4a9e910SFrançois Tigeot 570c4a9e910SFrançois Tigeot static device_method_t i915_methods[] = { 571c4a9e910SFrançois Tigeot /* Device interface */ 572c4a9e910SFrançois Tigeot DEVMETHOD(device_probe, i915_probe), 573c4a9e910SFrançois Tigeot DEVMETHOD(device_attach, i915_attach), 574c4a9e910SFrançois Tigeot DEVMETHOD(device_suspend, i915_suspend), 575c4a9e910SFrançois Tigeot DEVMETHOD(device_resume, i915_resume), 576e3adcf8fSFrançois Tigeot DEVMETHOD(device_detach, drm_detach), 577d3c9c58eSSascha Wildner DEVMETHOD_END 578c4a9e910SFrançois Tigeot }; 579c4a9e910SFrançois Tigeot 580c4a9e910SFrançois Tigeot static driver_t i915_driver = { 581c4a9e910SFrançois Tigeot "drm", 582c4a9e910SFrançois Tigeot i915_methods, 583c4a9e910SFrançois Tigeot sizeof(struct drm_device) 584c4a9e910SFrançois Tigeot }; 585c4a9e910SFrançois Tigeot 586c4a9e910SFrançois Tigeot extern devclass_t drm_devclass; 587e3adcf8fSFrançois Tigeot DRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0, 588e3adcf8fSFrançois Tigeot SI_ORDER_ANY); 589e3adcf8fSFrançois Tigeot MODULE_DEPEND(i915kms, drm, 1, 1, 1); 590e3adcf8fSFrançois Tigeot MODULE_DEPEND(i915kms, agp, 1, 1, 1); 591e3adcf8fSFrançois Tigeot MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); 592e3adcf8fSFrançois Tigeot MODULE_DEPEND(i915kms, iic, 1, 1, 1); 593e3adcf8fSFrançois Tigeot MODULE_DEPEND(i915kms, iicbb, 1, 1, 1); 594e3adcf8fSFrançois Tigeot 595e3adcf8fSFrançois Tigeot int intel_iommu_enabled = 0; 596e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.intel_iommu_enabled", &intel_iommu_enabled); 597e3adcf8fSFrançois Tigeot 598e3adcf8fSFrançois Tigeot int i915_semaphores = -1; 599e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.semaphores", &i915_semaphores); 600e3adcf8fSFrançois Tigeot static int i915_try_reset = 1; 601e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.try_reset", &i915_try_reset); 602e3adcf8fSFrançois Tigeot unsigned int i915_lvds_downclock = 0; 603e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock); 604e3adcf8fSFrançois Tigeot int i915_vbt_sdvo_panel_type = -1; 605e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type); 606e3adcf8fSFrançois Tigeot unsigned int i915_powersave = 1; 607e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.powersave", &i915_powersave); 608e3adcf8fSFrançois Tigeot int i915_enable_fbc = 0; 609e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc); 610e3adcf8fSFrançois Tigeot int i915_enable_rc6 = 0; 611e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6); 612e3adcf8fSFrançois Tigeot int i915_panel_use_ssc = -1; 613e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc); 614e3adcf8fSFrançois Tigeot int i915_panel_ignore_lid = 0; 615e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid); 616e3adcf8fSFrançois Tigeot int i915_modeset = 1; 617e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.modeset", &i915_modeset); 618e3adcf8fSFrançois Tigeot int i915_enable_ppgtt = -1; 619e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt); 620e3adcf8fSFrançois Tigeot int i915_enable_hangcheck = 1; 621e3adcf8fSFrançois Tigeot TUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck); 622e3adcf8fSFrançois Tigeot 62300640ec9SFrançois Tigeot static int i8xx_do_reset(struct drm_device *dev) 624e3adcf8fSFrançois Tigeot { 625e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 626e3adcf8fSFrançois Tigeot 627e3adcf8fSFrançois Tigeot if (IS_I85X(dev)) 628e3adcf8fSFrançois Tigeot return -ENODEV; 629e3adcf8fSFrançois Tigeot 630e3adcf8fSFrançois Tigeot I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830); 631e3adcf8fSFrançois Tigeot POSTING_READ(D_STATE); 632e3adcf8fSFrançois Tigeot 633e3adcf8fSFrançois Tigeot if (IS_I830(dev) || IS_845G(dev)) { 634e3adcf8fSFrançois Tigeot I915_WRITE(DEBUG_RESET_I830, 635e3adcf8fSFrançois Tigeot DEBUG_RESET_DISPLAY | 636e3adcf8fSFrançois Tigeot DEBUG_RESET_RENDER | 637e3adcf8fSFrançois Tigeot DEBUG_RESET_FULL); 638e3adcf8fSFrançois Tigeot POSTING_READ(DEBUG_RESET_I830); 63900640ec9SFrançois Tigeot msleep(1); 640e3adcf8fSFrançois Tigeot 641e3adcf8fSFrançois Tigeot I915_WRITE(DEBUG_RESET_I830, 0); 642e3adcf8fSFrançois Tigeot POSTING_READ(DEBUG_RESET_I830); 643e3adcf8fSFrançois Tigeot } 644e3adcf8fSFrançois Tigeot 64500640ec9SFrançois Tigeot msleep(1); 646e3adcf8fSFrançois Tigeot 647e3adcf8fSFrançois Tigeot I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830); 648e3adcf8fSFrançois Tigeot POSTING_READ(D_STATE); 649e3adcf8fSFrançois Tigeot 650e3adcf8fSFrançois Tigeot return 0; 651e3adcf8fSFrançois Tigeot } 652e3adcf8fSFrançois Tigeot 65300640ec9SFrançois Tigeot static int i965_reset_complete(struct drm_device *dev) 654e3adcf8fSFrançois Tigeot { 655e3adcf8fSFrançois Tigeot u8 gdrst; 6566df74fa7SFrançois Tigeot gdrst = pci_read_config(dev->dev, I965_GDRST, 1); 657e3adcf8fSFrançois Tigeot return (gdrst & 0x1); 658e3adcf8fSFrançois Tigeot } 659e3adcf8fSFrançois Tigeot 66000640ec9SFrançois Tigeot static int i965_do_reset(struct drm_device *dev) 661e3adcf8fSFrançois Tigeot { 66200640ec9SFrançois Tigeot int ret; 663e3adcf8fSFrançois Tigeot u8 gdrst; 664e3adcf8fSFrançois Tigeot 665e3adcf8fSFrançois Tigeot /* 666e3adcf8fSFrançois Tigeot * Set the domains we want to reset (GRDOM/bits 2 and 3) as 667e3adcf8fSFrançois Tigeot * well as the reset bit (GR/bit 0). Setting the GR bit 668e3adcf8fSFrançois Tigeot * triggers the reset; when done, the hardware will clear it. 669e3adcf8fSFrançois Tigeot */ 6706df74fa7SFrançois Tigeot gdrst = pci_read_config(dev->dev, I965_GDRST, 1); 67100640ec9SFrançois Tigeot pci_write_config(dev->dev, I965_GDRST, 67200640ec9SFrançois Tigeot gdrst | GRDOM_RENDER | 67300640ec9SFrançois Tigeot GRDOM_RESET_ENABLE, 1); 67400640ec9SFrançois Tigeot ret = wait_for(i965_reset_complete(dev), 500); 67500640ec9SFrançois Tigeot if (ret) 67600640ec9SFrançois Tigeot return ret; 677e3adcf8fSFrançois Tigeot 67800640ec9SFrançois Tigeot /* We can't reset render&media without also resetting display ... */ 67900640ec9SFrançois Tigeot gdrst = pci_read_config(dev->dev, I965_GDRST, 1); 68000640ec9SFrançois Tigeot pci_write_config(dev->dev, I965_GDRST, 68100640ec9SFrançois Tigeot gdrst | GRDOM_MEDIA | 68200640ec9SFrançois Tigeot GRDOM_RESET_ENABLE, 1); 68300640ec9SFrançois Tigeot 68400640ec9SFrançois Tigeot return wait_for(i965_reset_complete(dev), 500); 685e3adcf8fSFrançois Tigeot } 686e3adcf8fSFrançois Tigeot 68700640ec9SFrançois Tigeot static int ironlake_do_reset(struct drm_device *dev) 688e3adcf8fSFrançois Tigeot { 68900640ec9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 690e3adcf8fSFrançois Tigeot u32 gdrst; 69100640ec9SFrançois Tigeot int ret; 692e3adcf8fSFrançois Tigeot 693e3adcf8fSFrançois Tigeot gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); 69400640ec9SFrançois Tigeot I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 69500640ec9SFrançois Tigeot gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); 69600640ec9SFrançois Tigeot ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); 69700640ec9SFrançois Tigeot if (ret) 69800640ec9SFrançois Tigeot return ret; 69900640ec9SFrançois Tigeot 70000640ec9SFrançois Tigeot /* We can't reset render&media without also resetting display ... */ 70100640ec9SFrançois Tigeot gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); 70200640ec9SFrançois Tigeot I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 70300640ec9SFrançois Tigeot gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); 70400640ec9SFrançois Tigeot return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); 705e3adcf8fSFrançois Tigeot } 706e3adcf8fSFrançois Tigeot 707e9243325SFrançois Tigeot static int gen6_do_reset(struct drm_device *dev) 708e3adcf8fSFrançois Tigeot { 709e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 710e3adcf8fSFrançois Tigeot int ret; 711e3adcf8fSFrançois Tigeot 712e3adcf8fSFrançois Tigeot dev_priv = dev->dev_private; 713e3adcf8fSFrançois Tigeot 714e3adcf8fSFrançois Tigeot /* Hold gt_lock across reset to prevent any register access 715e3adcf8fSFrançois Tigeot * with forcewake not set correctly 716e3adcf8fSFrançois Tigeot */ 717e3adcf8fSFrançois Tigeot lockmgr(&dev_priv->gt_lock, LK_EXCLUSIVE); 718e3adcf8fSFrançois Tigeot 719e3adcf8fSFrançois Tigeot /* Reset the chip */ 720e3adcf8fSFrançois Tigeot 721e3adcf8fSFrançois Tigeot /* GEN6_GDRST is not in the gt power well, no need to check 722e3adcf8fSFrançois Tigeot * for fifo space for the write or forcewake the chip for 723e3adcf8fSFrançois Tigeot * the read 724e3adcf8fSFrançois Tigeot */ 725e3adcf8fSFrançois Tigeot I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); 726e3adcf8fSFrançois Tigeot 727e3adcf8fSFrançois Tigeot /* Spin waiting for the device to ack the reset request */ 72819df918dSFrançois Tigeot ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); 729e3adcf8fSFrançois Tigeot 730e3adcf8fSFrançois Tigeot /* If reset with a user forcewake, try to restore, otherwise turn it off */ 731e3adcf8fSFrançois Tigeot if (dev_priv->forcewake_count) 732e9243325SFrançois Tigeot dev_priv->gt.force_wake_get(dev_priv); 733e3adcf8fSFrançois Tigeot else 734e9243325SFrançois Tigeot dev_priv->gt.force_wake_put(dev_priv); 735e3adcf8fSFrançois Tigeot 736e3adcf8fSFrançois Tigeot /* Restore fifo count */ 737e3adcf8fSFrançois Tigeot dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); 738e3adcf8fSFrançois Tigeot 739e3adcf8fSFrançois Tigeot lockmgr(&dev_priv->gt_lock, LK_RELEASE); 740e9243325SFrançois Tigeot return ret; 741e3adcf8fSFrançois Tigeot } 742e3adcf8fSFrançois Tigeot 74300640ec9SFrançois Tigeot int intel_gpu_reset(struct drm_device *dev) 74400640ec9SFrançois Tigeot { 74500640ec9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 74600640ec9SFrançois Tigeot int ret = -ENODEV; 74700640ec9SFrançois Tigeot 74800640ec9SFrançois Tigeot switch (INTEL_INFO(dev)->gen) { 74900640ec9SFrançois Tigeot case 7: 75000640ec9SFrançois Tigeot case 6: 75100640ec9SFrançois Tigeot ret = gen6_do_reset(dev); 75200640ec9SFrançois Tigeot break; 75300640ec9SFrançois Tigeot case 5: 75400640ec9SFrançois Tigeot ret = ironlake_do_reset(dev); 75500640ec9SFrançois Tigeot break; 75600640ec9SFrançois Tigeot case 4: 75700640ec9SFrançois Tigeot ret = i965_do_reset(dev); 75800640ec9SFrançois Tigeot break; 75900640ec9SFrançois Tigeot case 2: 76000640ec9SFrançois Tigeot ret = i8xx_do_reset(dev); 76100640ec9SFrançois Tigeot break; 76200640ec9SFrançois Tigeot } 76300640ec9SFrançois Tigeot 76400640ec9SFrançois Tigeot /* Also reset the gpu hangman. */ 76500640ec9SFrançois Tigeot if (dev_priv->stop_rings) { 76600640ec9SFrançois Tigeot DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n"); 76700640ec9SFrançois Tigeot dev_priv->stop_rings = 0; 76800640ec9SFrançois Tigeot if (ret == -ENODEV) { 76900640ec9SFrançois Tigeot DRM_ERROR("Reset not implemented, but ignoring " 77000640ec9SFrançois Tigeot "error for simulated gpu hangs\n"); 77100640ec9SFrançois Tigeot ret = 0; 77200640ec9SFrançois Tigeot } 77300640ec9SFrançois Tigeot } 77400640ec9SFrançois Tigeot 77500640ec9SFrançois Tigeot return ret; 77600640ec9SFrançois Tigeot } 77700640ec9SFrançois Tigeot 778e9243325SFrançois Tigeot /** 779e9243325SFrançois Tigeot * i915_reset - reset chip after a hang 780e9243325SFrançois Tigeot * @dev: drm device to reset 781e9243325SFrançois Tigeot * 782e9243325SFrançois Tigeot * Reset the chip. Useful if a hang is detected. Returns zero on successful 783e9243325SFrançois Tigeot * reset or otherwise an error code. 784e9243325SFrançois Tigeot * 785e9243325SFrançois Tigeot * Procedure is fairly simple: 786e9243325SFrançois Tigeot * - reset the chip using the reset reg 787e9243325SFrançois Tigeot * - re-init context state 788e9243325SFrançois Tigeot * - re-init hardware status page 789e9243325SFrançois Tigeot * - re-init ring buffer 790e9243325SFrançois Tigeot * - re-init interrupt state 791e9243325SFrançois Tigeot * - re-init display 792e9243325SFrançois Tigeot */ 79300640ec9SFrançois Tigeot int i915_reset(struct drm_device *dev) 794e3adcf8fSFrançois Tigeot { 795e3adcf8fSFrançois Tigeot drm_i915_private_t *dev_priv = dev->dev_private; 796e9243325SFrançois Tigeot int ret; 797e9243325SFrançois Tigeot 798e9243325SFrançois Tigeot if (!i915_try_reset) 799e9243325SFrançois Tigeot return 0; 800e9243325SFrançois Tigeot 80100640ec9SFrançois Tigeot DRM_LOCK(dev); 802e3adcf8fSFrançois Tigeot 803e3adcf8fSFrançois Tigeot i915_gem_reset(dev); 804e3adcf8fSFrançois Tigeot 805e3adcf8fSFrançois Tigeot ret = -ENODEV; 80600640ec9SFrançois Tigeot if (time_uptime - dev_priv->last_gpu_reset < 5) 807e3adcf8fSFrançois Tigeot DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); 80800640ec9SFrançois Tigeot else 80900640ec9SFrançois Tigeot ret = intel_gpu_reset(dev); 81000640ec9SFrançois Tigeot 811e3adcf8fSFrançois Tigeot dev_priv->last_gpu_reset = time_uptime; 812e3adcf8fSFrançois Tigeot if (ret) { 813e3adcf8fSFrançois Tigeot DRM_ERROR("Failed to reset chip.\n"); 814e3adcf8fSFrançois Tigeot DRM_UNLOCK(dev); 81500640ec9SFrançois Tigeot return ret; 816e3adcf8fSFrançois Tigeot } 817e3adcf8fSFrançois Tigeot 818e9243325SFrançois Tigeot /* Ok, now get things going again... */ 819e9243325SFrançois Tigeot 820e9243325SFrançois Tigeot /* 821e9243325SFrançois Tigeot * Everything depends on having the GTT running, so we need to start 822e9243325SFrançois Tigeot * there. Fortunately we don't need to do this unless we reset the 823e9243325SFrançois Tigeot * chip at a PCI level. 824e9243325SFrançois Tigeot * 825e9243325SFrançois Tigeot * Next we need to restore the context, but we don't use those 826e9243325SFrançois Tigeot * yet either... 827e9243325SFrançois Tigeot * 828e9243325SFrançois Tigeot * Ring buffer needs to be re-initialized in the KMS case, or if X 829e9243325SFrançois Tigeot * was running at the time of the reset (i.e. we weren't VT 830e9243325SFrançois Tigeot * switched away). 831e9243325SFrançois Tigeot */ 832e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET) || 833e3adcf8fSFrançois Tigeot !dev_priv->mm.suspended) { 83400640ec9SFrançois Tigeot struct intel_ring_buffer *ring; 83500640ec9SFrançois Tigeot int i; 83600640ec9SFrançois Tigeot 837e3adcf8fSFrançois Tigeot dev_priv->mm.suspended = 0; 838e3adcf8fSFrançois Tigeot 839e3adcf8fSFrançois Tigeot i915_gem_init_swizzling(dev); 840e3adcf8fSFrançois Tigeot 84100640ec9SFrançois Tigeot for_each_ring(ring, dev_priv, i) 84200640ec9SFrançois Tigeot ring->init(ring); 843e3adcf8fSFrançois Tigeot 84400640ec9SFrançois Tigeot #if 0 /* XXX: HW context support */ 84500640ec9SFrançois Tigeot i915_gem_context_init(dev); 84600640ec9SFrançois Tigeot #endif 847e3adcf8fSFrançois Tigeot i915_gem_init_ppgtt(dev); 848e3adcf8fSFrançois Tigeot 84900640ec9SFrançois Tigeot /* 85000640ec9SFrançois Tigeot * It would make sense to re-init all the other hw state, at 85100640ec9SFrançois Tigeot * least the rps/rc6/emon init done within modeset_init_hw. For 85200640ec9SFrançois Tigeot * some unknown reason, this blows up my ilk, so don't. 85300640ec9SFrançois Tigeot */ 85400640ec9SFrançois Tigeot 855e3adcf8fSFrançois Tigeot DRM_UNLOCK(dev); 856e3adcf8fSFrançois Tigeot 85700640ec9SFrançois Tigeot drm_irq_uninstall(dev); 85800640ec9SFrançois Tigeot drm_irq_install(dev); 85900640ec9SFrançois Tigeot } else { 86000640ec9SFrançois Tigeot DRM_UNLOCK(dev); 861e3adcf8fSFrançois Tigeot } 862e3adcf8fSFrançois Tigeot 863e9243325SFrançois Tigeot return 0; 864e9243325SFrançois Tigeot } 865e9243325SFrançois Tigeot 866*f0b54121SFrançois Tigeot static struct drm_driver driver = { 867*f0b54121SFrançois Tigeot .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | 868*f0b54121SFrançois Tigeot DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_LOCKLESS_IRQ | 869*f0b54121SFrançois Tigeot DRIVER_GEM /*| DRIVER_MODESET*/, 870*f0b54121SFrançois Tigeot 871*f0b54121SFrançois Tigeot .buf_priv_size = sizeof(drm_i915_private_t), 872*f0b54121SFrançois Tigeot .load = i915_driver_load, 873*f0b54121SFrançois Tigeot .open = i915_driver_open, 874*f0b54121SFrançois Tigeot .unload = i915_driver_unload, 875*f0b54121SFrançois Tigeot .preclose = i915_driver_preclose, 876*f0b54121SFrançois Tigeot .lastclose = i915_driver_lastclose, 877*f0b54121SFrançois Tigeot .postclose = i915_driver_postclose, 878*f0b54121SFrançois Tigeot .device_is_agp = i915_driver_device_is_agp, 879*f0b54121SFrançois Tigeot .gem_init_object = i915_gem_init_object, 880*f0b54121SFrançois Tigeot .gem_free_object = i915_gem_free_object, 881*f0b54121SFrançois Tigeot .gem_pager_ops = &i915_gem_pager_ops, 882*f0b54121SFrançois Tigeot .dumb_create = i915_gem_dumb_create, 883*f0b54121SFrançois Tigeot .dumb_map_offset = i915_gem_mmap_gtt, 884*f0b54121SFrançois Tigeot .dumb_destroy = i915_gem_dumb_destroy, 885*f0b54121SFrançois Tigeot 886*f0b54121SFrançois Tigeot .ioctls = i915_ioctls, 887*f0b54121SFrançois Tigeot 888*f0b54121SFrançois Tigeot .name = DRIVER_NAME, 889*f0b54121SFrançois Tigeot .desc = DRIVER_DESC, 890*f0b54121SFrançois Tigeot .date = DRIVER_DATE, 891*f0b54121SFrançois Tigeot .major = DRIVER_MAJOR, 892*f0b54121SFrançois Tigeot .minor = DRIVER_MINOR, 893*f0b54121SFrançois Tigeot .patchlevel = DRIVER_PATCHLEVEL, 894*f0b54121SFrançois Tigeot }; 895*f0b54121SFrançois Tigeot 896c0bdd5d9SFrançois Tigeot /* We give fast paths for the really cool registers */ 897c0bdd5d9SFrançois Tigeot #define NEEDS_FORCE_WAKE(dev_priv, reg) \ 898c0bdd5d9SFrançois Tigeot ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ 899c0bdd5d9SFrançois Tigeot ((reg) < 0x40000) && \ 900c0bdd5d9SFrançois Tigeot ((reg) != FORCEWAKE)) 901c0bdd5d9SFrançois Tigeot 902e9243325SFrançois Tigeot static bool IS_DISPLAYREG(u32 reg) 903e9243325SFrançois Tigeot { 904e9243325SFrançois Tigeot /* 905e9243325SFrançois Tigeot * This should make it easier to transition modules over to the 906e9243325SFrançois Tigeot * new register block scheme, since we can do it incrementally. 907e9243325SFrançois Tigeot */ 908e9243325SFrançois Tigeot if (reg >= VLV_DISPLAY_BASE) 909e9243325SFrançois Tigeot return false; 910e9243325SFrançois Tigeot 911e9243325SFrançois Tigeot if (reg >= RENDER_RING_BASE && 912e9243325SFrançois Tigeot reg < RENDER_RING_BASE + 0xff) 913e9243325SFrançois Tigeot return false; 914e9243325SFrançois Tigeot if (reg >= GEN6_BSD_RING_BASE && 915e9243325SFrançois Tigeot reg < GEN6_BSD_RING_BASE + 0xff) 916e9243325SFrançois Tigeot return false; 917e9243325SFrançois Tigeot if (reg >= BLT_RING_BASE && 918e9243325SFrançois Tigeot reg < BLT_RING_BASE + 0xff) 919e9243325SFrançois Tigeot return false; 920e9243325SFrançois Tigeot 921e9243325SFrançois Tigeot if (reg == PGTBL_ER) 922e9243325SFrançois Tigeot return false; 923e9243325SFrançois Tigeot 924e9243325SFrançois Tigeot if (reg >= IPEIR_I965 && 925e9243325SFrançois Tigeot reg < HWSTAM) 926e9243325SFrançois Tigeot return false; 927e9243325SFrançois Tigeot 928e9243325SFrançois Tigeot if (reg == MI_MODE) 929e9243325SFrançois Tigeot return false; 930e9243325SFrançois Tigeot 931e9243325SFrançois Tigeot if (reg == GFX_MODE_GEN7) 932e9243325SFrançois Tigeot return false; 933e9243325SFrançois Tigeot 934e9243325SFrançois Tigeot if (reg == RENDER_HWS_PGA_GEN7 || 935e9243325SFrançois Tigeot reg == BSD_HWS_PGA_GEN7 || 936e9243325SFrançois Tigeot reg == BLT_HWS_PGA_GEN7) 937e9243325SFrançois Tigeot return false; 938e9243325SFrançois Tigeot 939e9243325SFrançois Tigeot if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || 940e9243325SFrançois Tigeot reg == GEN6_BSD_RNCID) 941e9243325SFrançois Tigeot return false; 942e9243325SFrançois Tigeot 943e9243325SFrançois Tigeot if (reg == GEN6_BLITTER_ECOSKPD) 944e9243325SFrançois Tigeot return false; 945e9243325SFrançois Tigeot 946e9243325SFrançois Tigeot if (reg >= 0x4000c && 947e9243325SFrançois Tigeot reg <= 0x4002c) 948e9243325SFrançois Tigeot return false; 949e9243325SFrançois Tigeot 950e9243325SFrançois Tigeot if (reg >= 0x4f000 && 951e9243325SFrançois Tigeot reg <= 0x4f08f) 952e9243325SFrançois Tigeot return false; 953e9243325SFrançois Tigeot 954e9243325SFrançois Tigeot if (reg >= 0x4f100 && 955e9243325SFrançois Tigeot reg <= 0x4f11f) 956e9243325SFrançois Tigeot return false; 957e9243325SFrançois Tigeot 958e9243325SFrançois Tigeot if (reg >= VLV_MASTER_IER && 959e9243325SFrançois Tigeot reg <= GEN6_PMIER) 960e9243325SFrançois Tigeot return false; 961e9243325SFrançois Tigeot 962e9243325SFrançois Tigeot if (reg >= FENCE_REG_SANDYBRIDGE_0 && 963e9243325SFrançois Tigeot reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) 964e9243325SFrançois Tigeot return false; 965e9243325SFrançois Tigeot 966e9243325SFrançois Tigeot if (reg >= VLV_IIR_RW && 967e9243325SFrançois Tigeot reg <= VLV_ISR) 968e9243325SFrançois Tigeot return false; 969e9243325SFrançois Tigeot 970e9243325SFrançois Tigeot if (reg == FORCEWAKE_VLV || 971e9243325SFrançois Tigeot reg == FORCEWAKE_ACK_VLV) 972e9243325SFrançois Tigeot return false; 973e9243325SFrançois Tigeot 974e9243325SFrançois Tigeot if (reg == GEN6_GDRST) 975e9243325SFrançois Tigeot return false; 976e9243325SFrançois Tigeot 977e9243325SFrançois Tigeot switch (reg) { 978e9243325SFrançois Tigeot case _3D_CHICKEN3: 979e9243325SFrançois Tigeot case IVB_CHICKEN3: 980e9243325SFrançois Tigeot case GEN7_COMMON_SLICE_CHICKEN1: 981e9243325SFrançois Tigeot case GEN7_L3CNTLREG1: 982e9243325SFrançois Tigeot case GEN7_L3_CHICKEN_MODE_REGISTER: 983e9243325SFrançois Tigeot case GEN7_ROW_CHICKEN2: 984e9243325SFrançois Tigeot case GEN7_L3SQCREG4: 985e9243325SFrançois Tigeot case GEN7_SQ_CHICKEN_MBCUNIT_CONFIG: 986e9243325SFrançois Tigeot case GEN7_HALF_SLICE_CHICKEN1: 987e9243325SFrançois Tigeot case GEN6_MBCTL: 988e9243325SFrançois Tigeot case GEN6_UCGCTL2: 989e9243325SFrançois Tigeot return false; 990e9243325SFrançois Tigeot default: 991e9243325SFrançois Tigeot break; 992e9243325SFrançois Tigeot } 993e9243325SFrançois Tigeot 994e9243325SFrançois Tigeot return true; 995e9243325SFrançois Tigeot } 996e9243325SFrançois Tigeot 997e9243325SFrançois Tigeot static void 998e9243325SFrançois Tigeot ilk_dummy_write(struct drm_i915_private *dev_priv) 999e9243325SFrançois Tigeot { 1000e9243325SFrançois Tigeot /* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the 1001e9243325SFrançois Tigeot * chip from rc6 before touching it for real. MI_MODE is masked, hence 1002e9243325SFrançois Tigeot * harmless to write 0 into. */ 1003e9243325SFrançois Tigeot I915_WRITE_NOTRACE(MI_MODE, 0); 1004e3adcf8fSFrançois Tigeot } 1005e3adcf8fSFrançois Tigeot 1006e3adcf8fSFrançois Tigeot #define __i915_read(x, y) \ 1007e3adcf8fSFrançois Tigeot u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ 1008e3adcf8fSFrançois Tigeot u##x val = 0; \ 1009e9243325SFrançois Tigeot if (IS_GEN5(dev_priv->dev)) \ 1010e9243325SFrançois Tigeot ilk_dummy_write(dev_priv); \ 1011e3adcf8fSFrançois Tigeot if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ 1012e3adcf8fSFrançois Tigeot lockmgr(&dev_priv->gt_lock, LK_EXCLUSIVE); \ 1013e3adcf8fSFrançois Tigeot if (dev_priv->forcewake_count == 0) \ 1014e9243325SFrançois Tigeot dev_priv->gt.force_wake_get(dev_priv); \ 1015e3adcf8fSFrançois Tigeot val = DRM_READ##y(dev_priv->mmio_map, reg); \ 1016e3adcf8fSFrançois Tigeot if (dev_priv->forcewake_count == 0) \ 1017e9243325SFrançois Tigeot dev_priv->gt.force_wake_put(dev_priv); \ 1018e3adcf8fSFrançois Tigeot lockmgr(&dev_priv->gt_lock, LK_RELEASE); \ 1019e9243325SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ 1020e9243325SFrançois Tigeot val = DRM_READ##y(dev_priv->mmio_map, reg + 0x180000); \ 1021e3adcf8fSFrançois Tigeot } else { \ 1022e3adcf8fSFrançois Tigeot val = DRM_READ##y(dev_priv->mmio_map, reg); \ 1023e3adcf8fSFrançois Tigeot } \ 1024e3adcf8fSFrançois Tigeot trace_i915_reg_rw(false, reg, val, sizeof(val)); \ 1025e3adcf8fSFrançois Tigeot return val; \ 1026e3adcf8fSFrançois Tigeot } 1027e3adcf8fSFrançois Tigeot 1028e3adcf8fSFrançois Tigeot __i915_read(8, 8) 1029e3adcf8fSFrançois Tigeot __i915_read(16, 16) 1030e3adcf8fSFrançois Tigeot __i915_read(32, 32) 1031e3adcf8fSFrançois Tigeot __i915_read(64, 64) 1032e3adcf8fSFrançois Tigeot #undef __i915_read 1033e3adcf8fSFrançois Tigeot 1034e3adcf8fSFrançois Tigeot #define __i915_write(x, y) \ 1035e3adcf8fSFrançois Tigeot void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ 1036e3adcf8fSFrançois Tigeot u32 __fifo_ret = 0; \ 1037e3adcf8fSFrançois Tigeot trace_i915_reg_rw(true, reg, val, sizeof(val)); \ 1038e3adcf8fSFrançois Tigeot if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ 1039e3adcf8fSFrançois Tigeot __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ 1040e3adcf8fSFrançois Tigeot } \ 1041e9243325SFrançois Tigeot if (IS_GEN5(dev_priv->dev)) \ 1042e9243325SFrançois Tigeot ilk_dummy_write(dev_priv); \ 1043e9243325SFrançois Tigeot if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ 1044e9243325SFrançois Tigeot DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \ 1045e9243325SFrançois Tigeot I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ 1046e9243325SFrançois Tigeot } \ 1047e9243325SFrançois Tigeot if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ 1048e9243325SFrançois Tigeot DRM_WRITE##y(dev_priv->mmio_map, reg + 0x180000, val); \ 1049e9243325SFrançois Tigeot } else { \ 1050e3adcf8fSFrançois Tigeot DRM_WRITE##y(dev_priv->mmio_map, reg, val); \ 1051e9243325SFrançois Tigeot } \ 1052e9243325SFrançois Tigeot if (unlikely(__fifo_ret)) { \ 1053e3adcf8fSFrançois Tigeot gen6_gt_check_fifodbg(dev_priv); \ 1054e3adcf8fSFrançois Tigeot } \ 1055e9243325SFrançois Tigeot if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ 1056e9243325SFrançois Tigeot DRM_ERROR("Unclaimed write to %x\n", reg); \ 1057e9243325SFrançois Tigeot DRM_WRITE32(dev_priv->mmio_map, GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ 1058e9243325SFrançois Tigeot } \ 1059e3adcf8fSFrançois Tigeot } 1060e9243325SFrançois Tigeot 1061e3adcf8fSFrançois Tigeot __i915_write(8, 8) 1062e3adcf8fSFrançois Tigeot __i915_write(16, 16) 1063e3adcf8fSFrançois Tigeot __i915_write(32, 32) 1064e3adcf8fSFrançois Tigeot __i915_write(64, 64) 1065e3adcf8fSFrançois Tigeot #undef __i915_write 1066