1296548Sdumbbell/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- 2235783Skib */ 3296548Sdumbbell/* 4296548Sdumbbell * 5296548Sdumbbell * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 6235783Skib * All Rights Reserved. 7235783Skib * 8235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 9296548Sdumbbell * copy of this software and associated documentation files (the 10296548Sdumbbell * "Software"), to deal in the Software without restriction, including 11296548Sdumbbell * without limitation the rights to use, copy, modify, merge, publish, 12296548Sdumbbell * distribute, sub license, and/or sell copies of the Software, and to 13296548Sdumbbell * permit persons to whom the Software is furnished to do so, subject to 14296548Sdumbbell * the following conditions: 15235783Skib * 16296548Sdumbbell * The above copyright notice and this permission notice (including the 17296548Sdumbbell * next paragraph) shall be included in all copies or substantial portions 18296548Sdumbbell * of the Software. 19235783Skib * 20296548Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21296548Sdumbbell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22296548Sdumbbell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23296548Sdumbbell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 24296548Sdumbbell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25296548Sdumbbell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26296548Sdumbbell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27235783Skib * 28235783Skib */ 29235783Skib 30235783Skib#include <sys/cdefs.h> 31235783Skib__FBSDID("$FreeBSD: stable/11/sys/dev/drm2/i915/i915_drv.c 317609 2017-04-30 18:39:31Z markj $"); 32235783Skib 33235783Skib#include <dev/drm2/drmP.h> 34296548Sdumbbell#include <dev/drm2/drm_pciids.h> 35235783Skib#include <dev/drm2/i915/i915_drm.h> 36296548Sdumbbell#include "dev/drm2/i915/i915_drv.h" 37296548Sdumbbell#ifdef __linux__ 38296548Sdumbbell#include "dev/drm2/i915/i915_trace.h" 39296548Sdumbbell#endif 40296548Sdumbbell#include "dev/drm2/i915/intel_drv.h" 41235783Skib 42296548Sdumbbell#include <dev/drm2/drm_crtc_helper.h> 43296548Sdumbbell 44259016Sray#include "fb_if.h" 45259016Sray 46296548Sdumbbellstatic int i915_modeset __read_mostly = 1; 47296548SdumbbellTUNABLE_INT("drm.i915.modeset", &i915_modeset); 48296548Sdumbbellmodule_param_named(modeset, i915_modeset, int, 0400); 49296548SdumbbellMODULE_PARM_DESC(modeset, 50296548Sdumbbell "Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, " 51296548Sdumbbell "1=on, -1=force vga console preference [default])"); 52290070Sdumbbell 53296548Sdumbbell#ifdef __linux__ 54296548Sdumbbellunsigned int i915_fbpercrtc __always_unused = 0; 55296548Sdumbbellmodule_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); 56296548Sdumbbell#endif 57296548Sdumbbell 58296548Sdumbbellint i915_panel_ignore_lid __read_mostly = 1; 59296548SdumbbellTUNABLE_INT("drm.i915.panel_ignore_lid", &i915_panel_ignore_lid); 60296548Sdumbbellmodule_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600); 61296548SdumbbellMODULE_PARM_DESC(panel_ignore_lid, 62296548Sdumbbell "Override lid status (0=autodetect, 1=autodetect disabled [default], " 63296548Sdumbbell "-1=force lid closed, -2=force lid open)"); 64296548Sdumbbell 65296548Sdumbbellunsigned int i915_powersave __read_mostly = 1; 66296548SdumbbellTUNABLE_INT("drm.i915.powersave", &i915_powersave); 67296548Sdumbbellmodule_param_named(powersave, i915_powersave, int, 0600); 68296548SdumbbellMODULE_PARM_DESC(powersave, 69296548Sdumbbell "Enable powersavings, fbc, downclocking, etc. (default: true)"); 70296548Sdumbbell 71296548Sdumbbellint i915_semaphores __read_mostly = -1; 72290070SdumbbellTUNABLE_INT("drm.i915.semaphores", &i915_semaphores); 73296548Sdumbbellmodule_param_named(semaphores, i915_semaphores, int, 0600); 74296548SdumbbellMODULE_PARM_DESC(semaphores, 75296548Sdumbbell "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); 76296548Sdumbbell 77296548Sdumbbellint i915_enable_rc6 __read_mostly = -1; 78296548SdumbbellTUNABLE_INT("drm.i915.enable_rc6", &i915_enable_rc6); 79296548Sdumbbellmodule_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); 80296548SdumbbellMODULE_PARM_DESC(i915_enable_rc6, 81296548Sdumbbell "Enable power-saving render C-state 6. " 82296548Sdumbbell "Different stages can be selected via bitmask values " 83296548Sdumbbell "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). " 84296548Sdumbbell "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " 85296548Sdumbbell "default: -1 (use per-chip default)"); 86296548Sdumbbell 87296548Sdumbbellint i915_enable_fbc __read_mostly = -1; 88296548SdumbbellTUNABLE_INT("drm.i915.enable_fbc", &i915_enable_fbc); 89296548Sdumbbellmodule_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); 90296548SdumbbellMODULE_PARM_DESC(i915_enable_fbc, 91296548Sdumbbell "Enable frame buffer compression for power savings " 92296548Sdumbbell "(default: -1 (use per-chip default))"); 93296548Sdumbbell 94296548Sdumbbellunsigned int i915_lvds_downclock __read_mostly = 0; 95290070SdumbbellTUNABLE_INT("drm.i915.lvds_downclock", &i915_lvds_downclock); 96296548Sdumbbellmodule_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); 97296548SdumbbellMODULE_PARM_DESC(lvds_downclock, 98296548Sdumbbell "Use panel (LVDS/eDP) downclocking for power savings " 99296548Sdumbbell "(default: false)"); 100296548Sdumbbell 101296548Sdumbbellint i915_lvds_channel_mode __read_mostly; 102290070SdumbbellTUNABLE_INT("drm.i915.lvds_channel_mode", &i915_lvds_channel_mode); 103296548Sdumbbellmodule_param_named(lvds_channel_mode, i915_lvds_channel_mode, int, 0600); 104296548SdumbbellMODULE_PARM_DESC(lvds_channel_mode, 105296548Sdumbbell "Specify LVDS channel mode " 106296548Sdumbbell "(0=probe BIOS [default], 1=single-channel, 2=dual-channel)"); 107296548Sdumbbell 108296548Sdumbbellint i915_panel_use_ssc __read_mostly = -1; 109290070SdumbbellTUNABLE_INT("drm.i915.panel_use_ssc", &i915_panel_use_ssc); 110296548Sdumbbellmodule_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); 111296548SdumbbellMODULE_PARM_DESC(lvds_use_ssc, 112296548Sdumbbell "Use Spread Spectrum Clock with panels [LVDS/eDP] " 113296548Sdumbbell "(default: auto from VBT)"); 114296548Sdumbbell 115296548Sdumbbellint i915_vbt_sdvo_panel_type __read_mostly = -1; 116296548SdumbbellTUNABLE_INT("drm.i915.vbt_sdvo_panel_type", &i915_vbt_sdvo_panel_type); 117296548Sdumbbellmodule_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600); 118296548SdumbbellMODULE_PARM_DESC(vbt_sdvo_panel_type, 119296548Sdumbbell "Override/Ignore selection of SDVO panel mode in the VBT " 120296548Sdumbbell "(-2=ignore, -1=auto [default], index in VBT BIOS table)"); 121296548Sdumbbell 122296548Sdumbbellstatic int i915_try_reset __read_mostly = true; 123296548SdumbbellTUNABLE_INT("drm.i915.try_reset", &i915_try_reset); 124296548Sdumbbellmodule_param_named(reset, i915_try_reset, bool, 0600); 125296548SdumbbellMODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)"); 126296548Sdumbbell 127296548Sdumbbellint i915_enable_hangcheck __read_mostly = true; 128290070SdumbbellTUNABLE_INT("drm.i915.enable_hangcheck", &i915_enable_hangcheck); 129296548Sdumbbellmodule_param_named(enable_hangcheck, i915_enable_hangcheck, bool, 0644); 130296548SdumbbellMODULE_PARM_DESC(enable_hangcheck, 131296548Sdumbbell "Periodically check GPU activity for detecting hangs. " 132296548Sdumbbell "WARNING: Disabling this can cause system wide hangs. " 133296548Sdumbbell "(default: true)"); 134290070Sdumbbell 135296548Sdumbbellint i915_enable_ppgtt __read_mostly = -1; 136296548SdumbbellTUNABLE_INT("drm.i915.enable_ppgtt", &i915_enable_ppgtt); 137296548Sdumbbellmodule_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); 138296548SdumbbellMODULE_PARM_DESC(i915_enable_ppgtt, 139296548Sdumbbell "Enable PPGTT (default: true)"); 140235783Skib 141296548Sdumbbellunsigned int i915_preliminary_hw_support __read_mostly = 0; 142296548SdumbbellTUNABLE_INT("drm.i915.enable_unsupported", &i915_preliminary_hw_support); 143296548Sdumbbellmodule_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); 144296548SdumbbellMODULE_PARM_DESC(preliminary_hw_support, 145296548Sdumbbell "Enable preliminary hardware support. " 146296548Sdumbbell "Enable Haswell and ValleyView Support. " 147296548Sdumbbell "(default: false)"); 148296548Sdumbbell 149296548Sdumbbellint intel_iommu_gfx_mapped = 0; 150296548SdumbbellTUNABLE_INT("drm.i915.intel_iommu_gfx_mapped", &intel_iommu_gfx_mapped); 151296548Sdumbbell 152296548Sdumbbellstatic struct drm_driver driver; 153296548Sdumbbellint intel_agp_enabled = 1; /* On FreeBSD, agp is a required dependency. */ 154296548Sdumbbell 155287173Sbapt#define INTEL_VGA_DEVICE(id, info_) { \ 156287173Sbapt .device = id, \ 157287173Sbapt .info = info_, \ 158287173Sbapt} 159287173Sbapt 160235783Skibstatic const struct intel_device_info intel_i830_info = { 161235783Skib .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, 162235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 163235783Skib}; 164235783Skib 165235783Skibstatic const struct intel_device_info intel_845g_info = { 166235783Skib .gen = 2, 167235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 168235783Skib}; 169235783Skib 170235783Skibstatic const struct intel_device_info intel_i85x_info = { 171235783Skib .gen = 2, .is_i85x = 1, .is_mobile = 1, 172235783Skib .cursor_needs_physical = 1, 173235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 174235783Skib}; 175235783Skib 176235783Skibstatic const struct intel_device_info intel_i865g_info = { 177235783Skib .gen = 2, 178235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 179235783Skib}; 180235783Skib 181235783Skibstatic const struct intel_device_info intel_i915g_info = { 182235783Skib .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, 183235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 184235783Skib}; 185235783Skibstatic const struct intel_device_info intel_i915gm_info = { 186235783Skib .gen = 3, .is_mobile = 1, 187235783Skib .cursor_needs_physical = 1, 188235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 189235783Skib .supports_tv = 1, 190235783Skib}; 191235783Skibstatic const struct intel_device_info intel_i945g_info = { 192235783Skib .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, 193235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 194235783Skib}; 195235783Skibstatic const struct intel_device_info intel_i945gm_info = { 196235783Skib .gen = 3, .is_i945gm = 1, .is_mobile = 1, 197235783Skib .has_hotplug = 1, .cursor_needs_physical = 1, 198235783Skib .has_overlay = 1, .overlay_needs_physical = 1, 199235783Skib .supports_tv = 1, 200235783Skib}; 201235783Skib 202235783Skibstatic const struct intel_device_info intel_i965g_info = { 203235783Skib .gen = 4, .is_broadwater = 1, 204235783Skib .has_hotplug = 1, 205235783Skib .has_overlay = 1, 206235783Skib}; 207235783Skib 208235783Skibstatic const struct intel_device_info intel_i965gm_info = { 209235783Skib .gen = 4, .is_crestline = 1, 210235783Skib .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, 211235783Skib .has_overlay = 1, 212235783Skib .supports_tv = 1, 213235783Skib}; 214235783Skib 215235783Skibstatic const struct intel_device_info intel_g33_info = { 216235783Skib .gen = 3, .is_g33 = 1, 217235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 218235783Skib .has_overlay = 1, 219235783Skib}; 220235783Skib 221235783Skibstatic const struct intel_device_info intel_g45_info = { 222235783Skib .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, 223235783Skib .has_pipe_cxsr = 1, .has_hotplug = 1, 224235783Skib .has_bsd_ring = 1, 225235783Skib}; 226235783Skib 227235783Skibstatic const struct intel_device_info intel_gm45_info = { 228235783Skib .gen = 4, .is_g4x = 1, 229235783Skib .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, 230235783Skib .has_pipe_cxsr = 1, .has_hotplug = 1, 231235783Skib .supports_tv = 1, 232235783Skib .has_bsd_ring = 1, 233235783Skib}; 234235783Skib 235235783Skibstatic const struct intel_device_info intel_pineview_info = { 236235783Skib .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, 237235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 238235783Skib .has_overlay = 1, 239235783Skib}; 240235783Skib 241235783Skibstatic const struct intel_device_info intel_ironlake_d_info = { 242235783Skib .gen = 5, 243235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 244235783Skib .has_bsd_ring = 1, 245235783Skib}; 246235783Skib 247235783Skibstatic const struct intel_device_info intel_ironlake_m_info = { 248235783Skib .gen = 5, .is_mobile = 1, 249235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 250296548Sdumbbell .has_fbc = 1, 251235783Skib .has_bsd_ring = 1, 252235783Skib}; 253235783Skib 254235783Skibstatic const struct intel_device_info intel_sandybridge_d_info = { 255235783Skib .gen = 6, 256235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 257235783Skib .has_bsd_ring = 1, 258235783Skib .has_blt_ring = 1, 259235783Skib .has_llc = 1, 260296548Sdumbbell .has_force_wake = 1, 261235783Skib}; 262235783Skib 263235783Skibstatic const struct intel_device_info intel_sandybridge_m_info = { 264235783Skib .gen = 6, .is_mobile = 1, 265235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 266235783Skib .has_fbc = 1, 267235783Skib .has_bsd_ring = 1, 268235783Skib .has_blt_ring = 1, 269235783Skib .has_llc = 1, 270296548Sdumbbell .has_force_wake = 1, 271235783Skib}; 272235783Skib 273235783Skibstatic const struct intel_device_info intel_ivybridge_d_info = { 274235783Skib .is_ivybridge = 1, .gen = 7, 275235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 276235783Skib .has_bsd_ring = 1, 277235783Skib .has_blt_ring = 1, 278235783Skib .has_llc = 1, 279296548Sdumbbell .has_force_wake = 1, 280235783Skib}; 281235783Skib 282235783Skibstatic const struct intel_device_info intel_ivybridge_m_info = { 283235783Skib .is_ivybridge = 1, .gen = 7, .is_mobile = 1, 284235783Skib .need_gfx_hws = 1, .has_hotplug = 1, 285235783Skib .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ 286235783Skib .has_bsd_ring = 1, 287235783Skib .has_blt_ring = 1, 288235783Skib .has_llc = 1, 289296548Sdumbbell .has_force_wake = 1, 290235783Skib}; 291235783Skib 292277487Skibstatic const struct intel_device_info intel_valleyview_m_info = { 293277487Skib .gen = 7, .is_mobile = 1, 294277487Skib .need_gfx_hws = 1, .has_hotplug = 1, 295277487Skib .has_fbc = 0, 296277487Skib .has_bsd_ring = 1, 297277487Skib .has_blt_ring = 1, 298277487Skib .is_valleyview = 1, 299277487Skib}; 300277487Skib 301277487Skibstatic const struct intel_device_info intel_valleyview_d_info = { 302277487Skib .gen = 7, 303277487Skib .need_gfx_hws = 1, .has_hotplug = 1, 304277487Skib .has_fbc = 0, 305277487Skib .has_bsd_ring = 1, 306277487Skib .has_blt_ring = 1, 307277487Skib .is_valleyview = 1, 308277487Skib}; 309277487Skib 310277487Skibstatic const struct intel_device_info intel_haswell_d_info = { 311277487Skib .is_haswell = 1, .gen = 7, 312277487Skib .need_gfx_hws = 1, .has_hotplug = 1, 313277487Skib .has_bsd_ring = 1, 314277487Skib .has_blt_ring = 1, 315277487Skib .has_llc = 1, 316296548Sdumbbell .has_force_wake = 1, 317277487Skib}; 318277487Skib 319277487Skibstatic const struct intel_device_info intel_haswell_m_info = { 320277487Skib .is_haswell = 1, .gen = 7, .is_mobile = 1, 321277487Skib .need_gfx_hws = 1, .has_hotplug = 1, 322277487Skib .has_bsd_ring = 1, 323277487Skib .has_blt_ring = 1, 324277487Skib .has_llc = 1, 325296548Sdumbbell .has_force_wake = 1, 326277487Skib}; 327277487Skib 328296548Sdumbbell/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */ 329296548Sdumbbellstatic const drm_pci_id_list_t pciidlist[] = { 330296548Sdumbbell i915_PCI_IDS 331296548Sdumbbell}; 332296548Sdumbbell 333235783Skibstatic const struct intel_gfx_device_id { 334235783Skib int device; 335235783Skib const struct intel_device_info *info; 336290070Sdumbbell} i915_infolist[] = { /* aka */ 337287173Sbapt INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ 338287173Sbapt INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ 339287173Sbapt INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ 340235783Skib INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), 341287173Sbapt INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ 342287173Sbapt INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ 343287173Sbapt INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ 344287173Sbapt INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ 345287173Sbapt INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ 346287173Sbapt INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ 347287173Sbapt INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ 348287173Sbapt INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ 349287173Sbapt INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ 350287173Sbapt INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ 351287173Sbapt INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ 352287173Sbapt INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ 353287173Sbapt INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ 354287173Sbapt INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ 355287173Sbapt INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ 356287173Sbapt INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ 357287173Sbapt INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ 358287173Sbapt INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ 359287173Sbapt INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ 360287173Sbapt INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ 361287173Sbapt INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ 362287173Sbapt INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ 363287173Sbapt INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ 364235783Skib INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), 365235783Skib INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), 366235783Skib INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), 367235783Skib INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), 368235783Skib INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), 369235783Skib INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), 370235783Skib INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), 371235783Skib INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), 372235783Skib INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), 373235783Skib INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), 374235783Skib INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), 375235783Skib INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ 376235783Skib INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ 377235783Skib INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ 378235783Skib INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ 379235783Skib INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ 380235783Skib INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ 381277487Skib INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ 382277487Skib INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ 383317609Smarkj INTEL_VGA_DEVICE(0x041e, &intel_haswell_d_info), /* GT2 desktop */ 384287173Sbapt INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ 385277487Skib INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ 386277487Skib INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ 387287173Sbapt INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ 388277487Skib INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ 389277487Skib INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ 390287173Sbapt INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ 391287173Sbapt INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ 392287173Sbapt INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ 393287173Sbapt INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ 394287173Sbapt INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ 395287173Sbapt INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ 396287173Sbapt INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ 397287173Sbapt INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ 398287173Sbapt INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ 399287173Sbapt INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ 400287173Sbapt INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ 401287173Sbapt INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ 402287173Sbapt INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ 403287173Sbapt INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ 404287173Sbapt INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ 405287173Sbapt INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ 406287173Sbapt INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ 407287173Sbapt INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ 408287173Sbapt INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ 409287173Sbapt INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */ 410287173Sbapt INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */ 411287173Sbapt INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ 412287173Sbapt INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */ 413287173Sbapt INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */ 414287173Sbapt INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ 415287173Sbapt INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ 416287173Sbapt INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ 417287173Sbapt INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ 418287173Sbapt INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), 419287173Sbapt INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), 420287173Sbapt INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), 421235783Skib {0, 0} 422235783Skib}; 423235783Skib 424296548Sdumbbell#if defined(CONFIG_DRM_I915_KMS) 425296548SdumbbellMODULE_DEVICE_TABLE(pci, pciidlist); 426296548Sdumbbell#endif 427278146Skib 428290070Sdumbbellvoid intel_detect_pch(struct drm_device *dev) 429290070Sdumbbell{ 430290070Sdumbbell struct drm_i915_private *dev_priv = dev->dev_private; 431290070Sdumbbell device_t pch; 432290070Sdumbbell 433296548Sdumbbell /* 434296548Sdumbbell * The reason to probe ISA bridge instead of Dev31:Fun0 is to 435296548Sdumbbell * make graphics device passthrough work easy for VMM, that only 436296548Sdumbbell * need to expose ISA bridge to let driver know the real hardware 437296548Sdumbbell * underneath. This is a requirement from virtualization team. 438296548Sdumbbell */ 439290070Sdumbbell pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA); 440296548Sdumbbell if (pch) { 441296548Sdumbbell if (pci_get_vendor(pch) == PCI_VENDOR_ID_INTEL) { 442296548Sdumbbell unsigned short id; 443296548Sdumbbell id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; 444296548Sdumbbell dev_priv->pch_id = id; 445296548Sdumbbell 446296548Sdumbbell if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { 447296548Sdumbbell dev_priv->pch_type = PCH_IBX; 448296548Sdumbbell dev_priv->num_pch_pll = 2; 449296548Sdumbbell DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); 450296548Sdumbbell WARN_ON(!IS_GEN5(dev)); 451296548Sdumbbell } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { 452296548Sdumbbell dev_priv->pch_type = PCH_CPT; 453296548Sdumbbell dev_priv->num_pch_pll = 2; 454296548Sdumbbell DRM_DEBUG_KMS("Found CougarPoint PCH\n"); 455296548Sdumbbell WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 456296548Sdumbbell } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { 457296548Sdumbbell /* PantherPoint is CPT compatible */ 458296548Sdumbbell dev_priv->pch_type = PCH_CPT; 459296548Sdumbbell dev_priv->num_pch_pll = 2; 460296548Sdumbbell DRM_DEBUG_KMS("Found PatherPoint PCH\n"); 461296548Sdumbbell WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 462296548Sdumbbell } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { 463296548Sdumbbell dev_priv->pch_type = PCH_LPT; 464296548Sdumbbell dev_priv->num_pch_pll = 0; 465296548Sdumbbell DRM_DEBUG_KMS("Found LynxPoint PCH\n"); 466296548Sdumbbell WARN_ON(!IS_HASWELL(dev)); 467296548Sdumbbell } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { 468296548Sdumbbell dev_priv->pch_type = PCH_LPT; 469296548Sdumbbell dev_priv->num_pch_pll = 0; 470296548Sdumbbell DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); 471296548Sdumbbell WARN_ON(!IS_HASWELL(dev)); 472296548Sdumbbell } 473296548Sdumbbell BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS); 474296548Sdumbbell } 475296548Sdumbbell } 476290070Sdumbbell} 477290070Sdumbbell 478290070Sdumbbellbool i915_semaphore_is_enabled(struct drm_device *dev) 479290070Sdumbbell{ 480290070Sdumbbell if (INTEL_INFO(dev)->gen < 6) 481290070Sdumbbell return 0; 482290070Sdumbbell 483290070Sdumbbell if (i915_semaphores >= 0) 484290070Sdumbbell return i915_semaphores; 485290070Sdumbbell 486296548Sdumbbell#ifdef CONFIG_INTEL_IOMMU 487290070Sdumbbell /* Enable semaphores on SNB when IO remapping is off */ 488290070Sdumbbell if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) 489290070Sdumbbell return false; 490296548Sdumbbell#endif 491290070Sdumbbell 492290070Sdumbbell return 1; 493290070Sdumbbell} 494290070Sdumbbell 495235783Skibstatic int i915_drm_freeze(struct drm_device *dev) 496235783Skib{ 497287173Sbapt struct drm_i915_private *dev_priv = dev->dev_private; 498235783Skib 499235783Skib drm_kms_helper_poll_disable(dev); 500235783Skib 501296548Sdumbbell#ifdef __linux__ 502235783Skib pci_save_state(dev->pdev); 503235783Skib#endif 504235783Skib 505235783Skib /* If KMS is active, we do the leavevt stuff here */ 506235783Skib if (drm_core_check_feature(dev, DRIVER_MODESET)) { 507287173Sbapt int error = i915_gem_idle(dev); 508235783Skib if (error) { 509296548Sdumbbell dev_err(dev->dev, 510287173Sbapt "GEM idle failed, resume might fail\n"); 511287173Sbapt return error; 512235783Skib } 513296548Sdumbbell 514296548Sdumbbell taskqueue_cancel_timeout(dev_priv->wq, 515296548Sdumbbell &dev_priv->rps.delayed_resume_work, NULL); 516296548Sdumbbell 517296548Sdumbbell intel_modeset_disable(dev); 518296548Sdumbbell 519235783Skib drm_irq_uninstall(dev); 520235783Skib } 521235783Skib 522235783Skib i915_save_state(dev); 523235783Skib 524235783Skib intel_opregion_fini(dev); 525235783Skib 526235783Skib /* Modeset on resume, not lid events */ 527235783Skib dev_priv->modeset_on_lid = 0; 528235783Skib 529296548Sdumbbell console_lock(); 530296548Sdumbbell intel_fbdev_set_suspend(dev, 1); 531296548Sdumbbell console_unlock(); 532296548Sdumbbell 533235783Skib return 0; 534235783Skib} 535235783Skib 536296548Sdumbbellint i915_suspend(struct drm_device *dev, pm_message_t state) 537235783Skib{ 538235783Skib int error; 539235783Skib 540290070Sdumbbell if (!dev || !dev->dev_private) { 541296548Sdumbbell DRM_ERROR("dev: %p\n", dev); 542235783Skib DRM_ERROR("DRM not initialized, aborting suspend.\n"); 543296548Sdumbbell return -ENODEV; 544235783Skib } 545235783Skib 546296548Sdumbbell if (state.event == PM_EVENT_PRETHAW) 547296548Sdumbbell return 0; 548296548Sdumbbell 549296548Sdumbbell 550296548Sdumbbell if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 551296548Sdumbbell return 0; 552296548Sdumbbell 553235783Skib error = i915_drm_freeze(dev); 554235783Skib if (error) 555296548Sdumbbell return error; 556235783Skib 557296548Sdumbbell if (state.event == PM_EVENT_SUSPEND) { 558296548Sdumbbell#ifdef __linux__ 559296548Sdumbbell /* Shut down the device */ 560296548Sdumbbell pci_disable_device(dev->pdev); 561296548Sdumbbell pci_set_power_state(dev->pdev, PCI_D3hot); 562296548Sdumbbell#endif 563296548Sdumbbell } 564296548Sdumbbell 565296548Sdumbbell return 0; 566235783Skib} 567235783Skib 568296548Sdumbbellvoid intel_console_resume(void *arg, int pending) 569235783Skib{ 570296548Sdumbbell struct drm_i915_private *dev_priv = 571296548Sdumbbell arg; 572296548Sdumbbell struct drm_device *dev = dev_priv->dev; 573296548Sdumbbell 574296548Sdumbbell console_lock(); 575296548Sdumbbell intel_fbdev_set_suspend(dev, 0); 576296548Sdumbbell console_unlock(); 577296548Sdumbbell} 578296548Sdumbbell 579296548Sdumbbellstatic int __i915_drm_thaw(struct drm_device *dev) 580296548Sdumbbell{ 581235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 582235783Skib int error = 0; 583235783Skib 584235783Skib i915_restore_state(dev); 585235783Skib intel_opregion_setup(dev); 586235783Skib 587235783Skib /* KMS EnterVT equivalent */ 588235783Skib if (drm_core_check_feature(dev, DRIVER_MODESET)) { 589296548Sdumbbell intel_init_pch_refclk(dev); 590277487Skib 591280183Sdumbbell DRM_LOCK(dev); 592235783Skib dev_priv->mm.suspended = 0; 593235783Skib 594235783Skib error = i915_gem_init_hw(dev); 595277487Skib DRM_UNLOCK(dev); 596235783Skib 597277487Skib intel_modeset_init_hw(dev); 598296548Sdumbbell intel_modeset_setup_hw_state(dev, false); 599235783Skib drm_irq_install(dev); 600235783Skib } 601235783Skib 602235783Skib intel_opregion_init(dev); 603235783Skib 604235783Skib dev_priv->modeset_on_lid = 0; 605235783Skib 606296548Sdumbbell /* 607296548Sdumbbell * The console lock can be pretty contented on resume due 608296548Sdumbbell * to all the printk activity. Try to keep it out of the hot 609296548Sdumbbell * path of resume if possible. 610296548Sdumbbell */ 611296548Sdumbbell if (console_trylock()) { 612296548Sdumbbell intel_fbdev_set_suspend(dev, 0); 613296548Sdumbbell console_unlock(); 614296548Sdumbbell } else { 615296548Sdumbbell taskqueue_enqueue(dev_priv->wq, 616296548Sdumbbell &dev_priv->console_resume_work); 617296548Sdumbbell } 618296548Sdumbbell 619235783Skib return error; 620235783Skib} 621235783Skib 622296548Sdumbbell#ifdef __linux__ 623296548Sdumbbellstatic int i915_drm_thaw(struct drm_device *dev) 624235783Skib{ 625296548Sdumbbell int error = 0; 626296548Sdumbbell 627296548Sdumbbell intel_gt_reset(dev); 628296548Sdumbbell 629296548Sdumbbell if (drm_core_check_feature(dev, DRIVER_MODESET)) { 630296548Sdumbbell DRM_LOCK(dev); 631296548Sdumbbell i915_gem_restore_gtt_mappings(dev); 632296548Sdumbbell DRM_UNLOCK(dev); 633296548Sdumbbell } 634296548Sdumbbell 635296548Sdumbbell __i915_drm_thaw(dev); 636296548Sdumbbell 637296548Sdumbbell return error; 638296548Sdumbbell} 639296548Sdumbbell#endif 640296548Sdumbbell 641296548Sdumbbellint i915_resume(struct drm_device *dev) 642296548Sdumbbell{ 643296548Sdumbbell struct drm_i915_private *dev_priv = dev->dev_private; 644235783Skib int ret; 645235783Skib 646296548Sdumbbell if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 647296548Sdumbbell return 0; 648296548Sdumbbell 649296548Sdumbbell#ifdef __linux__ 650235783Skib if (pci_enable_device(dev->pdev)) 651235783Skib return -EIO; 652235783Skib 653235783Skib pci_set_master(dev->pdev); 654235783Skib#endif 655235783Skib 656296548Sdumbbell intel_gt_reset(dev); 657296548Sdumbbell 658296548Sdumbbell /* 659296548Sdumbbell * Platforms with opregion should have sane BIOS, older ones (gen3 and 660296548Sdumbbell * earlier) need this since the BIOS might clear all our scratch PTEs. 661296548Sdumbbell */ 662296548Sdumbbell if (drm_core_check_feature(dev, DRIVER_MODESET) && 663296548Sdumbbell !dev_priv->opregion.header) { 664296548Sdumbbell DRM_LOCK(dev); 665296548Sdumbbell i915_gem_restore_gtt_mappings(dev); 666296548Sdumbbell DRM_UNLOCK(dev); 667296548Sdumbbell } 668296548Sdumbbell 669296548Sdumbbell ret = __i915_drm_thaw(dev); 670290070Sdumbbell if (ret) 671296548Sdumbbell return ret; 672235783Skib 673235783Skib drm_kms_helper_poll_enable(dev); 674296548Sdumbbell return 0; 675235783Skib} 676235783Skib 677287173Sbaptstatic int i8xx_do_reset(struct drm_device *dev) 678235783Skib{ 679235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 680235783Skib int onems; 681235783Skib 682235783Skib if (IS_I85X(dev)) 683235783Skib return -ENODEV; 684235783Skib 685235783Skib onems = hz / 1000; 686235783Skib if (onems == 0) 687235783Skib onems = 1; 688235783Skib 689235783Skib I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830); 690235783Skib POSTING_READ(D_STATE); 691235783Skib 692235783Skib if (IS_I830(dev) || IS_845G(dev)) { 693235783Skib I915_WRITE(DEBUG_RESET_I830, 694235783Skib DEBUG_RESET_DISPLAY | 695235783Skib DEBUG_RESET_RENDER | 696235783Skib DEBUG_RESET_FULL); 697235783Skib POSTING_READ(DEBUG_RESET_I830); 698235783Skib pause("i8xxrst1", onems); 699235783Skib 700235783Skib I915_WRITE(DEBUG_RESET_I830, 0); 701235783Skib POSTING_READ(DEBUG_RESET_I830); 702235783Skib } 703235783Skib 704235783Skib pause("i8xxrst2", onems); 705235783Skib 706235783Skib I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830); 707235783Skib POSTING_READ(D_STATE); 708235783Skib 709235783Skib return 0; 710235783Skib} 711235783Skib 712287173Sbaptstatic int i965_reset_complete(struct drm_device *dev) 713235783Skib{ 714235783Skib u8 gdrst; 715296548Sdumbbell pci_read_config_byte(dev->dev, I965_GDRST, &gdrst); 716277487Skib return (gdrst & GRDOM_RESET_ENABLE) == 0; 717235783Skib} 718235783Skib 719287173Sbaptstatic int i965_do_reset(struct drm_device *dev) 720235783Skib{ 721277487Skib int ret; 722235783Skib u8 gdrst; 723235783Skib 724235783Skib /* 725235783Skib * Set the domains we want to reset (GRDOM/bits 2 and 3) as 726235783Skib * well as the reset bit (GR/bit 0). Setting the GR bit 727235783Skib * triggers the reset; when done, the hardware will clear it. 728235783Skib */ 729296548Sdumbbell pci_read_config_byte(dev->dev, I965_GDRST, &gdrst); 730296548Sdumbbell pci_write_config_byte(dev->dev, I965_GDRST, 731290070Sdumbbell gdrst | GRDOM_RENDER | 732296548Sdumbbell GRDOM_RESET_ENABLE); 733277487Skib ret = wait_for(i965_reset_complete(dev), 500); 734277487Skib if (ret) 735277487Skib return ret; 736277487Skib 737277487Skib /* We can't reset render&media without also resetting display ... */ 738296548Sdumbbell pci_read_config_byte(dev->dev, I965_GDRST, &gdrst); 739296548Sdumbbell pci_write_config_byte(dev->dev, I965_GDRST, 740290070Sdumbbell gdrst | GRDOM_MEDIA | 741296548Sdumbbell GRDOM_RESET_ENABLE); 742287173Sbapt 743287173Sbapt return wait_for(i965_reset_complete(dev), 500); 744235783Skib} 745235783Skib 746287173Sbaptstatic int ironlake_do_reset(struct drm_device *dev) 747235783Skib{ 748287173Sbapt struct drm_i915_private *dev_priv = dev->dev_private; 749235783Skib u32 gdrst; 750277487Skib int ret; 751235783Skib 752235783Skib gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); 753271705Sdumbbell I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 754277487Skib gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); 755277487Skib ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); 756277487Skib if (ret) 757277487Skib return ret; 758277487Skib 759277487Skib /* We can't reset render&media without also resetting display ... */ 760277487Skib gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); 761277487Skib I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 762277487Skib gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); 763287173Sbapt return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); 764235783Skib} 765235783Skib 766287173Sbaptstatic int gen6_do_reset(struct drm_device *dev) 767235783Skib{ 768287173Sbapt struct drm_i915_private *dev_priv = dev->dev_private; 769287173Sbapt int ret; 770235783Skib 771235783Skib /* Hold gt_lock across reset to prevent any register access 772235783Skib * with forcewake not set correctly 773235783Skib */ 774235783Skib mtx_lock(&dev_priv->gt_lock); 775235783Skib 776235783Skib /* Reset the chip */ 777235783Skib 778235783Skib /* GEN6_GDRST is not in the gt power well, no need to check 779235783Skib * for fifo space for the write or forcewake the chip for 780235783Skib * the read 781235783Skib */ 782235783Skib I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); 783235783Skib 784235783Skib /* Spin waiting for the device to ack the reset request */ 785296548Sdumbbell /* 786296548Sdumbbell * NOTE Linux<->FreeBSD: We use _intel_wait_for() instead of 787296548Sdumbbell * wait_for(), because we want to set the 4th argument to 0. 788296548Sdumbbell * This allows us to use a struct mtx for dev_priv->gt_lock and 789296548Sdumbbell * avoid a LOR. 790296548Sdumbbell */ 791235783Skib ret = _intel_wait_for(dev, 792256848Skib (I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 793277487Skib 500, 0, "915rst"); 794235783Skib 795235783Skib /* If reset with a user forcewake, try to restore, otherwise turn it off */ 796290070Sdumbbell if (dev_priv->forcewake_count) 797296548Sdumbbell dev_priv->gt.force_wake_get(dev_priv); 798235783Skib else 799296548Sdumbbell dev_priv->gt.force_wake_put(dev_priv); 800235783Skib 801235783Skib /* Restore fifo count */ 802235783Skib dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); 803235783Skib 804235783Skib mtx_unlock(&dev_priv->gt_lock); 805290070Sdumbbell return ret; 806235783Skib} 807235783Skib 808287173Sbaptint intel_gpu_reset(struct drm_device *dev) 809271705Sdumbbell{ 810271705Sdumbbell struct drm_i915_private *dev_priv = dev->dev_private; 811271705Sdumbbell int ret = -ENODEV; 812271705Sdumbbell 813271705Sdumbbell switch (INTEL_INFO(dev)->gen) { 814271705Sdumbbell case 7: 815271705Sdumbbell case 6: 816271705Sdumbbell ret = gen6_do_reset(dev); 817271705Sdumbbell break; 818271705Sdumbbell case 5: 819271705Sdumbbell ret = ironlake_do_reset(dev); 820271705Sdumbbell break; 821271705Sdumbbell case 4: 822271705Sdumbbell ret = i965_do_reset(dev); 823271705Sdumbbell break; 824271705Sdumbbell case 2: 825271705Sdumbbell ret = i8xx_do_reset(dev); 826271705Sdumbbell break; 827271705Sdumbbell } 828271705Sdumbbell 829271705Sdumbbell /* Also reset the gpu hangman. */ 830271705Sdumbbell if (dev_priv->stop_rings) { 831271705Sdumbbell DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n"); 832271705Sdumbbell dev_priv->stop_rings = 0; 833271705Sdumbbell if (ret == -ENODEV) { 834271705Sdumbbell DRM_ERROR("Reset not implemented, but ignoring " 835271705Sdumbbell "error for simulated gpu hangs\n"); 836271705Sdumbbell ret = 0; 837271705Sdumbbell } 838271705Sdumbbell } 839271705Sdumbbell 840271705Sdumbbell return ret; 841271705Sdumbbell} 842271705Sdumbbell 843287173Sbapt/** 844287173Sbapt * i915_reset - reset chip after a hang 845287173Sbapt * @dev: drm device to reset 846287173Sbapt * 847287173Sbapt * Reset the chip. Useful if a hang is detected. Returns zero on successful 848287173Sbapt * reset or otherwise an error code. 849287173Sbapt * 850287173Sbapt * Procedure is fairly simple: 851287173Sbapt * - reset the chip using the reset reg 852287173Sbapt * - re-init context state 853287173Sbapt * - re-init hardware status page 854287173Sbapt * - re-init ring buffer 855287173Sbapt * - re-init interrupt state 856287173Sbapt * - re-init display 857287173Sbapt */ 858277487Skibint i915_reset(struct drm_device *dev) 859235783Skib{ 860235783Skib drm_i915_private_t *dev_priv = dev->dev_private; 861235783Skib int ret; 862235783Skib 863235783Skib if (!i915_try_reset) 864287173Sbapt return 0; 865235783Skib 866296548Sdumbbell DRM_LOCK(dev); 867235783Skib 868235783Skib i915_gem_reset(dev); 869235783Skib 870235783Skib ret = -ENODEV; 871296548Sdumbbell if (get_seconds() - dev_priv->last_gpu_reset < 5) 872235783Skib DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); 873277487Skib else 874271705Sdumbbell ret = intel_gpu_reset(dev); 875271705Sdumbbell 876296548Sdumbbell dev_priv->last_gpu_reset = get_seconds(); 877235783Skib if (ret) { 878235783Skib DRM_ERROR("Failed to reset chip.\n"); 879235783Skib DRM_UNLOCK(dev); 880287173Sbapt return ret; 881235783Skib } 882235783Skib 883287173Sbapt /* Ok, now get things going again... */ 884287173Sbapt 885287173Sbapt /* 886287173Sbapt * Everything depends on having the GTT running, so we need to start 887287173Sbapt * there. Fortunately we don't need to do this unless we reset the 888287173Sbapt * chip at a PCI level. 889287173Sbapt * 890287173Sbapt * Next we need to restore the context, but we don't use those 891287173Sbapt * yet either... 892287173Sbapt * 893287173Sbapt * Ring buffer needs to be re-initialized in the KMS case, or if X 894287173Sbapt * was running at the time of the reset (i.e. we weren't VT 895287173Sbapt * switched away). 896287173Sbapt */ 897235783Skib if (drm_core_check_feature(dev, DRIVER_MODESET) || 898287173Sbapt !dev_priv->mm.suspended) { 899277487Skib struct intel_ring_buffer *ring; 900277487Skib int i; 901277487Skib 902235783Skib dev_priv->mm.suspended = 0; 903235783Skib 904235783Skib i915_gem_init_swizzling(dev); 905235783Skib 906277487Skib for_each_ring(ring, dev_priv, i) 907277487Skib ring->init(ring); 908235783Skib 909271705Sdumbbell i915_gem_context_init(dev); 910235783Skib i915_gem_init_ppgtt(dev); 911235783Skib 912287173Sbapt /* 913287173Sbapt * It would make sense to re-init all the other hw state, at 914287173Sbapt * least the rps/rc6/emon init done within modeset_init_hw. For 915287173Sbapt * some unknown reason, this blows up my ilk, so don't. 916287173Sbapt */ 917290070Sdumbbell 918277487Skib DRM_UNLOCK(dev); 919277487Skib 920235783Skib drm_irq_uninstall(dev); 921235783Skib drm_irq_install(dev); 922287173Sbapt } else { 923277487Skib DRM_UNLOCK(dev); 924287173Sbapt } 925235783Skib 926287173Sbapt return 0; 927235783Skib} 928235783Skib 929290070Sdumbbellconst struct intel_device_info * 930290070Sdumbbelli915_get_device_id(int device) 931290070Sdumbbell{ 932290070Sdumbbell const struct intel_gfx_device_id *did; 933290070Sdumbbell 934290070Sdumbbell for (did = &i915_infolist[0]; did->device != 0; did++) { 935290070Sdumbbell if (did->device != device) 936290070Sdumbbell continue; 937290070Sdumbbell return (did->info); 938290070Sdumbbell } 939290070Sdumbbell return (NULL); 940290070Sdumbbell} 941290070Sdumbbell 942290070Sdumbbellstatic int i915_probe(device_t kdev) 943290070Sdumbbell{ 944290070Sdumbbell const struct intel_device_info *intel_info = 945290070Sdumbbell i915_get_device_id(pci_get_device(kdev)); 946290070Sdumbbell 947290070Sdumbbell if (intel_info == NULL) 948290070Sdumbbell return (ENXIO); 949296548Sdumbbell if (intel_info->is_valleyview) 950296548Sdumbbell if(!i915_preliminary_hw_support) { 951296548Sdumbbell DRM_ERROR("Preliminary hardware support disabled\n"); 952296548Sdumbbell return (ENXIO); 953296548Sdumbbell } 954290070Sdumbbell 955296548Sdumbbell /* Only bind to function 0 of the device. Early generations 956296548Sdumbbell * used function 1 as a placeholder for multi-head. This causes 957296548Sdumbbell * us confusion instead, especially on the systems where both 958296548Sdumbbell * functions have the same PCI-ID! 959296548Sdumbbell */ 960296548Sdumbbell if (pci_get_function(kdev)) 961296548Sdumbbell return (ENXIO); 962296548Sdumbbell 963296548Sdumbbell /* We've managed to ship a kms-enabled ddx that shipped with an XvMC 964296548Sdumbbell * implementation for gen3 (and only gen3) that used legacy drm maps 965296548Sdumbbell * (gasp!) to share buffers between X and the client. Hence we need to 966296548Sdumbbell * keep around the fake agp stuff for gen3, even when kms is enabled. */ 967296548Sdumbbell if (intel_info->gen != 3) { 968296548Sdumbbell driver.driver_features &= 969296548Sdumbbell ~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP); 970296548Sdumbbell } else if (!intel_agp_enabled) { 971296548Sdumbbell DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); 972296548Sdumbbell return (ENXIO); 973296548Sdumbbell } 974296548Sdumbbell 975296548Sdumbbell return -drm_probe_helper(kdev, pciidlist); 976290070Sdumbbell} 977290070Sdumbbell 978296548Sdumbbell#ifdef __linux__ 979296548Sdumbbellstatic void 980296548Sdumbbelli915_pci_remove(struct pci_dev *pdev) 981290070Sdumbbell{ 982296548Sdumbbell struct drm_device *dev = pci_get_drvdata(pdev); 983290070Sdumbbell 984296548Sdumbbell drm_put_dev(dev); 985296548Sdumbbell} 986296548Sdumbbell 987296548Sdumbbellstatic int i915_pm_suspend(struct device *dev) 988296548Sdumbbell{ 989296548Sdumbbell struct pci_dev *pdev = to_pci_dev(dev); 990296548Sdumbbell struct drm_device *drm_dev = pci_get_drvdata(pdev); 991296548Sdumbbell int error; 992296548Sdumbbell 993296548Sdumbbell if (!drm_dev || !drm_dev->dev_private) { 994296548Sdumbbell dev_err(dev, "DRM not initialized, aborting suspend.\n"); 995296548Sdumbbell return -ENODEV; 996296548Sdumbbell } 997296548Sdumbbell 998296548Sdumbbell if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 999296548Sdumbbell return 0; 1000296548Sdumbbell 1001296548Sdumbbell error = i915_drm_freeze(drm_dev); 1002296548Sdumbbell if (error) 1003296548Sdumbbell return error; 1004296548Sdumbbell 1005296548Sdumbbell pci_disable_device(pdev); 1006296548Sdumbbell pci_set_power_state(pdev, PCI_D3hot); 1007296548Sdumbbell 1008296548Sdumbbell return 0; 1009296548Sdumbbell} 1010296548Sdumbbell 1011296548Sdumbbellstatic int i915_pm_resume(struct device *dev) 1012296548Sdumbbell{ 1013296548Sdumbbell struct pci_dev *pdev = to_pci_dev(dev); 1014296548Sdumbbell struct drm_device *drm_dev = pci_get_drvdata(pdev); 1015296548Sdumbbell 1016296548Sdumbbell return i915_resume(drm_dev); 1017296548Sdumbbell} 1018296548Sdumbbell 1019296548Sdumbbellstatic int i915_pm_freeze(struct device *dev) 1020296548Sdumbbell{ 1021296548Sdumbbell struct pci_dev *pdev = to_pci_dev(dev); 1022296548Sdumbbell struct drm_device *drm_dev = pci_get_drvdata(pdev); 1023296548Sdumbbell 1024296548Sdumbbell if (!drm_dev || !drm_dev->dev_private) { 1025296548Sdumbbell dev_err(dev, "DRM not initialized, aborting suspend.\n"); 1026296548Sdumbbell return -ENODEV; 1027296548Sdumbbell } 1028296548Sdumbbell 1029296548Sdumbbell return i915_drm_freeze(drm_dev); 1030296548Sdumbbell} 1031296548Sdumbbell 1032296548Sdumbbellstatic int i915_pm_thaw(struct device *dev) 1033296548Sdumbbell{ 1034296548Sdumbbell struct pci_dev *pdev = to_pci_dev(dev); 1035296548Sdumbbell struct drm_device *drm_dev = pci_get_drvdata(pdev); 1036296548Sdumbbell 1037296548Sdumbbell return i915_drm_thaw(drm_dev); 1038296548Sdumbbell} 1039296548Sdumbbell 1040296548Sdumbbellstatic int i915_pm_poweroff(struct device *dev) 1041296548Sdumbbell{ 1042296548Sdumbbell struct pci_dev *pdev = to_pci_dev(dev); 1043296548Sdumbbell struct drm_device *drm_dev = pci_get_drvdata(pdev); 1044296548Sdumbbell 1045296548Sdumbbell return i915_drm_freeze(drm_dev); 1046296548Sdumbbell} 1047296548Sdumbbell 1048296548Sdumbbellstatic const struct dev_pm_ops i915_pm_ops = { 1049296548Sdumbbell .suspend = i915_pm_suspend, 1050296548Sdumbbell .resume = i915_pm_resume, 1051296548Sdumbbell .freeze = i915_pm_freeze, 1052296548Sdumbbell .thaw = i915_pm_thaw, 1053296548Sdumbbell .poweroff = i915_pm_poweroff, 1054296548Sdumbbell .restore = i915_pm_resume, 1055296548Sdumbbell}; 1056296548Sdumbbell 1057296548Sdumbbellstatic const struct vm_operations_struct i915_gem_vm_ops = { 1058296548Sdumbbell .fault = i915_gem_fault, 1059296548Sdumbbell .open = drm_gem_vm_open, 1060296548Sdumbbell .close = drm_gem_vm_close, 1061296548Sdumbbell}; 1062296548Sdumbbell 1063296548Sdumbbellstatic const struct file_operations i915_driver_fops = { 1064296548Sdumbbell .owner = THIS_MODULE, 1065296548Sdumbbell .open = drm_open, 1066296548Sdumbbell .release = drm_release, 1067296548Sdumbbell .unlocked_ioctl = drm_ioctl, 1068296548Sdumbbell .mmap = drm_gem_mmap, 1069296548Sdumbbell .poll = drm_poll, 1070296548Sdumbbell .fasync = drm_fasync, 1071296548Sdumbbell .read = drm_read, 1072296548Sdumbbell#ifdef CONFIG_COMPAT 1073296548Sdumbbell .compat_ioctl = i915_compat_ioctl, 1074296548Sdumbbell#endif 1075296548Sdumbbell .llseek = noop_llseek, 1076296548Sdumbbell}; 1077296548Sdumbbell#endif /* __linux__ */ 1078296548Sdumbbell 1079296548Sdumbbell#ifdef COMPAT_FREEBSD32 1080296548Sdumbbellextern struct drm_ioctl_desc i915_compat_ioctls[]; 1081296548Sdumbbellextern int i915_compat_ioctls_nr; 1082296548Sdumbbell#endif 1083296548Sdumbbell 1084296548Sdumbbellstatic struct drm_driver driver = { 1085296548Sdumbbell /* Don't use MTRRs here; the Xserver or userspace app should 1086296548Sdumbbell * deal with them for Intel hardware. 1087296548Sdumbbell */ 1088296548Sdumbbell .driver_features = 1089296548Sdumbbell DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ 1090296548Sdumbbell DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME, 1091296548Sdumbbell .load = i915_driver_load, 1092296548Sdumbbell .unload = i915_driver_unload, 1093296548Sdumbbell .open = i915_driver_open, 1094296548Sdumbbell .lastclose = i915_driver_lastclose, 1095296548Sdumbbell .preclose = i915_driver_preclose, 1096296548Sdumbbell .postclose = i915_driver_postclose, 1097296548Sdumbbell 1098296548Sdumbbell /* Used in place of i915_pm_ops for non-DRIVER_MODESET */ 1099296548Sdumbbell .suspend = i915_suspend, 1100296548Sdumbbell .resume = i915_resume, 1101296548Sdumbbell 1102296548Sdumbbell .device_is_agp = i915_driver_device_is_agp, 1103296548Sdumbbell .master_create = i915_master_create, 1104296548Sdumbbell .master_destroy = i915_master_destroy, 1105296548Sdumbbell#if defined(CONFIG_DEBUG_FS) 1106296548Sdumbbell .debugfs_init = i915_debugfs_init, 1107296548Sdumbbell .debugfs_cleanup = i915_debugfs_cleanup, 1108296548Sdumbbell#endif 1109296548Sdumbbell .gem_init_object = i915_gem_init_object, 1110296548Sdumbbell .gem_free_object = i915_gem_free_object, 1111296548Sdumbbell#if defined(__linux__) 1112296548Sdumbbell .gem_vm_ops = &i915_gem_vm_ops, 1113296548Sdumbbell#elif defined(__FreeBSD__) 1114296548Sdumbbell .gem_pager_ops = &i915_gem_pager_ops, 1115296548Sdumbbell#endif 1116296548Sdumbbell 1117296548Sdumbbell#ifdef FREEBSD_WIP 1118296548Sdumbbell .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 1119296548Sdumbbell .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 1120296548Sdumbbell .gem_prime_export = i915_gem_prime_export, 1121296548Sdumbbell .gem_prime_import = i915_gem_prime_import, 1122296548Sdumbbell#endif /* FREEBSD_WIP */ 1123296548Sdumbbell 1124296548Sdumbbell .dumb_create = i915_gem_dumb_create, 1125296548Sdumbbell .dumb_map_offset = i915_gem_mmap_gtt, 1126296548Sdumbbell .dumb_destroy = i915_gem_dumb_destroy, 1127296548Sdumbbell .ioctls = i915_ioctls, 1128296548Sdumbbell#ifdef COMPAT_FREEBSD32 1129296548Sdumbbell .compat_ioctls = i915_compat_ioctls, 1130296548Sdumbbell .num_compat_ioctls = &i915_compat_ioctls_nr, 1131296548Sdumbbell#endif 1132296548Sdumbbell#ifdef __linux__ 1133296548Sdumbbell .fops = &i915_driver_fops, 1134296548Sdumbbell#endif 1135296548Sdumbbell#ifdef __FreeBSD__ 1136296548Sdumbbell .sysctl_init = i915_sysctl_init, 1137296548Sdumbbell .sysctl_cleanup = i915_sysctl_cleanup, 1138296548Sdumbbell#endif 1139296548Sdumbbell .name = DRIVER_NAME, 1140296548Sdumbbell .desc = DRIVER_DESC, 1141296548Sdumbbell .date = DRIVER_DATE, 1142296548Sdumbbell .major = DRIVER_MAJOR, 1143296548Sdumbbell .minor = DRIVER_MINOR, 1144296548Sdumbbell .patchlevel = DRIVER_PATCHLEVEL, 1145296548Sdumbbell}; 1146296548Sdumbbell 1147296548Sdumbbell#ifdef __linux__ 1148296548Sdumbbellstatic struct pci_driver i915_pci_driver = { 1149296548Sdumbbell .name = DRIVER_NAME, 1150296548Sdumbbell .id_table = pciidlist, 1151296548Sdumbbell .probe = i915_pci_probe, 1152296548Sdumbbell .remove = i915_pci_remove, 1153296548Sdumbbell .driver.pm = &i915_pm_ops, 1154296548Sdumbbell}; 1155296548Sdumbbell#endif 1156296548Sdumbbell 1157296548Sdumbbellstatic int __init i915_attach(device_t kdev) 1158296548Sdumbbell{ 1159296548Sdumbbell driver.num_ioctls = i915_max_ioctl; 1160296548Sdumbbell 1161296548Sdumbbell /* 1162296548Sdumbbell * If CONFIG_DRM_I915_KMS is set, default to KMS unless 1163296548Sdumbbell * explicitly disabled with the module pararmeter. 1164296548Sdumbbell * 1165296548Sdumbbell * Otherwise, just follow the parameter (defaulting to off). 1166296548Sdumbbell * 1167296548Sdumbbell * Allow optional vga_text_mode_force boot option to override 1168296548Sdumbbell * the default behavior. 1169296548Sdumbbell */ 1170296548Sdumbbell#if defined(CONFIG_DRM_I915_KMS) 1171296548Sdumbbell if (i915_modeset != 0) 1172296548Sdumbbell driver.driver_features |= DRIVER_MODESET; 1173296548Sdumbbell#endif 1174290070Sdumbbell if (i915_modeset == 1) 1175296548Sdumbbell driver.driver_features |= DRIVER_MODESET; 1176296548Sdumbbell 1177296548Sdumbbell#ifdef CONFIG_VGA_CONSOLE 1178296548Sdumbbell if (vgacon_text_force() && i915_modeset == -1) 1179296548Sdumbbell driver.driver_features &= ~DRIVER_MODESET; 1180296548Sdumbbell#endif 1181296548Sdumbbell 1182296548Sdumbbell if (!(driver.driver_features & DRIVER_MODESET)) 1183296548Sdumbbell driver.get_vblank_timestamp = NULL; 1184296548Sdumbbell 1185296548Sdumbbell return (-drm_attach_helper(kdev, pciidlist, &driver)); 1186290070Sdumbbell} 1187290070Sdumbbell 1188290070Sdumbbellstatic struct fb_info * 1189290070Sdumbbelli915_fb_helper_getinfo(device_t kdev) 1190290070Sdumbbell{ 1191290070Sdumbbell struct intel_fbdev *ifbdev; 1192290070Sdumbbell drm_i915_private_t *dev_priv; 1193290070Sdumbbell struct drm_device *dev; 1194290070Sdumbbell struct fb_info *info; 1195290070Sdumbbell 1196290070Sdumbbell dev = device_get_softc(kdev); 1197290070Sdumbbell dev_priv = dev->dev_private; 1198290070Sdumbbell ifbdev = dev_priv->fbdev; 1199290070Sdumbbell if (ifbdev == NULL) 1200290070Sdumbbell return (NULL); 1201290070Sdumbbell 1202290070Sdumbbell info = ifbdev->helper.fbdev; 1203290070Sdumbbell 1204290070Sdumbbell return (info); 1205290070Sdumbbell} 1206290070Sdumbbell 1207290070Sdumbbellstatic device_method_t i915_methods[] = { 1208290070Sdumbbell /* Device interface */ 1209290070Sdumbbell DEVMETHOD(device_probe, i915_probe), 1210290070Sdumbbell DEVMETHOD(device_attach, i915_attach), 1211296548Sdumbbell DEVMETHOD(device_suspend, drm_generic_suspend), 1212296548Sdumbbell DEVMETHOD(device_resume, drm_generic_resume), 1213290070Sdumbbell DEVMETHOD(device_detach, drm_generic_detach), 1214290070Sdumbbell 1215290070Sdumbbell /* Framebuffer service methods */ 1216290070Sdumbbell DEVMETHOD(fb_getinfo, i915_fb_helper_getinfo), 1217290070Sdumbbell 1218290070Sdumbbell DEVMETHOD_END 1219290070Sdumbbell}; 1220290070Sdumbbell 1221290070Sdumbbellstatic driver_t i915_driver = { 1222290070Sdumbbell "drmn", 1223290070Sdumbbell i915_methods, 1224290070Sdumbbell sizeof(struct drm_device) 1225290070Sdumbbell}; 1226290070Sdumbbell 1227296548SdumbbellMODULE_AUTHOR(DRIVER_AUTHOR); 1228296548SdumbbellMODULE_DESCRIPTION(DRIVER_DESC); 1229296548SdumbbellMODULE_LICENSE("GPL and additional rights"); 1230296548Sdumbbell 1231290070Sdumbbellextern devclass_t drm_devclass; 1232290070SdumbbellDRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0, 1233290070Sdumbbell SI_ORDER_ANY); 1234290070SdumbbellMODULE_DEPEND(i915kms, drmn, 1, 1, 1); 1235290070SdumbbellMODULE_DEPEND(i915kms, agp, 1, 1, 1); 1236290070SdumbbellMODULE_DEPEND(i915kms, iicbus, 1, 1, 1); 1237290070SdumbbellMODULE_DEPEND(i915kms, iic, 1, 1, 1); 1238290070SdumbbellMODULE_DEPEND(i915kms, iicbb, 1, 1, 1); 1239290070Sdumbbell 1240277487Skib/* We give fast paths for the really cool registers */ 1241277487Skib#define NEEDS_FORCE_WAKE(dev_priv, reg) \ 1242296548Sdumbbell ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ 1243290070Sdumbbell ((reg) < 0x40000) && \ 1244296548Sdumbbell ((reg) != FORCEWAKE)) 1245277487Skib 1246296548Sdumbbellstatic bool IS_DISPLAYREG(u32 reg) 1247290070Sdumbbell{ 1248296548Sdumbbell /* 1249296548Sdumbbell * This should make it easier to transition modules over to the 1250296548Sdumbbell * new register block scheme, since we can do it incrementally. 1251296548Sdumbbell */ 1252296548Sdumbbell if (reg >= VLV_DISPLAY_BASE) 1253296548Sdumbbell return false; 1254290070Sdumbbell 1255296548Sdumbbell if (reg >= RENDER_RING_BASE && 1256296548Sdumbbell reg < RENDER_RING_BASE + 0xff) 1257296548Sdumbbell return false; 1258296548Sdumbbell if (reg >= GEN6_BSD_RING_BASE && 1259296548Sdumbbell reg < GEN6_BSD_RING_BASE + 0xff) 1260296548Sdumbbell return false; 1261296548Sdumbbell if (reg >= BLT_RING_BASE && 1262296548Sdumbbell reg < BLT_RING_BASE + 0xff) 1263296548Sdumbbell return false; 1264290070Sdumbbell 1265296548Sdumbbell if (reg == PGTBL_ER) 1266296548Sdumbbell return false; 1267290070Sdumbbell 1268296548Sdumbbell if (reg >= IPEIR_I965 && 1269296548Sdumbbell reg < HWSTAM) 1270296548Sdumbbell return false; 1271290070Sdumbbell 1272296548Sdumbbell if (reg == MI_MODE) 1273296548Sdumbbell return false; 1274290070Sdumbbell 1275296548Sdumbbell if (reg == GFX_MODE_GEN7) 1276296548Sdumbbell return false; 1277290070Sdumbbell 1278296548Sdumbbell if (reg == RENDER_HWS_PGA_GEN7 || 1279296548Sdumbbell reg == BSD_HWS_PGA_GEN7 || 1280296548Sdumbbell reg == BLT_HWS_PGA_GEN7) 1281296548Sdumbbell return false; 1282290070Sdumbbell 1283296548Sdumbbell if (reg == GEN6_BSD_SLEEP_PSMI_CONTROL || 1284296548Sdumbbell reg == GEN6_BSD_RNCID) 1285296548Sdumbbell return false; 1286290070Sdumbbell 1287296548Sdumbbell if (reg == GEN6_BLITTER_ECOSKPD) 1288296548Sdumbbell return false; 1289290070Sdumbbell 1290296548Sdumbbell if (reg >= 0x4000c && 1291296548Sdumbbell reg <= 0x4002c) 1292296548Sdumbbell return false; 1293290070Sdumbbell 1294296548Sdumbbell if (reg >= 0x4f000 && 1295296548Sdumbbell reg <= 0x4f08f) 1296296548Sdumbbell return false; 1297290070Sdumbbell 1298296548Sdumbbell if (reg >= 0x4f100 && 1299296548Sdumbbell reg <= 0x4f11f) 1300296548Sdumbbell return false; 1301290070Sdumbbell 1302296548Sdumbbell if (reg >= VLV_MASTER_IER && 1303296548Sdumbbell reg <= GEN6_PMIER) 1304296548Sdumbbell return false; 1305290070Sdumbbell 1306296548Sdumbbell if (reg >= FENCE_REG_SANDYBRIDGE_0 && 1307296548Sdumbbell reg < (FENCE_REG_SANDYBRIDGE_0 + (16*8))) 1308296548Sdumbbell return false; 1309290070Sdumbbell 1310296548Sdumbbell if (reg >= VLV_IIR_RW && 1311296548Sdumbbell reg <= VLV_ISR) 1312296548Sdumbbell return false; 1313290070Sdumbbell 1314296548Sdumbbell if (reg == FORCEWAKE_VLV || 1315296548Sdumbbell reg == FORCEWAKE_ACK_VLV) 1316296548Sdumbbell return false; 1317290070Sdumbbell 1318296548Sdumbbell if (reg == GEN6_GDRST) 1319296548Sdumbbell return false; 1320290070Sdumbbell 1321296548Sdumbbell switch (reg) { 1322296548Sdumbbell case _3D_CHICKEN3: 1323296548Sdumbbell case IVB_CHICKEN3: 1324296548Sdumbbell case GEN7_COMMON_SLICE_CHICKEN1: 1325296548Sdumbbell case GEN7_L3CNTLREG1: 1326296548Sdumbbell case GEN7_L3_CHICKEN_MODE_REGISTER: 1327296548Sdumbbell case GEN7_ROW_CHICKEN2: 1328296548Sdumbbell case GEN7_L3SQCREG4: 1329296548Sdumbbell case GEN7_SQ_CHICKEN_MBCUNIT_CONFIG: 1330296548Sdumbbell case GEN7_HALF_SLICE_CHICKEN1: 1331296548Sdumbbell case GEN6_MBCTL: 1332296548Sdumbbell case GEN6_UCGCTL2: 1333296548Sdumbbell return false; 1334296548Sdumbbell default: 1335296548Sdumbbell break; 1336290070Sdumbbell } 1337290070Sdumbbell 1338296548Sdumbbell return true; 1339290070Sdumbbell} 1340290070Sdumbbell 1341296548Sdumbbellstatic void 1342296548Sdumbbellilk_dummy_write(struct drm_i915_private *dev_priv) 1343290070Sdumbbell{ 1344296548Sdumbbell /* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the 1345296548Sdumbbell * chip from rc6 before touching it for real. MI_MODE is masked, hence 1346296548Sdumbbell * harmless to write 0 into. */ 1347296548Sdumbbell I915_WRITE_NOTRACE(MI_MODE, 0); 1348290070Sdumbbell} 1349290070Sdumbbell 1350235783Skib#define __i915_read(x, y) \ 1351235783Skibu##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ 1352235783Skib u##x val = 0; \ 1353296548Sdumbbell if (IS_GEN5(dev_priv->dev)) \ 1354296548Sdumbbell ilk_dummy_write(dev_priv); \ 1355235783Skib if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ 1356235783Skib mtx_lock(&dev_priv->gt_lock); \ 1357235783Skib if (dev_priv->forcewake_count == 0) \ 1358296548Sdumbbell dev_priv->gt.force_wake_get(dev_priv); \ 1359290070Sdumbbell val = DRM_READ##x(dev_priv->mmio_map, reg); \ 1360235783Skib if (dev_priv->forcewake_count == 0) \ 1361296548Sdumbbell dev_priv->gt.force_wake_put(dev_priv); \ 1362235783Skib mtx_unlock(&dev_priv->gt_lock); \ 1363296548Sdumbbell } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ 1364296548Sdumbbell val = DRM_READ##x(dev_priv->mmio_map, reg + 0x180000); \ 1365235783Skib } else { \ 1366290070Sdumbbell val = DRM_READ##x(dev_priv->mmio_map, reg); \ 1367235783Skib } \ 1368235783Skib trace_i915_reg_rw(false, reg, val, sizeof(val)); \ 1369235783Skib return val; \ 1370235783Skib} 1371235783Skib 1372296548Sdumbbell__i915_read(8, b) 1373296548Sdumbbell__i915_read(16, w) 1374296548Sdumbbell__i915_read(32, l) 1375296548Sdumbbell__i915_read(64, q) 1376235783Skib#undef __i915_read 1377235783Skib 1378235783Skib#define __i915_write(x, y) \ 1379235783Skibvoid i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ 1380235783Skib u32 __fifo_ret = 0; \ 1381235783Skib trace_i915_reg_rw(true, reg, val, sizeof(val)); \ 1382235783Skib if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ 1383235783Skib __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ 1384235783Skib } \ 1385296548Sdumbbell if (IS_GEN5(dev_priv->dev)) \ 1386296548Sdumbbell ilk_dummy_write(dev_priv); \ 1387296548Sdumbbell if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ 1388296548Sdumbbell DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \ 1389296548Sdumbbell I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ 1390296548Sdumbbell } \ 1391296548Sdumbbell if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ 1392296548Sdumbbell DRM_WRITE##x(dev_priv->mmio_map, reg + 0x180000, val); \ 1393296548Sdumbbell } else { \ 1394296548Sdumbbell DRM_WRITE##x(dev_priv->mmio_map, reg, val); \ 1395296548Sdumbbell } \ 1396296548Sdumbbell if (unlikely(__fifo_ret)) { \ 1397235783Skib gen6_gt_check_fifodbg(dev_priv); \ 1398235783Skib } \ 1399296548Sdumbbell if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ 1400296548Sdumbbell DRM_ERROR("Unclaimed write to %x\n", reg); \ 1401296548Sdumbbell DRM_WRITE32(dev_priv->mmio_map, GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ 1402296548Sdumbbell } \ 1403235783Skib} 1404296548Sdumbbell__i915_write(8, b) 1405296548Sdumbbell__i915_write(16, w) 1406296548Sdumbbell__i915_write(32, l) 1407296548Sdumbbell__i915_write(64, q) 1408235783Skib#undef __i915_write 1409296548Sdumbbell 1410296548Sdumbbellstatic const struct register_whitelist { 1411296548Sdumbbell uint64_t offset; 1412296548Sdumbbell uint32_t size; 1413296548Sdumbbell uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ 1414296548Sdumbbell} whitelist[] = { 1415296548Sdumbbell { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0xF0 }, 1416296548Sdumbbell}; 1417296548Sdumbbell 1418296548Sdumbbellint i915_reg_read_ioctl(struct drm_device *dev, 1419296548Sdumbbell void *data, struct drm_file *file) 1420296548Sdumbbell{ 1421296548Sdumbbell struct drm_i915_private *dev_priv = dev->dev_private; 1422296548Sdumbbell struct drm_i915_reg_read *reg = data; 1423296548Sdumbbell struct register_whitelist const *entry = whitelist; 1424296548Sdumbbell int i; 1425296548Sdumbbell 1426296548Sdumbbell for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { 1427296548Sdumbbell if (entry->offset == reg->offset && 1428296548Sdumbbell (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) 1429296548Sdumbbell break; 1430296548Sdumbbell } 1431296548Sdumbbell 1432296548Sdumbbell if (i == ARRAY_SIZE(whitelist)) 1433296548Sdumbbell return -EINVAL; 1434296548Sdumbbell 1435296548Sdumbbell switch (entry->size) { 1436296548Sdumbbell case 8: 1437296548Sdumbbell reg->val = I915_READ64(reg->offset); 1438296548Sdumbbell break; 1439296548Sdumbbell case 4: 1440296548Sdumbbell reg->val = I915_READ(reg->offset); 1441296548Sdumbbell break; 1442296548Sdumbbell case 2: 1443296548Sdumbbell reg->val = I915_READ16(reg->offset); 1444296548Sdumbbell break; 1445296548Sdumbbell case 1: 1446296548Sdumbbell reg->val = I915_READ8(reg->offset); 1447296548Sdumbbell break; 1448296548Sdumbbell default: 1449296548Sdumbbell WARN_ON(1); 1450296548Sdumbbell return -EINVAL; 1451296548Sdumbbell } 1452296548Sdumbbell 1453296548Sdumbbell return 0; 1454296548Sdumbbell} 1455