1e555d299SFrançois Tigeot /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- 2c4a9e910SFrançois Tigeot */ 3e555d299SFrançois Tigeot /* 4e555d299SFrançois Tigeot * 5e555d299SFrançois Tigeot * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 6c4a9e910SFrançois Tigeot * All Rights Reserved. 7c4a9e910SFrançois Tigeot * 8c4a9e910SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 9e555d299SFrançois Tigeot * copy of this software and associated documentation files (the 10e555d299SFrançois Tigeot * "Software"), to deal in the Software without restriction, including 11e555d299SFrançois Tigeot * without limitation the rights to use, copy, modify, merge, publish, 12e555d299SFrançois Tigeot * distribute, sub license, and/or sell copies of the Software, and to 13e555d299SFrançois Tigeot * permit persons to whom the Software is furnished to do so, subject to 14e555d299SFrançois Tigeot * the following conditions: 15c4a9e910SFrançois Tigeot * 16e555d299SFrançois Tigeot * The above copyright notice and this permission notice (including the 17e555d299SFrançois Tigeot * next paragraph) shall be included in all copies or substantial portions 18e555d299SFrançois Tigeot * of the Software. 19c4a9e910SFrançois Tigeot * 20e555d299SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21e555d299SFrançois Tigeot * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22e555d299SFrançois Tigeot * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23e555d299SFrançois Tigeot * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 24e555d299SFrançois Tigeot * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25e555d299SFrançois Tigeot * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26e555d299SFrançois Tigeot * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27c4a9e910SFrançois Tigeot * 28c4a9e910SFrançois Tigeot */ 29c4a9e910SFrançois Tigeot 3018e26a6dSFrançois Tigeot #include <drm/drmP.h> 315c6c6f23SFrançois Tigeot #include <drm/i915_drm.h> 32c4a9e910SFrançois Tigeot #include "i915_drv.h" 3318e26a6dSFrançois Tigeot #include <drm/drm_pciids.h> 34e3adcf8fSFrançois Tigeot #include "intel_drv.h" 35c4a9e910SFrançois Tigeot 369edbd4a0SFrançois Tigeot #include <linux/module.h> 379edbd4a0SFrançois Tigeot #include <drm/drm_crtc_helper.h> 389edbd4a0SFrançois Tigeot 39f0b54121SFrançois Tigeot static struct drm_driver driver; 40f0b54121SFrançois Tigeot 41ba55f2f5SFrançois Tigeot #define GEN_DEFAULT_PIPEOFFSETS \ 42ba55f2f5SFrançois Tigeot .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ 43ba55f2f5SFrançois Tigeot PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ 44ba55f2f5SFrançois Tigeot .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ 45ba55f2f5SFrançois Tigeot TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ 46ba55f2f5SFrançois Tigeot .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } 47ba55f2f5SFrançois Tigeot 48ba55f2f5SFrançois Tigeot #define GEN_CHV_PIPEOFFSETS \ 49ba55f2f5SFrançois Tigeot .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ 50ba55f2f5SFrançois Tigeot CHV_PIPE_C_OFFSET }, \ 51ba55f2f5SFrançois Tigeot .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ 52ba55f2f5SFrançois Tigeot CHV_TRANSCODER_C_OFFSET, }, \ 53ba55f2f5SFrançois Tigeot .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ 54ba55f2f5SFrançois Tigeot CHV_PALETTE_C_OFFSET } 55ba55f2f5SFrançois Tigeot 56ba55f2f5SFrançois Tigeot #define CURSOR_OFFSETS \ 57ba55f2f5SFrançois Tigeot .cursor_offsets = { CURSOR_A_OFFSET, CURSOR_B_OFFSET, CHV_CURSOR_C_OFFSET } 58ba55f2f5SFrançois Tigeot 59ba55f2f5SFrançois Tigeot #define IVB_CURSOR_OFFSETS \ 60ba55f2f5SFrançois Tigeot .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } 61ba55f2f5SFrançois Tigeot 62e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i830_info = { 638e26cdf6SFrançois Tigeot .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, 64e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 659edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 66ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 67ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 68e3adcf8fSFrançois Tigeot }; 69c4a9e910SFrançois Tigeot 70e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_845g_info = { 718e26cdf6SFrançois Tigeot .gen = 2, .num_pipes = 1, 72e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 739edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 74ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 75ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 76e3adcf8fSFrançois Tigeot }; 77e3adcf8fSFrançois Tigeot 78e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i85x_info = { 798e26cdf6SFrançois Tigeot .gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2, 80e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 81e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 829edbd4a0SFrançois Tigeot .has_fbc = 1, 839edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 84ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 85ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 86e3adcf8fSFrançois Tigeot }; 87e3adcf8fSFrançois Tigeot 88e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i865g_info = { 898e26cdf6SFrançois Tigeot .gen = 2, .num_pipes = 1, 90e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 919edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 92ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 93ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 94e3adcf8fSFrançois Tigeot }; 95e3adcf8fSFrançois Tigeot 96e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915g_info = { 978e26cdf6SFrançois Tigeot .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2, 98e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 999edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 100ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 101ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 102e3adcf8fSFrançois Tigeot }; 103e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915gm_info = { 1048e26cdf6SFrançois Tigeot .gen = 3, .is_mobile = 1, .num_pipes = 2, 105e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 106e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 107e3adcf8fSFrançois Tigeot .supports_tv = 1, 1089edbd4a0SFrançois Tigeot .has_fbc = 1, 1099edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 110ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 111ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 112e3adcf8fSFrançois Tigeot }; 113e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945g_info = { 1148e26cdf6SFrançois Tigeot .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2, 115e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 1169edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 117ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 118ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 119e3adcf8fSFrançois Tigeot }; 120e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945gm_info = { 1218e26cdf6SFrançois Tigeot .gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2, 122e3adcf8fSFrançois Tigeot .has_hotplug = 1, .cursor_needs_physical = 1, 123e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 124e3adcf8fSFrançois Tigeot .supports_tv = 1, 1259edbd4a0SFrançois Tigeot .has_fbc = 1, 1269edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 127ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 128ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 129e3adcf8fSFrançois Tigeot }; 130e3adcf8fSFrançois Tigeot 131e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965g_info = { 1328e26cdf6SFrançois Tigeot .gen = 4, .is_broadwater = 1, .num_pipes = 2, 133e3adcf8fSFrançois Tigeot .has_hotplug = 1, 134e3adcf8fSFrançois Tigeot .has_overlay = 1, 1359edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 136ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 137ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 138e3adcf8fSFrançois Tigeot }; 139e3adcf8fSFrançois Tigeot 140e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965gm_info = { 1418e26cdf6SFrançois Tigeot .gen = 4, .is_crestline = 1, .num_pipes = 2, 142e3adcf8fSFrançois Tigeot .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, 143e3adcf8fSFrançois Tigeot .has_overlay = 1, 144e3adcf8fSFrançois Tigeot .supports_tv = 1, 1459edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 146ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 147ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 148e3adcf8fSFrançois Tigeot }; 149e3adcf8fSFrançois Tigeot 150e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g33_info = { 1518e26cdf6SFrançois Tigeot .gen = 3, .is_g33 = 1, .num_pipes = 2, 152e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 153e3adcf8fSFrançois Tigeot .has_overlay = 1, 1549edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 155ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 156ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 157e3adcf8fSFrançois Tigeot }; 158e3adcf8fSFrançois Tigeot 159e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g45_info = { 1608e26cdf6SFrançois Tigeot .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2, 161e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 1629edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 163ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 164ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 165e3adcf8fSFrançois Tigeot }; 166e3adcf8fSFrançois Tigeot 167e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_gm45_info = { 1688e26cdf6SFrançois Tigeot .gen = 4, .is_g4x = 1, .num_pipes = 2, 169e3adcf8fSFrançois Tigeot .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, 170e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 171e3adcf8fSFrançois Tigeot .supports_tv = 1, 1729edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 173ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 174ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 175e3adcf8fSFrançois Tigeot }; 176e3adcf8fSFrançois Tigeot 177e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_pineview_info = { 1788e26cdf6SFrançois Tigeot .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2, 179e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 180e3adcf8fSFrançois Tigeot .has_overlay = 1, 181ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 182ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 183e3adcf8fSFrançois Tigeot }; 184e3adcf8fSFrançois Tigeot 185e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_d_info = { 1868e26cdf6SFrançois Tigeot .gen = 5, .num_pipes = 2, 187e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 1889edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 189ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 190ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 191e3adcf8fSFrançois Tigeot }; 192e3adcf8fSFrançois Tigeot 193e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_m_info = { 1948e26cdf6SFrançois Tigeot .gen = 5, .is_mobile = 1, .num_pipes = 2, 195e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 19600dca1bbSFrançois Tigeot .has_fbc = 1, 1979edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 198ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 199ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 200e3adcf8fSFrançois Tigeot }; 201e3adcf8fSFrançois Tigeot 202e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_d_info = { 2038e26cdf6SFrançois Tigeot .gen = 6, .num_pipes = 2, 204e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 2059edbd4a0SFrançois Tigeot .has_fbc = 1, 2069edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, 207e3adcf8fSFrançois Tigeot .has_llc = 1, 208ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 209ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 210e3adcf8fSFrançois Tigeot }; 211e3adcf8fSFrançois Tigeot 212e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_m_info = { 2138e26cdf6SFrançois Tigeot .gen = 6, .is_mobile = 1, .num_pipes = 2, 214e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 215e3adcf8fSFrançois Tigeot .has_fbc = 1, 2169edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, 217e3adcf8fSFrançois Tigeot .has_llc = 1, 218ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 219ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 220e3adcf8fSFrançois Tigeot }; 221e3adcf8fSFrançois Tigeot 2228e26cdf6SFrançois Tigeot #define GEN7_FEATURES \ 2238e26cdf6SFrançois Tigeot .gen = 7, .num_pipes = 3, \ 2248e26cdf6SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, \ 2259edbd4a0SFrançois Tigeot .has_fbc = 1, \ 2269edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ 2279edbd4a0SFrançois Tigeot .has_llc = 1 2288e26cdf6SFrançois Tigeot 229e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_d_info = { 2308e26cdf6SFrançois Tigeot GEN7_FEATURES, 2318e26cdf6SFrançois Tigeot .is_ivybridge = 1, 232ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 233ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 234e3adcf8fSFrançois Tigeot }; 235e3adcf8fSFrançois Tigeot 236e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_m_info = { 2378e26cdf6SFrançois Tigeot GEN7_FEATURES, 2388e26cdf6SFrançois Tigeot .is_ivybridge = 1, 2398e26cdf6SFrançois Tigeot .is_mobile = 1, 240ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 241ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 2428e26cdf6SFrançois Tigeot }; 2438e26cdf6SFrançois Tigeot 2448e26cdf6SFrançois Tigeot static const struct intel_device_info intel_ivybridge_q_info = { 2458e26cdf6SFrançois Tigeot GEN7_FEATURES, 2468e26cdf6SFrançois Tigeot .is_ivybridge = 1, 2478e26cdf6SFrançois Tigeot .num_pipes = 0, /* legal, last one wins */ 248ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 249ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 250e3adcf8fSFrançois Tigeot }; 251e3adcf8fSFrançois Tigeot 252e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_m_info = { 2538e26cdf6SFrançois Tigeot GEN7_FEATURES, 2548e26cdf6SFrançois Tigeot .is_mobile = 1, 2558e26cdf6SFrançois Tigeot .num_pipes = 2, 256e9243325SFrançois Tigeot .is_valleyview = 1, 257a2fdbec6SFrançois Tigeot .display_mmio_offset = VLV_DISPLAY_BASE, 2589edbd4a0SFrançois Tigeot .has_fbc = 0, /* legal, last one wins */ 2598e26cdf6SFrançois Tigeot .has_llc = 0, /* legal, last one wins */ 260ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 261ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 262e9243325SFrançois Tigeot }; 263e9243325SFrançois Tigeot 264e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_d_info = { 2658e26cdf6SFrançois Tigeot GEN7_FEATURES, 2668e26cdf6SFrançois Tigeot .num_pipes = 2, 267e9243325SFrançois Tigeot .is_valleyview = 1, 268a2fdbec6SFrançois Tigeot .display_mmio_offset = VLV_DISPLAY_BASE, 2699edbd4a0SFrançois Tigeot .has_fbc = 0, /* legal, last one wins */ 2708e26cdf6SFrançois Tigeot .has_llc = 0, /* legal, last one wins */ 271ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 272ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 273e9243325SFrançois Tigeot }; 274e9243325SFrançois Tigeot 275e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_d_info = { 2768e26cdf6SFrançois Tigeot GEN7_FEATURES, 2778e26cdf6SFrançois Tigeot .is_haswell = 1, 2785d0b1887SFrançois Tigeot .has_ddi = 1, 2795d0b1887SFrançois Tigeot .has_fpga_dbg = 1, 2809edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 281ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 282ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 283e9243325SFrançois Tigeot }; 284e9243325SFrançois Tigeot 285e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_m_info = { 2868e26cdf6SFrançois Tigeot GEN7_FEATURES, 2878e26cdf6SFrançois Tigeot .is_haswell = 1, 2888e26cdf6SFrançois Tigeot .is_mobile = 1, 2895d0b1887SFrançois Tigeot .has_ddi = 1, 2905d0b1887SFrançois Tigeot .has_fpga_dbg = 1, 2919edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 292ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 293ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 294e9243325SFrançois Tigeot }; 295e3adcf8fSFrançois Tigeot 2969edbd4a0SFrançois Tigeot static const struct intel_device_info intel_broadwell_d_info = { 2979edbd4a0SFrançois Tigeot .gen = 8, .num_pipes = 3, 2989edbd4a0SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 2999edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 3009edbd4a0SFrançois Tigeot .has_llc = 1, 3019edbd4a0SFrançois Tigeot .has_ddi = 1, 302*24edb884SFrançois Tigeot .has_fpga_dbg = 1, 303ba55f2f5SFrançois Tigeot .has_fbc = 1, 304ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 305ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 3069edbd4a0SFrançois Tigeot }; 3079edbd4a0SFrançois Tigeot 3089edbd4a0SFrançois Tigeot static const struct intel_device_info intel_broadwell_m_info = { 3099edbd4a0SFrançois Tigeot .gen = 8, .is_mobile = 1, .num_pipes = 3, 3109edbd4a0SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 3119edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 3129edbd4a0SFrançois Tigeot .has_llc = 1, 3139edbd4a0SFrançois Tigeot .has_ddi = 1, 314*24edb884SFrançois Tigeot .has_fpga_dbg = 1, 315ba55f2f5SFrançois Tigeot .has_fbc = 1, 316ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 317ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 318ba55f2f5SFrançois Tigeot }; 319ba55f2f5SFrançois Tigeot 320ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_broadwell_gt3d_info = { 321ba55f2f5SFrançois Tigeot .gen = 8, .num_pipes = 3, 322ba55f2f5SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 323ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 324ba55f2f5SFrançois Tigeot .has_llc = 1, 325ba55f2f5SFrançois Tigeot .has_ddi = 1, 326*24edb884SFrançois Tigeot .has_fpga_dbg = 1, 327ba55f2f5SFrançois Tigeot .has_fbc = 1, 328ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 329ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 330ba55f2f5SFrançois Tigeot }; 331ba55f2f5SFrançois Tigeot 332ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_broadwell_gt3m_info = { 333ba55f2f5SFrançois Tigeot .gen = 8, .is_mobile = 1, .num_pipes = 3, 334ba55f2f5SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 335ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 336ba55f2f5SFrançois Tigeot .has_llc = 1, 337ba55f2f5SFrançois Tigeot .has_ddi = 1, 338*24edb884SFrançois Tigeot .has_fpga_dbg = 1, 339ba55f2f5SFrançois Tigeot .has_fbc = 1, 340ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 341ba55f2f5SFrançois Tigeot IVB_CURSOR_OFFSETS, 342ba55f2f5SFrançois Tigeot }; 343ba55f2f5SFrançois Tigeot 344ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_cherryview_info = { 345ba55f2f5SFrançois Tigeot .is_preliminary = 1, 346ba55f2f5SFrançois Tigeot .gen = 8, .num_pipes = 3, 347ba55f2f5SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 348ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 349ba55f2f5SFrançois Tigeot .is_valleyview = 1, 350ba55f2f5SFrançois Tigeot .display_mmio_offset = VLV_DISPLAY_BASE, 351ba55f2f5SFrançois Tigeot GEN_CHV_PIPEOFFSETS, 352ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 3539edbd4a0SFrançois Tigeot }; 3549edbd4a0SFrançois Tigeot 3559edbd4a0SFrançois Tigeot /* 3569edbd4a0SFrançois Tigeot * Make sure any device matches here are from most specific to most 3579edbd4a0SFrançois Tigeot * general. For example, since the Quanta match is based on the subsystem 3589edbd4a0SFrançois Tigeot * and subvendor IDs, we need it to come before the more general IVB 3599edbd4a0SFrançois Tigeot * PCI ID matches, otherwise we'll use the wrong info struct above. 3609edbd4a0SFrançois Tigeot */ 3619edbd4a0SFrançois Tigeot #define INTEL_PCI_IDS \ 3629edbd4a0SFrançois Tigeot INTEL_I830_IDS(&intel_i830_info), \ 3639edbd4a0SFrançois Tigeot INTEL_I845G_IDS(&intel_845g_info), \ 3649edbd4a0SFrançois Tigeot INTEL_I85X_IDS(&intel_i85x_info), \ 3659edbd4a0SFrançois Tigeot INTEL_I865G_IDS(&intel_i865g_info), \ 3669edbd4a0SFrançois Tigeot INTEL_I915G_IDS(&intel_i915g_info), \ 3679edbd4a0SFrançois Tigeot INTEL_I915GM_IDS(&intel_i915gm_info), \ 3689edbd4a0SFrançois Tigeot INTEL_I945G_IDS(&intel_i945g_info), \ 3699edbd4a0SFrançois Tigeot INTEL_I945GM_IDS(&intel_i945gm_info), \ 3709edbd4a0SFrançois Tigeot INTEL_I965G_IDS(&intel_i965g_info), \ 3719edbd4a0SFrançois Tigeot INTEL_G33_IDS(&intel_g33_info), \ 3729edbd4a0SFrançois Tigeot INTEL_I965GM_IDS(&intel_i965gm_info), \ 3739edbd4a0SFrançois Tigeot INTEL_GM45_IDS(&intel_gm45_info), \ 3749edbd4a0SFrançois Tigeot INTEL_G45_IDS(&intel_g45_info), \ 3759edbd4a0SFrançois Tigeot INTEL_PINEVIEW_IDS(&intel_pineview_info), \ 3769edbd4a0SFrançois Tigeot INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), \ 3779edbd4a0SFrançois Tigeot INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), \ 3789edbd4a0SFrançois Tigeot INTEL_SNB_D_IDS(&intel_sandybridge_d_info), \ 3799edbd4a0SFrançois Tigeot INTEL_SNB_M_IDS(&intel_sandybridge_m_info), \ 3809edbd4a0SFrançois Tigeot INTEL_IVB_M_IDS(&intel_ivybridge_m_info), \ 3819edbd4a0SFrançois Tigeot INTEL_IVB_D_IDS(&intel_ivybridge_d_info), \ 3829edbd4a0SFrançois Tigeot INTEL_HSW_D_IDS(&intel_haswell_d_info), \ 3839edbd4a0SFrançois Tigeot INTEL_HSW_M_IDS(&intel_haswell_m_info), \ 3849edbd4a0SFrançois Tigeot INTEL_VLV_M_IDS(&intel_valleyview_m_info), \ 3859edbd4a0SFrançois Tigeot INTEL_VLV_D_IDS(&intel_valleyview_d_info), \ 386ba55f2f5SFrançois Tigeot INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), \ 387ba55f2f5SFrançois Tigeot INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), \ 388ba55f2f5SFrançois Tigeot INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), \ 389ba55f2f5SFrançois Tigeot INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), \ 390ba55f2f5SFrançois Tigeot INTEL_CHV_IDS(&intel_cherryview_info) 3919edbd4a0SFrançois Tigeot 3928e26cdf6SFrançois Tigeot static const struct pci_device_id pciidlist[] = { /* aka */ 3939edbd4a0SFrançois Tigeot INTEL_PCI_IDS, 394e3adcf8fSFrançois Tigeot {0, 0} 395e3adcf8fSFrançois Tigeot }; 396e3adcf8fSFrançois Tigeot 397e9243325SFrançois Tigeot #define PCI_VENDOR_INTEL 0x8086 398e9243325SFrançois Tigeot 399e9243325SFrançois Tigeot void intel_detect_pch(struct drm_device *dev) 400e9243325SFrançois Tigeot { 401e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 4029edbd4a0SFrançois Tigeot struct device *pch = NULL; 40327a0f882SMatthew Dillon struct pci_devinfo *di; 404e9243325SFrançois Tigeot 4058e26cdf6SFrançois Tigeot /* In all current cases, num_pipes is equivalent to the PCH_NOP setting 4068e26cdf6SFrançois Tigeot * (which really amounts to a PCH but no South Display). 4078e26cdf6SFrançois Tigeot */ 4088e26cdf6SFrançois Tigeot if (INTEL_INFO(dev)->num_pipes == 0) { 4098e26cdf6SFrançois Tigeot dev_priv->pch_type = PCH_NOP; 4108e26cdf6SFrançois Tigeot return; 4118e26cdf6SFrançois Tigeot } 4128e26cdf6SFrançois Tigeot 4139edbd4a0SFrançois Tigeot /* XXX The ISA bridge probe causes some old Core2 machines to hang */ 4149edbd4a0SFrançois Tigeot if (INTEL_INFO(dev)->gen < 5) 4159edbd4a0SFrançois Tigeot return; 4169edbd4a0SFrançois Tigeot 417e9243325SFrançois Tigeot /* 418e9243325SFrançois Tigeot * The reason to probe ISA bridge instead of Dev31:Fun0 is to 419e9243325SFrançois Tigeot * make graphics device passthrough work easy for VMM, that only 420e9243325SFrançois Tigeot * need to expose ISA bridge to let driver know the real hardware 421e9243325SFrançois Tigeot * underneath. This is a requirement from virtualization team. 4229edbd4a0SFrançois Tigeot * 4239edbd4a0SFrançois Tigeot * In some virtualized environments (e.g. XEN), there is irrelevant 4249edbd4a0SFrançois Tigeot * ISA bridge in the system. To work reliably, we should scan trhough 4259edbd4a0SFrançois Tigeot * all the ISA bridge devices and check for the first match, instead 4269edbd4a0SFrançois Tigeot * of only checking the first one. 427e9243325SFrançois Tigeot */ 42827a0f882SMatthew Dillon di = NULL; 42927a0f882SMatthew Dillon 43027a0f882SMatthew Dillon while ((pch = pci_iterate_class(&di, PCIC_BRIDGE, PCIS_BRIDGE_ISA))) { 431e9243325SFrançois Tigeot if (pci_get_vendor(pch) == PCI_VENDOR_INTEL) { 4329edbd4a0SFrançois Tigeot unsigned short id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; 433e9243325SFrançois Tigeot dev_priv->pch_id = id; 434e9243325SFrançois Tigeot 435e9243325SFrançois Tigeot if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { 436e9243325SFrançois Tigeot dev_priv->pch_type = PCH_IBX; 437e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); 438e9243325SFrançois Tigeot WARN_ON(!IS_GEN5(dev)); 439e9243325SFrançois Tigeot } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { 440e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 441e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found CougarPoint PCH\n"); 442e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 443e9243325SFrançois Tigeot } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { 444e9243325SFrançois Tigeot /* PantherPoint is CPT compatible */ 445e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 4469edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Found PantherPoint PCH\n"); 447e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 448e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { 449e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 450e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint PCH\n"); 451e9243325SFrançois Tigeot WARN_ON(!IS_HASWELL(dev)); 4528e26cdf6SFrançois Tigeot WARN_ON(IS_ULT(dev)); 4539edbd4a0SFrançois Tigeot } else if (IS_BROADWELL(dev)) { 4549edbd4a0SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 4559edbd4a0SFrançois Tigeot dev_priv->pch_id = 4569edbd4a0SFrançois Tigeot INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; 4579edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("This is Broadwell, assuming " 4589edbd4a0SFrançois Tigeot "LynxPoint LP PCH\n"); 459e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { 460e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 461e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); 462e9243325SFrançois Tigeot WARN_ON(!IS_HASWELL(dev)); 4638e26cdf6SFrançois Tigeot WARN_ON(!IS_ULT(dev)); 4649edbd4a0SFrançois Tigeot } else 4659edbd4a0SFrançois Tigeot continue; 4669edbd4a0SFrançois Tigeot 4679edbd4a0SFrançois Tigeot break; 468e9243325SFrançois Tigeot } 469e9243325SFrançois Tigeot } 4709edbd4a0SFrançois Tigeot if (!pch) 4719edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("No PCH found.\n"); 4729edbd4a0SFrançois Tigeot 473e9243325SFrançois Tigeot #if 0 474e9243325SFrançois Tigeot pci_dev_put(pch); 475e9243325SFrançois Tigeot #endif 476e9243325SFrançois Tigeot } 477e9243325SFrançois Tigeot 4783d4007e0SFrançois Tigeot bool i915_semaphore_is_enabled(struct drm_device *dev) 4793d4007e0SFrançois Tigeot { 4803d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen < 6) 4819edbd4a0SFrançois Tigeot return false; 4829edbd4a0SFrançois Tigeot 483ba55f2f5SFrançois Tigeot if (i915.semaphores >= 0) 484ba55f2f5SFrançois Tigeot return i915.semaphores; 4853d4007e0SFrançois Tigeot 486ba55f2f5SFrançois Tigeot /* Until we get further testing... */ 487ba55f2f5SFrançois Tigeot if (IS_GEN8(dev)) 488ba55f2f5SFrançois Tigeot return false; 4893d4007e0SFrançois Tigeot 4903d4007e0SFrançois Tigeot #ifdef CONFIG_INTEL_IOMMU 4913d4007e0SFrançois Tigeot /* Enable semaphores on SNB when IO remapping is off */ 4923d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) 4933d4007e0SFrançois Tigeot return false; 4943d4007e0SFrançois Tigeot #endif 4953d4007e0SFrançois Tigeot 4969edbd4a0SFrançois Tigeot return true; 4973d4007e0SFrançois Tigeot } 4983d4007e0SFrançois Tigeot 499*24edb884SFrançois Tigeot void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) 500*24edb884SFrançois Tigeot { 501*24edb884SFrançois Tigeot lockmgr(&dev_priv->irq_lock, LK_EXCLUSIVE); 502*24edb884SFrançois Tigeot 503*24edb884SFrançois Tigeot dev_priv->long_hpd_port_mask = 0; 504*24edb884SFrançois Tigeot dev_priv->short_hpd_port_mask = 0; 505*24edb884SFrançois Tigeot dev_priv->hpd_event_bits = 0; 506*24edb884SFrançois Tigeot 507*24edb884SFrançois Tigeot lockmgr(&dev_priv->irq_lock, LK_RELEASE); 508*24edb884SFrançois Tigeot 509*24edb884SFrançois Tigeot cancel_work_sync(&dev_priv->dig_port_work); 510*24edb884SFrançois Tigeot cancel_work_sync(&dev_priv->hotplug_work); 511*24edb884SFrançois Tigeot cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); 512*24edb884SFrançois Tigeot } 513*24edb884SFrançois Tigeot 514*24edb884SFrançois Tigeot static void intel_suspend_encoders(struct drm_i915_private *dev_priv) 515*24edb884SFrançois Tigeot { 516*24edb884SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 517*24edb884SFrançois Tigeot struct drm_encoder *encoder; 518*24edb884SFrançois Tigeot 519*24edb884SFrançois Tigeot drm_modeset_lock_all(dev); 520*24edb884SFrançois Tigeot list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 521*24edb884SFrançois Tigeot struct intel_encoder *intel_encoder = to_intel_encoder(encoder); 522*24edb884SFrançois Tigeot 523*24edb884SFrançois Tigeot if (intel_encoder->suspend) 524*24edb884SFrançois Tigeot intel_encoder->suspend(intel_encoder); 525*24edb884SFrançois Tigeot } 526*24edb884SFrançois Tigeot drm_modeset_unlock_all(dev); 527*24edb884SFrançois Tigeot } 528*24edb884SFrançois Tigeot 529e3adcf8fSFrançois Tigeot static int i915_drm_freeze(struct drm_device *dev) 530e3adcf8fSFrançois Tigeot { 531e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 5328e26cdf6SFrançois Tigeot struct drm_crtc *crtc; 533*24edb884SFrançois Tigeot pci_power_t opregion_target_state; 5349edbd4a0SFrançois Tigeot 535a2fdbec6SFrançois Tigeot /* ignore lid events during suspend */ 536a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock); 537a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_SUSPENDED; 538a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock); 539a2fdbec6SFrançois Tigeot 5409edbd4a0SFrançois Tigeot /* We do a lot of poking in a lot of registers, make sure they work 5419edbd4a0SFrançois Tigeot * properly. */ 542ba55f2f5SFrançois Tigeot intel_display_set_init_power(dev_priv, true); 543a2fdbec6SFrançois Tigeot 544e3adcf8fSFrançois Tigeot drm_kms_helper_poll_disable(dev); 545e3adcf8fSFrançois Tigeot 546e3adcf8fSFrançois Tigeot #if 0 547e3adcf8fSFrançois Tigeot pci_save_state(dev->pdev); 548e3adcf8fSFrançois Tigeot #endif 549e3adcf8fSFrançois Tigeot 550e3adcf8fSFrançois Tigeot /* If KMS is active, we do the leavevt stuff here */ 551e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) { 5529edbd4a0SFrançois Tigeot int error; 5539edbd4a0SFrançois Tigeot 5549edbd4a0SFrançois Tigeot error = i915_gem_suspend(dev); 555e3adcf8fSFrançois Tigeot if (error) { 556a2fdbec6SFrançois Tigeot dev_err(dev->pdev->dev, 557a2fdbec6SFrançois Tigeot "GEM idle failed, resume might fail\n"); 558e9243325SFrançois Tigeot return error; 559e3adcf8fSFrançois Tigeot } 560a2fdbec6SFrançois Tigeot 5618e26cdf6SFrançois Tigeot /* 5628e26cdf6SFrançois Tigeot * Disable CRTCs directly since we want to preserve sw state 563*24edb884SFrançois Tigeot * for _thaw. Also, power gate the CRTC power wells. 5648e26cdf6SFrançois Tigeot */ 565ba55f2f5SFrançois Tigeot drm_modeset_lock_all(dev); 566*24edb884SFrançois Tigeot for_each_crtc(dev, crtc) 567*24edb884SFrançois Tigeot intel_crtc_control(crtc, false); 568ba55f2f5SFrançois Tigeot drm_modeset_unlock_all(dev); 5695d0b1887SFrançois Tigeot 570*24edb884SFrançois Tigeot #if 0 571*24edb884SFrançois Tigeot intel_dp_mst_suspend(dev); 572*24edb884SFrançois Tigeot 573*24edb884SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 574*24edb884SFrançois Tigeot #endif 575*24edb884SFrançois Tigeot 576*24edb884SFrançois Tigeot intel_runtime_pm_disable_interrupts(dev); 577*24edb884SFrançois Tigeot intel_hpd_cancel_work(dev_priv); 578*24edb884SFrançois Tigeot 579*24edb884SFrançois Tigeot intel_suspend_encoders(dev_priv); 580*24edb884SFrançois Tigeot 581*24edb884SFrançois Tigeot intel_suspend_gt_powersave(dev); 582*24edb884SFrançois Tigeot 5835d0b1887SFrançois Tigeot intel_modeset_suspend_hw(dev); 584e3adcf8fSFrançois Tigeot } 585e3adcf8fSFrançois Tigeot 5869edbd4a0SFrançois Tigeot i915_gem_suspend_gtt_mappings(dev); 5879edbd4a0SFrançois Tigeot 588e3adcf8fSFrançois Tigeot i915_save_state(dev); 589e3adcf8fSFrançois Tigeot 590*24edb884SFrançois Tigeot opregion_target_state = PCI_D3cold; 591*24edb884SFrançois Tigeot #if IS_ENABLED(CONFIG_ACPI_SLEEP) 592*24edb884SFrançois Tigeot if (acpi_target_system_state() < ACPI_STATE_S3) 593*24edb884SFrançois Tigeot opregion_target_state = PCI_D1; 594*24edb884SFrançois Tigeot #endif 595*24edb884SFrançois Tigeot intel_opregion_notify_adapter(dev, opregion_target_state); 596*24edb884SFrançois Tigeot 597*24edb884SFrançois Tigeot #if 0 598*24edb884SFrançois Tigeot intel_uncore_forcewake_reset(dev, false); 599*24edb884SFrançois Tigeot #endif 600e3adcf8fSFrançois Tigeot intel_opregion_fini(dev); 601e3adcf8fSFrançois Tigeot 6025d0b1887SFrançois Tigeot #if 0 6035d0b1887SFrançois Tigeot console_lock(); 6045d0b1887SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); 6055d0b1887SFrançois Tigeot console_unlock(); 6065d0b1887SFrançois Tigeot #endif 6075d0b1887SFrançois Tigeot 608ba55f2f5SFrançois Tigeot dev_priv->suspend_count++; 609ba55f2f5SFrançois Tigeot 610*24edb884SFrançois Tigeot intel_display_set_init_power(dev_priv, false); 611*24edb884SFrançois Tigeot 612e3adcf8fSFrançois Tigeot return 0; 613e3adcf8fSFrançois Tigeot } 614e3adcf8fSFrançois Tigeot 6159edbd4a0SFrançois Tigeot int i915_suspend(device_t kdev) 616e3adcf8fSFrançois Tigeot { 6179edbd4a0SFrançois Tigeot struct drm_device *dev = device_get_softc(kdev); 618e3adcf8fSFrançois Tigeot int error; 619e3adcf8fSFrançois Tigeot 6209edbd4a0SFrançois Tigeot if (!dev || !dev->dev_private) { 6219edbd4a0SFrançois Tigeot DRM_ERROR("dev: %p\n", dev); 622c4a9e910SFrançois Tigeot DRM_ERROR("DRM not initialized, aborting suspend.\n"); 623c4a9e910SFrançois Tigeot return -ENODEV; 624c4a9e910SFrançois Tigeot } 625c4a9e910SFrançois Tigeot 6269edbd4a0SFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 6279edbd4a0SFrançois Tigeot return 0; 6289edbd4a0SFrançois Tigeot 629e3adcf8fSFrançois Tigeot error = i915_drm_freeze(dev); 630e3adcf8fSFrançois Tigeot if (error) 6319edbd4a0SFrançois Tigeot return error; 6329edbd4a0SFrançois Tigeot 6339edbd4a0SFrançois Tigeot #if 0 6349edbd4a0SFrançois Tigeot if (state.event == PM_EVENT_SUSPEND) { 6359edbd4a0SFrançois Tigeot /* Shut down the device */ 6369edbd4a0SFrançois Tigeot pci_disable_device(dev->pdev); 6379edbd4a0SFrançois Tigeot pci_set_power_state(dev->pdev, PCI_D3hot); 6389edbd4a0SFrançois Tigeot } 6399edbd4a0SFrançois Tigeot #endif 640c4a9e910SFrançois Tigeot 641e3adcf8fSFrançois Tigeot error = bus_generic_suspend(kdev); 642e3adcf8fSFrançois Tigeot return (error); 643c4a9e910SFrançois Tigeot } 644c4a9e910SFrançois Tigeot 6455d0b1887SFrançois Tigeot #if 0 6465d0b1887SFrançois Tigeot void intel_console_resume(struct work_struct *work) 6475d0b1887SFrançois Tigeot { 6485d0b1887SFrançois Tigeot struct drm_i915_private *dev_priv = 6495d0b1887SFrançois Tigeot container_of(work, struct drm_i915_private, 6505d0b1887SFrançois Tigeot console_resume_work); 6515d0b1887SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 6525d0b1887SFrançois Tigeot 6535d0b1887SFrançois Tigeot console_lock(); 6545d0b1887SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); 6555d0b1887SFrançois Tigeot console_unlock(); 6565d0b1887SFrançois Tigeot } 657*24edb884SFrançois Tigeot 658*24edb884SFrançois Tigeot static int i915_drm_thaw_early(struct drm_device *dev) 659*24edb884SFrançois Tigeot { 660*24edb884SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 661*24edb884SFrançois Tigeot 662*24edb884SFrançois Tigeot if (IS_HASWELL(dev) || IS_BROADWELL(dev)) 663*24edb884SFrançois Tigeot hsw_disable_pc8(dev_priv); 664*24edb884SFrançois Tigeot 665*24edb884SFrançois Tigeot intel_uncore_early_sanitize(dev, true); 666*24edb884SFrançois Tigeot intel_uncore_sanitize(dev); 667*24edb884SFrançois Tigeot intel_power_domains_init_hw(dev_priv); 668*24edb884SFrançois Tigeot 669*24edb884SFrançois Tigeot return 0; 670*24edb884SFrançois Tigeot } 6715d0b1887SFrançois Tigeot #endif 6725d0b1887SFrançois Tigeot 6739edbd4a0SFrançois Tigeot static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) 674c4a9e910SFrançois Tigeot { 675e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 6769edbd4a0SFrançois Tigeot 6779edbd4a0SFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET) && 6789edbd4a0SFrançois Tigeot restore_gtt_mappings) { 6799edbd4a0SFrançois Tigeot mutex_lock(&dev->struct_mutex); 6809edbd4a0SFrançois Tigeot i915_gem_restore_gtt_mappings(dev); 6819edbd4a0SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 6829edbd4a0SFrançois Tigeot } 6839edbd4a0SFrançois Tigeot 684ba55f2f5SFrançois Tigeot intel_power_domains_init_hw(dev_priv); 6859edbd4a0SFrançois Tigeot 686c4a9e910SFrançois Tigeot i915_restore_state(dev); 687e3adcf8fSFrançois Tigeot intel_opregion_setup(dev); 688c4a9e910SFrançois Tigeot 689e3adcf8fSFrançois Tigeot /* KMS EnterVT equivalent */ 690e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) { 69119df918dSFrançois Tigeot intel_init_pch_refclk(dev); 692ba55f2f5SFrançois Tigeot drm_mode_config_reset(dev); 69319df918dSFrançois Tigeot 694a2fdbec6SFrançois Tigeot mutex_lock(&dev->struct_mutex); 695ba55f2f5SFrançois Tigeot if (i915_gem_init_hw(dev)) { 696ba55f2f5SFrançois Tigeot DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); 697ba55f2f5SFrançois Tigeot atomic_set_mask(I915_WEDGED, &dev_priv->gpu_error.reset_counter); 698ba55f2f5SFrançois Tigeot } 699a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 700a2fdbec6SFrançois Tigeot 701*24edb884SFrançois Tigeot intel_runtime_pm_restore_interrupts(dev); 70219df918dSFrançois Tigeot 70319df918dSFrançois Tigeot intel_modeset_init_hw(dev); 7048e26cdf6SFrançois Tigeot 7058e26cdf6SFrançois Tigeot drm_modeset_lock_all(dev); 7068e26cdf6SFrançois Tigeot intel_modeset_setup_hw_state(dev, true); 7078e26cdf6SFrançois Tigeot drm_modeset_unlock_all(dev); 708a2fdbec6SFrançois Tigeot 709a2fdbec6SFrançois Tigeot /* 710a2fdbec6SFrançois Tigeot * ... but also need to make sure that hotplug processing 711a2fdbec6SFrançois Tigeot * doesn't cause havoc. Like in the driver load code we don't 712a2fdbec6SFrançois Tigeot * bother with the tiny race here where we might loose hotplug 713a2fdbec6SFrançois Tigeot * notifications. 714a2fdbec6SFrançois Tigeot * */ 715a2fdbec6SFrançois Tigeot intel_hpd_init(dev); 7168e26cdf6SFrançois Tigeot /* Config may have changed between suspend and resume */ 717ba55f2f5SFrançois Tigeot drm_helper_hpd_irq_event(dev); 718c4a9e910SFrançois Tigeot } 719c4a9e910SFrançois Tigeot 720e3adcf8fSFrançois Tigeot intel_opregion_init(dev); 721e3adcf8fSFrançois Tigeot 722a2fdbec6SFrançois Tigeot /* 723a2fdbec6SFrançois Tigeot * The console lock can be pretty contented on resume due 724a2fdbec6SFrançois Tigeot * to all the printk activity. Try to keep it out of the hot 725a2fdbec6SFrançois Tigeot * path of resume if possible. 726a2fdbec6SFrançois Tigeot */ 72719df918dSFrançois Tigeot #if 0 728a2fdbec6SFrançois Tigeot if (console_trylock()) { 7295d0b1887SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); 73019df918dSFrançois Tigeot console_unlock(); 731a2fdbec6SFrançois Tigeot } else { 732a2fdbec6SFrançois Tigeot schedule_work(&dev_priv->console_resume_work); 733a2fdbec6SFrançois Tigeot } 73419df918dSFrançois Tigeot #endif 735a2fdbec6SFrançois Tigeot 736a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock); 737a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_DONE; 738a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock); 7399edbd4a0SFrançois Tigeot 740*24edb884SFrançois Tigeot #if 0 741*24edb884SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D0); 742*24edb884SFrançois Tigeot #endif 743*24edb884SFrançois Tigeot 744ba55f2f5SFrançois Tigeot return 0; 745a2fdbec6SFrançois Tigeot } 746a2fdbec6SFrançois Tigeot 7479edbd4a0SFrançois Tigeot #if 0 748a2fdbec6SFrançois Tigeot static int i915_drm_thaw(struct drm_device *dev) 749a2fdbec6SFrançois Tigeot { 7509edbd4a0SFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET)) 7519edbd4a0SFrançois Tigeot i915_check_and_clear_faults(dev); 752a2fdbec6SFrançois Tigeot 7539edbd4a0SFrançois Tigeot return __i915_drm_thaw(dev, true); 754a2fdbec6SFrançois Tigeot } 7559edbd4a0SFrançois Tigeot #endif 756a2fdbec6SFrançois Tigeot 7579edbd4a0SFrançois Tigeot int i915_resume(struct drm_device *dev) 758c4a9e910SFrançois Tigeot { 7595d0b1887SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 760e3adcf8fSFrançois Tigeot int ret; 761c4a9e910SFrançois Tigeot 7625d0b1887SFrançois Tigeot /* 7635d0b1887SFrançois Tigeot * Platforms with opregion should have sane BIOS, older ones (gen3 and 7649edbd4a0SFrançois Tigeot * earlier) need to restore the GTT mappings since the BIOS might clear 7659edbd4a0SFrançois Tigeot * all our scratch PTEs. 7665d0b1887SFrançois Tigeot */ 7679edbd4a0SFrançois Tigeot ret = __i915_drm_thaw(dev, !dev_priv->opregion.header); 7685d0b1887SFrançois Tigeot if (ret) 7695d0b1887SFrançois Tigeot return ret; 770e3adcf8fSFrançois Tigeot 771e3adcf8fSFrançois Tigeot drm_kms_helper_poll_enable(dev); 7725d0b1887SFrançois Tigeot return 0; 773c4a9e910SFrançois Tigeot } 774c4a9e910SFrançois Tigeot 77562e5f8e8SFrançois Tigeot /* XXX Hack for the old *BSD drm code base 77662e5f8e8SFrançois Tigeot * The device id field is set at probe time */ 77762e5f8e8SFrançois Tigeot static drm_pci_id_list_t i915_attach_list[] = { 77862e5f8e8SFrançois Tigeot {0x8086, 0, 0, "Intel i915 GPU"}, 77962e5f8e8SFrançois Tigeot {0, 0, 0, NULL} 78062e5f8e8SFrançois Tigeot }; 78162e5f8e8SFrançois Tigeot 782ba55f2f5SFrançois Tigeot struct intel_device_info * 783e3adcf8fSFrançois Tigeot i915_get_device_id(int device) 784c4a9e910SFrançois Tigeot { 7858e26cdf6SFrançois Tigeot const struct pci_device_id *did; 786c4a9e910SFrançois Tigeot 787e3adcf8fSFrançois Tigeot for (did = &pciidlist[0]; did->device != 0; did++) { 788e3adcf8fSFrançois Tigeot if (did->device != device) 789e3adcf8fSFrançois Tigeot continue; 7908e26cdf6SFrançois Tigeot return (struct intel_device_info *)did->driver_data; 791e3adcf8fSFrançois Tigeot } 792e3adcf8fSFrançois Tigeot return (NULL); 793c4a9e910SFrançois Tigeot } 794c4a9e910SFrançois Tigeot 795c4a9e910SFrançois Tigeot extern devclass_t drm_devclass; 796e3adcf8fSFrançois Tigeot 797e9243325SFrançois Tigeot /** 798e9243325SFrançois Tigeot * i915_reset - reset chip after a hang 799e9243325SFrançois Tigeot * @dev: drm device to reset 800e9243325SFrançois Tigeot * 801e9243325SFrançois Tigeot * Reset the chip. Useful if a hang is detected. Returns zero on successful 802e9243325SFrançois Tigeot * reset or otherwise an error code. 803e9243325SFrançois Tigeot * 804e9243325SFrançois Tigeot * Procedure is fairly simple: 805e9243325SFrançois Tigeot * - reset the chip using the reset reg 806e9243325SFrançois Tigeot * - re-init context state 807e9243325SFrançois Tigeot * - re-init hardware status page 808e9243325SFrançois Tigeot * - re-init ring buffer 809e9243325SFrançois Tigeot * - re-init interrupt state 810e9243325SFrançois Tigeot * - re-init display 811e9243325SFrançois Tigeot */ 81200640ec9SFrançois Tigeot int i915_reset(struct drm_device *dev) 813e3adcf8fSFrançois Tigeot { 814ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 8155d0b1887SFrançois Tigeot bool simulated; 816e9243325SFrançois Tigeot int ret; 817e9243325SFrançois Tigeot 818ba55f2f5SFrançois Tigeot if (!i915.reset) 819e9243325SFrançois Tigeot return 0; 820e9243325SFrançois Tigeot 821a2fdbec6SFrançois Tigeot mutex_lock(&dev->struct_mutex); 822e3adcf8fSFrançois Tigeot 823e3adcf8fSFrançois Tigeot i915_gem_reset(dev); 824e3adcf8fSFrançois Tigeot 8255d0b1887SFrançois Tigeot simulated = dev_priv->gpu_error.stop_rings != 0; 8265d0b1887SFrançois Tigeot 82700640ec9SFrançois Tigeot ret = intel_gpu_reset(dev); 82800640ec9SFrançois Tigeot 8295d0b1887SFrançois Tigeot /* Also reset the gpu hangman. */ 8305d0b1887SFrançois Tigeot if (simulated) { 8315d0b1887SFrançois Tigeot DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); 8325d0b1887SFrançois Tigeot dev_priv->gpu_error.stop_rings = 0; 8335d0b1887SFrançois Tigeot if (ret == -ENODEV) { 8349edbd4a0SFrançois Tigeot DRM_INFO("Reset not implemented, but ignoring " 8355d0b1887SFrançois Tigeot "error for simulated gpu hangs\n"); 8365d0b1887SFrançois Tigeot ret = 0; 8375d0b1887SFrançois Tigeot } 8385d0b1887SFrançois Tigeot } 8399edbd4a0SFrançois Tigeot 840e3adcf8fSFrançois Tigeot if (ret) { 8419edbd4a0SFrançois Tigeot DRM_ERROR("Failed to reset chip: %i\n", ret); 842a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 84300640ec9SFrançois Tigeot return ret; 844e3adcf8fSFrançois Tigeot } 845e3adcf8fSFrançois Tigeot 846e9243325SFrançois Tigeot /* Ok, now get things going again... */ 847e9243325SFrançois Tigeot 848e9243325SFrançois Tigeot /* 849e9243325SFrançois Tigeot * Everything depends on having the GTT running, so we need to start 850e9243325SFrançois Tigeot * there. Fortunately we don't need to do this unless we reset the 851e9243325SFrançois Tigeot * chip at a PCI level. 852e9243325SFrançois Tigeot * 853e9243325SFrançois Tigeot * Next we need to restore the context, but we don't use those 854e9243325SFrançois Tigeot * yet either... 855e9243325SFrançois Tigeot * 856e9243325SFrançois Tigeot * Ring buffer needs to be re-initialized in the KMS case, or if X 857e9243325SFrançois Tigeot * was running at the time of the reset (i.e. we weren't VT 858e9243325SFrançois Tigeot * switched away). 859e9243325SFrançois Tigeot */ 860e3adcf8fSFrançois Tigeot if (drm_core_check_feature(dev, DRIVER_MODESET) || 8619edbd4a0SFrançois Tigeot !dev_priv->ums.mm_suspended) { 8629edbd4a0SFrançois Tigeot dev_priv->ums.mm_suspended = 0; 86300640ec9SFrançois Tigeot 8649edbd4a0SFrançois Tigeot ret = i915_gem_init_hw(dev); 865a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 8669edbd4a0SFrançois Tigeot if (ret) { 8679edbd4a0SFrançois Tigeot DRM_ERROR("Failed hw init on reset %d\n", ret); 8689edbd4a0SFrançois Tigeot return ret; 8699edbd4a0SFrançois Tigeot } 870e3adcf8fSFrançois Tigeot 871ba55f2f5SFrançois Tigeot /* 872ba55f2f5SFrançois Tigeot * FIXME: This races pretty badly against concurrent holders of 873ba55f2f5SFrançois Tigeot * ring interrupts. This is possible since we've started to drop 874ba55f2f5SFrançois Tigeot * dev->struct_mutex in select places when waiting for the gpu. 875ba55f2f5SFrançois Tigeot */ 876ba55f2f5SFrançois Tigeot 877ba55f2f5SFrançois Tigeot /* 878ba55f2f5SFrançois Tigeot * rps/rc6 re-init is necessary to restore state lost after the 879ba55f2f5SFrançois Tigeot * reset and the re-install of gt irqs. Skip for ironlake per 880ba55f2f5SFrançois Tigeot * previous concerns that it doesn't respond well to some forms 881ba55f2f5SFrançois Tigeot * of re-init after reset. 882ba55f2f5SFrançois Tigeot */ 883ba55f2f5SFrançois Tigeot if (INTEL_INFO(dev)->gen > 5) 884ba55f2f5SFrançois Tigeot intel_reset_gt_powersave(dev); 885ba55f2f5SFrançois Tigeot 886a2fdbec6SFrançois Tigeot intel_hpd_init(dev); 88700640ec9SFrançois Tigeot } else { 888a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 889e3adcf8fSFrançois Tigeot } 890e3adcf8fSFrançois Tigeot 891e9243325SFrançois Tigeot return 0; 892e9243325SFrançois Tigeot } 893e9243325SFrançois Tigeot 894ba55f2f5SFrançois Tigeot static int i915_pci_probe(device_t kdev) 895a2fdbec6SFrançois Tigeot { 896a2fdbec6SFrançois Tigeot int device, i = 0; 897a2fdbec6SFrançois Tigeot 898a2fdbec6SFrançois Tigeot if (pci_get_class(kdev) != PCIC_DISPLAY) 899a2fdbec6SFrançois Tigeot return ENXIO; 900a2fdbec6SFrançois Tigeot 901a2fdbec6SFrançois Tigeot if (pci_get_vendor(kdev) != PCI_VENDOR_INTEL) 902a2fdbec6SFrançois Tigeot return ENXIO; 903a2fdbec6SFrançois Tigeot 904a2fdbec6SFrançois Tigeot device = pci_get_device(kdev); 905a2fdbec6SFrançois Tigeot 906a2fdbec6SFrançois Tigeot for (i = 0; pciidlist[i].device != 0; i++) { 907a2fdbec6SFrançois Tigeot if (pciidlist[i].device == device) { 908a2fdbec6SFrançois Tigeot i915_attach_list[0].device = device; 909a2fdbec6SFrançois Tigeot return 0; 910a2fdbec6SFrançois Tigeot } 911a2fdbec6SFrançois Tigeot } 912a2fdbec6SFrançois Tigeot 913a2fdbec6SFrançois Tigeot return ENXIO; 914a2fdbec6SFrançois Tigeot } 915a2fdbec6SFrançois Tigeot 9169edbd4a0SFrançois Tigeot #if 0 9179edbd4a0SFrançois Tigeot static void 9189edbd4a0SFrançois Tigeot i915_pci_remove(struct pci_dev *pdev) 9199edbd4a0SFrançois Tigeot { 9209edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 9219edbd4a0SFrançois Tigeot 9229edbd4a0SFrançois Tigeot drm_put_dev(dev); 9239edbd4a0SFrançois Tigeot } 9249edbd4a0SFrançois Tigeot 9259edbd4a0SFrançois Tigeot static int i915_pm_suspend(struct device *dev) 9269edbd4a0SFrançois Tigeot { 9279edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 9289edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 9299edbd4a0SFrançois Tigeot 9309edbd4a0SFrançois Tigeot if (!drm_dev || !drm_dev->dev_private) { 9319edbd4a0SFrançois Tigeot dev_err(dev, "DRM not initialized, aborting suspend.\n"); 9329edbd4a0SFrançois Tigeot return -ENODEV; 9339edbd4a0SFrançois Tigeot } 9349edbd4a0SFrançois Tigeot 9359edbd4a0SFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 9369edbd4a0SFrançois Tigeot return 0; 9379edbd4a0SFrançois Tigeot 938ba55f2f5SFrançois Tigeot return i915_drm_freeze(drm_dev); 9399edbd4a0SFrançois Tigeot } 9409edbd4a0SFrançois Tigeot 941*24edb884SFrançois Tigeot static int i915_pm_suspend_late(struct device *dev) 942*24edb884SFrançois Tigeot { 943*24edb884SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 944*24edb884SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 945*24edb884SFrançois Tigeot struct drm_i915_private *dev_priv = drm_dev->dev_private; 946*24edb884SFrançois Tigeot 947*24edb884SFrançois Tigeot /* 948*24edb884SFrançois Tigeot * We have a suspedn ordering issue with the snd-hda driver also 949*24edb884SFrançois Tigeot * requiring our device to be power up. Due to the lack of a 950*24edb884SFrançois Tigeot * parent/child relationship we currently solve this with an late 951*24edb884SFrançois Tigeot * suspend hook. 952*24edb884SFrançois Tigeot * 953*24edb884SFrançois Tigeot * FIXME: This should be solved with a special hdmi sink device or 954*24edb884SFrançois Tigeot * similar so that power domains can be employed. 955*24edb884SFrançois Tigeot */ 956*24edb884SFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 957*24edb884SFrançois Tigeot return 0; 958*24edb884SFrançois Tigeot 959*24edb884SFrançois Tigeot if (IS_HASWELL(drm_dev) || IS_BROADWELL(drm_dev)) 960*24edb884SFrançois Tigeot hsw_enable_pc8(dev_priv); 961*24edb884SFrançois Tigeot 962*24edb884SFrançois Tigeot pci_disable_device(pdev); 963*24edb884SFrançois Tigeot pci_set_power_state(pdev, PCI_D3hot); 964*24edb884SFrançois Tigeot 965*24edb884SFrançois Tigeot return 0; 966*24edb884SFrançois Tigeot } 967*24edb884SFrançois Tigeot 9689edbd4a0SFrançois Tigeot static int i915_pm_resume(struct device *dev) 9699edbd4a0SFrançois Tigeot { 9709edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 9719edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 9729edbd4a0SFrançois Tigeot 9739edbd4a0SFrançois Tigeot return i915_resume(drm_dev); 9749edbd4a0SFrançois Tigeot } 9759edbd4a0SFrançois Tigeot 9769edbd4a0SFrançois Tigeot static int i915_pm_freeze(struct device *dev) 9779edbd4a0SFrançois Tigeot { 9789edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 9799edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 980*24edb884SFrançois Tigeot struct drm_i915_private *dev_priv = drm_dev->dev_private; 9819edbd4a0SFrançois Tigeot 9829edbd4a0SFrançois Tigeot if (!drm_dev || !drm_dev->dev_private) { 9839edbd4a0SFrançois Tigeot dev_err(dev, "DRM not initialized, aborting suspend.\n"); 9849edbd4a0SFrançois Tigeot return -ENODEV; 9859edbd4a0SFrançois Tigeot } 9869edbd4a0SFrançois Tigeot 9879edbd4a0SFrançois Tigeot return i915_drm_freeze(drm_dev); 9889edbd4a0SFrançois Tigeot } 9899edbd4a0SFrançois Tigeot 9909edbd4a0SFrançois Tigeot static int i915_pm_thaw(struct device *dev) 9919edbd4a0SFrançois Tigeot { 9929edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 9939edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 9949edbd4a0SFrançois Tigeot 9959edbd4a0SFrançois Tigeot return i915_drm_thaw(drm_dev); 9969edbd4a0SFrançois Tigeot } 9979edbd4a0SFrançois Tigeot 9989edbd4a0SFrançois Tigeot static int i915_pm_poweroff(struct device *dev) 9999edbd4a0SFrançois Tigeot { 10009edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 10019edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 10029edbd4a0SFrançois Tigeot 10039edbd4a0SFrançois Tigeot return i915_drm_freeze(drm_dev); 10049edbd4a0SFrançois Tigeot } 10059edbd4a0SFrançois Tigeot 1006ba55f2f5SFrançois Tigeot static int hsw_runtime_suspend(struct drm_i915_private *dev_priv) 1007ba55f2f5SFrançois Tigeot { 1008ba55f2f5SFrançois Tigeot hsw_enable_pc8(dev_priv); 1009ba55f2f5SFrançois Tigeot 1010ba55f2f5SFrançois Tigeot return 0; 1011ba55f2f5SFrançois Tigeot } 1012ba55f2f5SFrançois Tigeot 1013ba55f2f5SFrançois Tigeot static int snb_runtime_resume(struct drm_i915_private *dev_priv) 1014ba55f2f5SFrançois Tigeot { 1015ba55f2f5SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 1016ba55f2f5SFrançois Tigeot 1017ba55f2f5SFrançois Tigeot intel_init_pch_refclk(dev); 1018ba55f2f5SFrançois Tigeot 1019ba55f2f5SFrançois Tigeot return 0; 1020ba55f2f5SFrançois Tigeot } 1021ba55f2f5SFrançois Tigeot 1022ba55f2f5SFrançois Tigeot static int hsw_runtime_resume(struct drm_i915_private *dev_priv) 1023ba55f2f5SFrançois Tigeot { 1024ba55f2f5SFrançois Tigeot hsw_disable_pc8(dev_priv); 1025ba55f2f5SFrançois Tigeot 1026ba55f2f5SFrançois Tigeot return 0; 1027ba55f2f5SFrançois Tigeot } 1028ba55f2f5SFrançois Tigeot 1029ba55f2f5SFrançois Tigeot /* 1030ba55f2f5SFrançois Tigeot * Save all Gunit registers that may be lost after a D3 and a subsequent 1031ba55f2f5SFrançois Tigeot * S0i[R123] transition. The list of registers needing a save/restore is 1032ba55f2f5SFrançois Tigeot * defined in the VLV2_S0IXRegs document. This documents marks all Gunit 1033ba55f2f5SFrançois Tigeot * registers in the following way: 1034ba55f2f5SFrançois Tigeot * - Driver: saved/restored by the driver 1035ba55f2f5SFrançois Tigeot * - Punit : saved/restored by the Punit firmware 1036ba55f2f5SFrançois Tigeot * - No, w/o marking: no need to save/restore, since the register is R/O or 1037ba55f2f5SFrançois Tigeot * used internally by the HW in a way that doesn't depend 1038ba55f2f5SFrançois Tigeot * keeping the content across a suspend/resume. 1039ba55f2f5SFrançois Tigeot * - Debug : used for debugging 1040ba55f2f5SFrançois Tigeot * 1041ba55f2f5SFrançois Tigeot * We save/restore all registers marked with 'Driver', with the following 1042ba55f2f5SFrançois Tigeot * exceptions: 1043ba55f2f5SFrançois Tigeot * - Registers out of use, including also registers marked with 'Debug'. 1044ba55f2f5SFrançois Tigeot * These have no effect on the driver's operation, so we don't save/restore 1045ba55f2f5SFrançois Tigeot * them to reduce the overhead. 1046ba55f2f5SFrançois Tigeot * - Registers that are fully setup by an initialization function called from 1047ba55f2f5SFrançois Tigeot * the resume path. For example many clock gating and RPS/RC6 registers. 1048ba55f2f5SFrançois Tigeot * - Registers that provide the right functionality with their reset defaults. 1049ba55f2f5SFrançois Tigeot * 1050ba55f2f5SFrançois Tigeot * TODO: Except for registers that based on the above 3 criteria can be safely 1051ba55f2f5SFrançois Tigeot * ignored, we save/restore all others, practically treating the HW context as 1052ba55f2f5SFrançois Tigeot * a black-box for the driver. Further investigation is needed to reduce the 1053ba55f2f5SFrançois Tigeot * saved/restored registers even further, by following the same 3 criteria. 1054ba55f2f5SFrançois Tigeot */ 1055ba55f2f5SFrançois Tigeot static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv) 1056ba55f2f5SFrançois Tigeot { 1057ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state; 1058ba55f2f5SFrançois Tigeot int i; 1059ba55f2f5SFrançois Tigeot 1060ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */ 1061ba55f2f5SFrançois Tigeot s->wr_watermark = I915_READ(GEN7_WR_WATERMARK); 1062ba55f2f5SFrançois Tigeot s->gfx_prio_ctrl = I915_READ(GEN7_GFX_PRIO_CTRL); 1063ba55f2f5SFrançois Tigeot s->arb_mode = I915_READ(ARB_MODE); 1064ba55f2f5SFrançois Tigeot s->gfx_pend_tlb0 = I915_READ(GEN7_GFX_PEND_TLB0); 1065ba55f2f5SFrançois Tigeot s->gfx_pend_tlb1 = I915_READ(GEN7_GFX_PEND_TLB1); 1066ba55f2f5SFrançois Tigeot 1067ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) 1068ba55f2f5SFrançois Tigeot s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4); 1069ba55f2f5SFrançois Tigeot 1070ba55f2f5SFrançois Tigeot s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); 1071ba55f2f5SFrançois Tigeot s->gfx_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); 1072ba55f2f5SFrançois Tigeot 1073ba55f2f5SFrançois Tigeot s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7); 1074ba55f2f5SFrançois Tigeot s->ecochk = I915_READ(GAM_ECOCHK); 1075ba55f2f5SFrançois Tigeot s->bsd_hwsp = I915_READ(BSD_HWS_PGA_GEN7); 1076ba55f2f5SFrançois Tigeot s->blt_hwsp = I915_READ(BLT_HWS_PGA_GEN7); 1077ba55f2f5SFrançois Tigeot 1078ba55f2f5SFrançois Tigeot s->tlb_rd_addr = I915_READ(GEN7_TLB_RD_ADDR); 1079ba55f2f5SFrançois Tigeot 1080ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */ 1081ba55f2f5SFrançois Tigeot s->g3dctl = I915_READ(VLV_G3DCTL); 1082ba55f2f5SFrançois Tigeot s->gsckgctl = I915_READ(VLV_GSCKGCTL); 1083ba55f2f5SFrançois Tigeot s->mbctl = I915_READ(GEN6_MBCTL); 1084ba55f2f5SFrançois Tigeot 1085ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */ 1086ba55f2f5SFrançois Tigeot s->ucgctl1 = I915_READ(GEN6_UCGCTL1); 1087ba55f2f5SFrançois Tigeot s->ucgctl3 = I915_READ(GEN6_UCGCTL3); 1088ba55f2f5SFrançois Tigeot s->rcgctl1 = I915_READ(GEN6_RCGCTL1); 1089ba55f2f5SFrançois Tigeot s->rcgctl2 = I915_READ(GEN6_RCGCTL2); 1090ba55f2f5SFrançois Tigeot s->rstctl = I915_READ(GEN6_RSTCTL); 1091ba55f2f5SFrançois Tigeot s->misccpctl = I915_READ(GEN7_MISCCPCTL); 1092ba55f2f5SFrançois Tigeot 1093ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */ 1094ba55f2f5SFrançois Tigeot s->gfxpause = I915_READ(GEN6_GFXPAUSE); 1095ba55f2f5SFrançois Tigeot s->rpdeuhwtc = I915_READ(GEN6_RPDEUHWTC); 1096ba55f2f5SFrançois Tigeot s->rpdeuc = I915_READ(GEN6_RPDEUC); 1097ba55f2f5SFrançois Tigeot s->ecobus = I915_READ(ECOBUS); 1098ba55f2f5SFrançois Tigeot s->pwrdwnupctl = I915_READ(VLV_PWRDWNUPCTL); 1099ba55f2f5SFrançois Tigeot s->rp_down_timeout = I915_READ(GEN6_RP_DOWN_TIMEOUT); 1100ba55f2f5SFrançois Tigeot s->rp_deucsw = I915_READ(GEN6_RPDEUCSW); 1101ba55f2f5SFrançois Tigeot s->rcubmabdtmr = I915_READ(GEN6_RCUBMABDTMR); 1102ba55f2f5SFrançois Tigeot s->rcedata = I915_READ(VLV_RCEDATA); 1103ba55f2f5SFrançois Tigeot s->spare2gh = I915_READ(VLV_SPAREG2H); 1104ba55f2f5SFrançois Tigeot 1105ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */ 1106ba55f2f5SFrançois Tigeot s->gt_imr = I915_READ(GTIMR); 1107ba55f2f5SFrançois Tigeot s->gt_ier = I915_READ(GTIER); 1108ba55f2f5SFrançois Tigeot s->pm_imr = I915_READ(GEN6_PMIMR); 1109ba55f2f5SFrançois Tigeot s->pm_ier = I915_READ(GEN6_PMIER); 1110ba55f2f5SFrançois Tigeot 1111ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) 1112ba55f2f5SFrançois Tigeot s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH_BASE + i * 4); 1113ba55f2f5SFrançois Tigeot 1114ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */ 1115ba55f2f5SFrançois Tigeot s->tilectl = I915_READ(TILECTL); 1116ba55f2f5SFrançois Tigeot s->gt_fifoctl = I915_READ(GTFIFOCTL); 1117ba55f2f5SFrançois Tigeot s->gtlc_wake_ctrl = I915_READ(VLV_GTLC_WAKE_CTRL); 1118ba55f2f5SFrançois Tigeot s->gtlc_survive = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1119ba55f2f5SFrançois Tigeot s->pmwgicz = I915_READ(VLV_PMWGICZ); 1120ba55f2f5SFrançois Tigeot 1121ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */ 1122ba55f2f5SFrançois Tigeot s->gu_ctl0 = I915_READ(VLV_GU_CTL0); 1123ba55f2f5SFrançois Tigeot s->gu_ctl1 = I915_READ(VLV_GU_CTL1); 1124ba55f2f5SFrançois Tigeot s->clock_gate_dis2 = I915_READ(VLV_GUNIT_CLOCK_GATE2); 1125ba55f2f5SFrançois Tigeot 1126ba55f2f5SFrançois Tigeot /* 1127ba55f2f5SFrançois Tigeot * Not saving any of: 1128ba55f2f5SFrançois Tigeot * DFT, 0x9800-0x9EC0 1129ba55f2f5SFrançois Tigeot * SARB, 0xB000-0xB1FC 1130ba55f2f5SFrançois Tigeot * GAC, 0x5208-0x524C, 0x14000-0x14C000 1131ba55f2f5SFrançois Tigeot * PCI CFG 1132ba55f2f5SFrançois Tigeot */ 1133ba55f2f5SFrançois Tigeot } 1134ba55f2f5SFrançois Tigeot 1135ba55f2f5SFrançois Tigeot static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) 1136ba55f2f5SFrançois Tigeot { 1137ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state; 1138ba55f2f5SFrançois Tigeot u32 val; 1139ba55f2f5SFrançois Tigeot int i; 1140ba55f2f5SFrançois Tigeot 1141ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */ 1142ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_WR_WATERMARK, s->wr_watermark); 1143ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PRIO_CTRL, s->gfx_prio_ctrl); 1144ba55f2f5SFrançois Tigeot I915_WRITE(ARB_MODE, s->arb_mode | (0xffff << 16)); 1145ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB0, s->gfx_pend_tlb0); 1146ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB1, s->gfx_pend_tlb1); 1147ba55f2f5SFrançois Tigeot 1148ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) 1149ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]); 1150ba55f2f5SFrançois Tigeot 1151ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); 1152ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->gfx_max_req_count); 1153ba55f2f5SFrançois Tigeot 1154ba55f2f5SFrançois Tigeot I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); 1155ba55f2f5SFrançois Tigeot I915_WRITE(GAM_ECOCHK, s->ecochk); 1156ba55f2f5SFrançois Tigeot I915_WRITE(BSD_HWS_PGA_GEN7, s->bsd_hwsp); 1157ba55f2f5SFrançois Tigeot I915_WRITE(BLT_HWS_PGA_GEN7, s->blt_hwsp); 1158ba55f2f5SFrançois Tigeot 1159ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_TLB_RD_ADDR, s->tlb_rd_addr); 1160ba55f2f5SFrançois Tigeot 1161ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */ 1162ba55f2f5SFrançois Tigeot I915_WRITE(VLV_G3DCTL, s->g3dctl); 1163ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GSCKGCTL, s->gsckgctl); 1164ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_MBCTL, s->mbctl); 1165ba55f2f5SFrançois Tigeot 1166ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */ 1167ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL1, s->ucgctl1); 1168ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL3, s->ucgctl3); 1169ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL1, s->rcgctl1); 1170ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL2, s->rcgctl2); 1171ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RSTCTL, s->rstctl); 1172ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MISCCPCTL, s->misccpctl); 1173ba55f2f5SFrançois Tigeot 1174ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */ 1175ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_GFXPAUSE, s->gfxpause); 1176ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUHWTC, s->rpdeuhwtc); 1177ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUC, s->rpdeuc); 1178ba55f2f5SFrançois Tigeot I915_WRITE(ECOBUS, s->ecobus); 1179ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PWRDWNUPCTL, s->pwrdwnupctl); 1180ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RP_DOWN_TIMEOUT,s->rp_down_timeout); 1181ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUCSW, s->rp_deucsw); 1182ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCUBMABDTMR, s->rcubmabdtmr); 1183ba55f2f5SFrançois Tigeot I915_WRITE(VLV_RCEDATA, s->rcedata); 1184ba55f2f5SFrançois Tigeot I915_WRITE(VLV_SPAREG2H, s->spare2gh); 1185ba55f2f5SFrançois Tigeot 1186ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */ 1187ba55f2f5SFrançois Tigeot I915_WRITE(GTIMR, s->gt_imr); 1188ba55f2f5SFrançois Tigeot I915_WRITE(GTIER, s->gt_ier); 1189ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIMR, s->pm_imr); 1190ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIER, s->pm_ier); 1191ba55f2f5SFrançois Tigeot 1192ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) 1193ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GT_SCRATCH_BASE + i * 4, s->gt_scratch[i]); 1194ba55f2f5SFrançois Tigeot 1195ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */ 1196ba55f2f5SFrançois Tigeot I915_WRITE(TILECTL, s->tilectl); 1197ba55f2f5SFrançois Tigeot I915_WRITE(GTFIFOCTL, s->gt_fifoctl); 1198ba55f2f5SFrançois Tigeot /* 1199ba55f2f5SFrançois Tigeot * Preserve the GT allow wake and GFX force clock bit, they are not 1200ba55f2f5SFrançois Tigeot * be restored, as they are used to control the s0ix suspend/resume 1201ba55f2f5SFrançois Tigeot * sequence by the caller. 1202ba55f2f5SFrançois Tigeot */ 1203ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL); 1204ba55f2f5SFrançois Tigeot val &= VLV_GTLC_ALLOWWAKEREQ; 1205ba55f2f5SFrançois Tigeot val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ; 1206ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val); 1207ba55f2f5SFrançois Tigeot 1208ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1209ba55f2f5SFrançois Tigeot val &= VLV_GFX_CLK_FORCE_ON_BIT; 1210ba55f2f5SFrançois Tigeot val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT; 1211ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); 1212ba55f2f5SFrançois Tigeot 1213ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PMWGICZ, s->pmwgicz); 1214ba55f2f5SFrançois Tigeot 1215ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */ 1216ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL0, s->gu_ctl0); 1217ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL1, s->gu_ctl1); 1218ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GUNIT_CLOCK_GATE2, s->clock_gate_dis2); 1219ba55f2f5SFrançois Tigeot } 1220ba55f2f5SFrançois Tigeot #endif 1221ba55f2f5SFrançois Tigeot 1222ba55f2f5SFrançois Tigeot int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) 1223ba55f2f5SFrançois Tigeot { 1224ba55f2f5SFrançois Tigeot u32 val; 1225ba55f2f5SFrançois Tigeot int err; 1226ba55f2f5SFrançois Tigeot 1227ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1228ba55f2f5SFrançois Tigeot WARN_ON(!!(val & VLV_GFX_CLK_FORCE_ON_BIT) == force_on); 1229ba55f2f5SFrançois Tigeot 1230ba55f2f5SFrançois Tigeot #define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT) 1231ba55f2f5SFrançois Tigeot /* Wait for a previous force-off to settle */ 1232ba55f2f5SFrançois Tigeot if (force_on) { 1233ba55f2f5SFrançois Tigeot err = wait_for(!COND, 20); 1234ba55f2f5SFrançois Tigeot if (err) { 1235ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GFX clock force-off (%08x)\n", 1236ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_SURVIVABILITY_REG)); 1237ba55f2f5SFrançois Tigeot return err; 1238ba55f2f5SFrançois Tigeot } 1239ba55f2f5SFrançois Tigeot } 1240ba55f2f5SFrançois Tigeot 1241ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1242ba55f2f5SFrançois Tigeot val &= ~VLV_GFX_CLK_FORCE_ON_BIT; 1243ba55f2f5SFrançois Tigeot if (force_on) 1244ba55f2f5SFrançois Tigeot val |= VLV_GFX_CLK_FORCE_ON_BIT; 1245ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); 1246ba55f2f5SFrançois Tigeot 1247ba55f2f5SFrançois Tigeot if (!force_on) 1248ba55f2f5SFrançois Tigeot return 0; 1249ba55f2f5SFrançois Tigeot 1250ba55f2f5SFrançois Tigeot err = wait_for(COND, 20); 1251ba55f2f5SFrançois Tigeot if (err) 1252ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n", 1253ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_SURVIVABILITY_REG)); 1254ba55f2f5SFrançois Tigeot 1255ba55f2f5SFrançois Tigeot return err; 1256ba55f2f5SFrançois Tigeot #undef COND 1257ba55f2f5SFrançois Tigeot } 1258ba55f2f5SFrançois Tigeot 1259ba55f2f5SFrançois Tigeot #if 0 1260ba55f2f5SFrançois Tigeot static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow) 1261ba55f2f5SFrançois Tigeot { 1262ba55f2f5SFrançois Tigeot u32 val; 1263ba55f2f5SFrançois Tigeot int err = 0; 1264ba55f2f5SFrançois Tigeot 1265ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL); 1266ba55f2f5SFrançois Tigeot val &= ~VLV_GTLC_ALLOWWAKEREQ; 1267ba55f2f5SFrançois Tigeot if (allow) 1268ba55f2f5SFrançois Tigeot val |= VLV_GTLC_ALLOWWAKEREQ; 1269ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val); 1270ba55f2f5SFrançois Tigeot POSTING_READ(VLV_GTLC_WAKE_CTRL); 1271ba55f2f5SFrançois Tigeot 1272ba55f2f5SFrançois Tigeot #define COND (!!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEACK) == \ 1273ba55f2f5SFrançois Tigeot allow) 1274ba55f2f5SFrançois Tigeot err = wait_for(COND, 1); 1275ba55f2f5SFrançois Tigeot if (err) 1276ba55f2f5SFrançois Tigeot DRM_ERROR("timeout disabling GT waking\n"); 1277ba55f2f5SFrançois Tigeot return err; 1278ba55f2f5SFrançois Tigeot #undef COND 1279ba55f2f5SFrançois Tigeot } 1280ba55f2f5SFrançois Tigeot 1281ba55f2f5SFrançois Tigeot static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, 1282ba55f2f5SFrançois Tigeot bool wait_for_on) 1283ba55f2f5SFrançois Tigeot { 1284ba55f2f5SFrançois Tigeot u32 mask; 1285ba55f2f5SFrançois Tigeot u32 val; 1286ba55f2f5SFrançois Tigeot int err; 1287ba55f2f5SFrançois Tigeot 1288ba55f2f5SFrançois Tigeot mask = VLV_GTLC_PW_MEDIA_STATUS_MASK | VLV_GTLC_PW_RENDER_STATUS_MASK; 1289ba55f2f5SFrançois Tigeot val = wait_for_on ? mask : 0; 1290ba55f2f5SFrançois Tigeot #define COND ((I915_READ(VLV_GTLC_PW_STATUS) & mask) == val) 1291ba55f2f5SFrançois Tigeot if (COND) 1292ba55f2f5SFrançois Tigeot return 0; 1293ba55f2f5SFrançois Tigeot 1294ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("waiting for GT wells to go %s (%08x)\n", 1295ba55f2f5SFrançois Tigeot wait_for_on ? "on" : "off", 1296ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_PW_STATUS)); 1297ba55f2f5SFrançois Tigeot 1298ba55f2f5SFrançois Tigeot /* 1299ba55f2f5SFrançois Tigeot * RC6 transitioning can be delayed up to 2 msec (see 1300ba55f2f5SFrançois Tigeot * valleyview_enable_rps), use 3 msec for safety. 1301ba55f2f5SFrançois Tigeot */ 1302ba55f2f5SFrançois Tigeot err = wait_for(COND, 3); 1303ba55f2f5SFrançois Tigeot if (err) 1304ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GT wells to go %s\n", 1305ba55f2f5SFrançois Tigeot wait_for_on ? "on" : "off"); 1306ba55f2f5SFrançois Tigeot 1307ba55f2f5SFrançois Tigeot return err; 1308ba55f2f5SFrançois Tigeot #undef COND 1309ba55f2f5SFrançois Tigeot } 1310ba55f2f5SFrançois Tigeot 1311ba55f2f5SFrançois Tigeot static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) 1312ba55f2f5SFrançois Tigeot { 1313ba55f2f5SFrançois Tigeot if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR)) 1314ba55f2f5SFrançois Tigeot return; 1315ba55f2f5SFrançois Tigeot 1316ba55f2f5SFrançois Tigeot DRM_ERROR("GT register access while GT waking disabled\n"); 1317ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); 1318ba55f2f5SFrançois Tigeot } 1319ba55f2f5SFrançois Tigeot 1320ba55f2f5SFrançois Tigeot static int vlv_runtime_suspend(struct drm_i915_private *dev_priv) 1321ba55f2f5SFrançois Tigeot { 1322ba55f2f5SFrançois Tigeot u32 mask; 1323ba55f2f5SFrançois Tigeot int err; 1324ba55f2f5SFrançois Tigeot 1325ba55f2f5SFrançois Tigeot /* 1326ba55f2f5SFrançois Tigeot * Bspec defines the following GT well on flags as debug only, so 1327ba55f2f5SFrançois Tigeot * don't treat them as hard failures. 1328ba55f2f5SFrançois Tigeot */ 1329ba55f2f5SFrançois Tigeot (void)vlv_wait_for_gt_wells(dev_priv, false); 1330ba55f2f5SFrançois Tigeot 1331ba55f2f5SFrançois Tigeot mask = VLV_GTLC_RENDER_CTX_EXISTS | VLV_GTLC_MEDIA_CTX_EXISTS; 1332ba55f2f5SFrançois Tigeot WARN_ON((I915_READ(VLV_GTLC_WAKE_CTRL) & mask) != mask); 1333ba55f2f5SFrançois Tigeot 1334ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv); 1335ba55f2f5SFrançois Tigeot 1336ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, true); 1337ba55f2f5SFrançois Tigeot if (err) 1338ba55f2f5SFrançois Tigeot goto err1; 1339ba55f2f5SFrançois Tigeot 1340ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, false); 1341ba55f2f5SFrançois Tigeot if (err) 1342ba55f2f5SFrançois Tigeot goto err2; 1343ba55f2f5SFrançois Tigeot vlv_save_gunit_s0ix_state(dev_priv); 1344ba55f2f5SFrançois Tigeot 1345ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false); 1346ba55f2f5SFrançois Tigeot if (err) 1347ba55f2f5SFrançois Tigeot goto err2; 1348ba55f2f5SFrançois Tigeot 1349ba55f2f5SFrançois Tigeot return 0; 1350ba55f2f5SFrançois Tigeot 1351ba55f2f5SFrançois Tigeot err2: 1352ba55f2f5SFrançois Tigeot /* For safety always re-enable waking and disable gfx clock forcing */ 1353ba55f2f5SFrançois Tigeot vlv_allow_gt_wake(dev_priv, true); 1354ba55f2f5SFrançois Tigeot err1: 1355ba55f2f5SFrançois Tigeot vlv_force_gfx_clock(dev_priv, false); 1356ba55f2f5SFrançois Tigeot 1357ba55f2f5SFrançois Tigeot return err; 1358ba55f2f5SFrançois Tigeot } 1359ba55f2f5SFrançois Tigeot 1360ba55f2f5SFrançois Tigeot static int vlv_runtime_resume(struct drm_i915_private *dev_priv) 1361ba55f2f5SFrançois Tigeot { 1362ba55f2f5SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 1363ba55f2f5SFrançois Tigeot int err; 1364ba55f2f5SFrançois Tigeot int ret; 1365ba55f2f5SFrançois Tigeot 1366ba55f2f5SFrançois Tigeot /* 1367ba55f2f5SFrançois Tigeot * If any of the steps fail just try to continue, that's the best we 1368ba55f2f5SFrançois Tigeot * can do at this point. Return the first error code (which will also 1369ba55f2f5SFrançois Tigeot * leave RPM permanently disabled). 1370ba55f2f5SFrançois Tigeot */ 1371ba55f2f5SFrançois Tigeot ret = vlv_force_gfx_clock(dev_priv, true); 1372ba55f2f5SFrançois Tigeot 1373ba55f2f5SFrançois Tigeot vlv_restore_gunit_s0ix_state(dev_priv); 1374ba55f2f5SFrançois Tigeot 1375ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, true); 1376ba55f2f5SFrançois Tigeot if (!ret) 1377ba55f2f5SFrançois Tigeot ret = err; 1378ba55f2f5SFrançois Tigeot 1379ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false); 1380ba55f2f5SFrançois Tigeot if (!ret) 1381ba55f2f5SFrançois Tigeot ret = err; 1382ba55f2f5SFrançois Tigeot 1383ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv); 1384ba55f2f5SFrançois Tigeot 1385ba55f2f5SFrançois Tigeot intel_init_clock_gating(dev); 1386ba55f2f5SFrançois Tigeot i915_gem_restore_fences(dev); 1387ba55f2f5SFrançois Tigeot 1388ba55f2f5SFrançois Tigeot return ret; 1389ba55f2f5SFrançois Tigeot } 1390ba55f2f5SFrançois Tigeot 1391ba55f2f5SFrançois Tigeot static int intel_runtime_suspend(struct device *device) 13929edbd4a0SFrançois Tigeot { 13939edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(device); 13949edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 13959edbd4a0SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 1396ba55f2f5SFrançois Tigeot int ret; 1397ba55f2f5SFrançois Tigeot 1398ba55f2f5SFrançois Tigeot if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev)))) 1399ba55f2f5SFrançois Tigeot return -ENODEV; 14009edbd4a0SFrançois Tigeot 14019edbd4a0SFrançois Tigeot WARN_ON(!HAS_RUNTIME_PM(dev)); 1402ba55f2f5SFrançois Tigeot assert_force_wake_inactive(dev_priv); 14039edbd4a0SFrançois Tigeot 14049edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Suspending device\n"); 14059edbd4a0SFrançois Tigeot 1406ba55f2f5SFrançois Tigeot /* 1407ba55f2f5SFrançois Tigeot * We could deadlock here in case another thread holding struct_mutex 1408ba55f2f5SFrançois Tigeot * calls RPM suspend concurrently, since the RPM suspend will wait 1409ba55f2f5SFrançois Tigeot * first for this RPM suspend to finish. In this case the concurrent 1410ba55f2f5SFrançois Tigeot * RPM resume will be followed by its RPM suspend counterpart. Still 1411ba55f2f5SFrançois Tigeot * for consistency return -EAGAIN, which will reschedule this suspend. 1412ba55f2f5SFrançois Tigeot */ 1413ba55f2f5SFrançois Tigeot if (!mutex_trylock(&dev->struct_mutex)) { 1414ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("device lock contention, deffering suspend\n"); 1415ba55f2f5SFrançois Tigeot /* 1416ba55f2f5SFrançois Tigeot * Bump the expiration timestamp, otherwise the suspend won't 1417ba55f2f5SFrançois Tigeot * be rescheduled. 1418ba55f2f5SFrançois Tigeot */ 1419ba55f2f5SFrançois Tigeot pm_runtime_mark_last_busy(device); 1420ba55f2f5SFrançois Tigeot 1421ba55f2f5SFrançois Tigeot return -EAGAIN; 1422ba55f2f5SFrançois Tigeot } 1423ba55f2f5SFrançois Tigeot /* 1424ba55f2f5SFrançois Tigeot * We are safe here against re-faults, since the fault handler takes 1425ba55f2f5SFrançois Tigeot * an RPM reference. 1426ba55f2f5SFrançois Tigeot */ 14279edbd4a0SFrançois Tigeot i915_gem_release_all_mmaps(dev_priv); 1428ba55f2f5SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 1429ba55f2f5SFrançois Tigeot 1430ba55f2f5SFrançois Tigeot /* 1431ba55f2f5SFrançois Tigeot * rps.work can't be rearmed here, since we get here only after making 1432ba55f2f5SFrançois Tigeot * sure the GPU is idle and the RPS freq is set to the minimum. See 1433ba55f2f5SFrançois Tigeot * intel_mark_idle(). 1434ba55f2f5SFrançois Tigeot */ 1435ba55f2f5SFrançois Tigeot cancel_work_sync(&dev_priv->rps.work); 1436ba55f2f5SFrançois Tigeot intel_runtime_pm_disable_interrupts(dev); 1437ba55f2f5SFrançois Tigeot 1438ba55f2f5SFrançois Tigeot if (IS_GEN6(dev)) { 1439ba55f2f5SFrançois Tigeot ret = 0; 1440ba55f2f5SFrançois Tigeot } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { 1441ba55f2f5SFrançois Tigeot ret = hsw_runtime_suspend(dev_priv); 1442ba55f2f5SFrançois Tigeot } else if (IS_VALLEYVIEW(dev)) { 1443ba55f2f5SFrançois Tigeot ret = vlv_runtime_suspend(dev_priv); 1444ba55f2f5SFrançois Tigeot } else { 1445ba55f2f5SFrançois Tigeot ret = -ENODEV; 1446ba55f2f5SFrançois Tigeot WARN_ON(1); 1447ba55f2f5SFrançois Tigeot } 1448ba55f2f5SFrançois Tigeot 1449ba55f2f5SFrançois Tigeot if (ret) { 1450ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); 1451ba55f2f5SFrançois Tigeot intel_runtime_pm_restore_interrupts(dev); 1452ba55f2f5SFrançois Tigeot 1453ba55f2f5SFrançois Tigeot return ret; 1454ba55f2f5SFrançois Tigeot } 14559edbd4a0SFrançois Tigeot 14569edbd4a0SFrançois Tigeot del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); 14579edbd4a0SFrançois Tigeot dev_priv->pm.suspended = true; 14589edbd4a0SFrançois Tigeot 14599edbd4a0SFrançois Tigeot /* 14609edbd4a0SFrançois Tigeot * current versions of firmware which depend on this opregion 14619edbd4a0SFrançois Tigeot * notification have repurposed the D1 definition to mean 14629edbd4a0SFrançois Tigeot * "runtime suspended" vs. what you would normally expect (D3) 14639edbd4a0SFrançois Tigeot * to distinguish it from notifications that might be sent 14649edbd4a0SFrançois Tigeot * via the suspend path. 14659edbd4a0SFrançois Tigeot */ 14669edbd4a0SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D1); 14679edbd4a0SFrançois Tigeot 1468ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device suspended\n"); 14699edbd4a0SFrançois Tigeot return 0; 14709edbd4a0SFrançois Tigeot } 14719edbd4a0SFrançois Tigeot 1472ba55f2f5SFrançois Tigeot static int intel_runtime_resume(struct device *device) 14739edbd4a0SFrançois Tigeot { 14749edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(device); 14759edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 14769edbd4a0SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 1477ba55f2f5SFrançois Tigeot int ret; 14789edbd4a0SFrançois Tigeot 14799edbd4a0SFrançois Tigeot WARN_ON(!HAS_RUNTIME_PM(dev)); 14809edbd4a0SFrançois Tigeot 14819edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Resuming device\n"); 14829edbd4a0SFrançois Tigeot 14839edbd4a0SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D0); 14849edbd4a0SFrançois Tigeot dev_priv->pm.suspended = false; 14859edbd4a0SFrançois Tigeot 1486ba55f2f5SFrançois Tigeot if (IS_GEN6(dev)) { 1487ba55f2f5SFrançois Tigeot ret = snb_runtime_resume(dev_priv); 1488ba55f2f5SFrançois Tigeot } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { 1489ba55f2f5SFrançois Tigeot ret = hsw_runtime_resume(dev_priv); 1490ba55f2f5SFrançois Tigeot } else if (IS_VALLEYVIEW(dev)) { 1491ba55f2f5SFrançois Tigeot ret = vlv_runtime_resume(dev_priv); 1492ba55f2f5SFrançois Tigeot } else { 1493ba55f2f5SFrançois Tigeot WARN_ON(1); 1494ba55f2f5SFrançois Tigeot ret = -ENODEV; 1495ba55f2f5SFrançois Tigeot } 1496ba55f2f5SFrançois Tigeot 1497ba55f2f5SFrançois Tigeot /* 1498ba55f2f5SFrançois Tigeot * No point of rolling back things in case of an error, as the best 1499ba55f2f5SFrançois Tigeot * we can do is to hope that things will still work (and disable RPM). 1500ba55f2f5SFrançois Tigeot */ 1501ba55f2f5SFrançois Tigeot i915_gem_init_swizzling(dev); 1502ba55f2f5SFrançois Tigeot gen6_update_ring_freq(dev); 1503ba55f2f5SFrançois Tigeot 1504ba55f2f5SFrançois Tigeot intel_runtime_pm_restore_interrupts(dev); 1505ba55f2f5SFrançois Tigeot intel_reset_gt_powersave(dev); 1506ba55f2f5SFrançois Tigeot 1507ba55f2f5SFrançois Tigeot if (ret) 1508ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret); 1509ba55f2f5SFrançois Tigeot else 1510ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device resumed\n"); 1511ba55f2f5SFrançois Tigeot 1512ba55f2f5SFrançois Tigeot return ret; 15139edbd4a0SFrançois Tigeot } 15149edbd4a0SFrançois Tigeot 15159edbd4a0SFrançois Tigeot static const struct dev_pm_ops i915_pm_ops = { 15169edbd4a0SFrançois Tigeot .suspend = i915_pm_suspend, 15179edbd4a0SFrançois Tigeot .resume = i915_pm_resume, 15189edbd4a0SFrançois Tigeot .freeze = i915_pm_freeze, 15199edbd4a0SFrançois Tigeot .thaw = i915_pm_thaw, 15209edbd4a0SFrançois Tigeot .poweroff = i915_pm_poweroff, 15219edbd4a0SFrançois Tigeot .restore = i915_pm_resume, 1522ba55f2f5SFrançois Tigeot .runtime_suspend = intel_runtime_suspend, 1523ba55f2f5SFrançois Tigeot .runtime_resume = intel_runtime_resume, 15249edbd4a0SFrançois Tigeot }; 15259edbd4a0SFrançois Tigeot 15269edbd4a0SFrançois Tigeot static const struct vm_operations_struct i915_gem_vm_ops = { 15279edbd4a0SFrançois Tigeot .fault = i915_gem_fault, 15289edbd4a0SFrançois Tigeot .open = drm_gem_vm_open, 15299edbd4a0SFrançois Tigeot .close = drm_gem_vm_close, 15309edbd4a0SFrançois Tigeot }; 15319edbd4a0SFrançois Tigeot 15329edbd4a0SFrançois Tigeot static const struct file_operations i915_driver_fops = { 15339edbd4a0SFrançois Tigeot .owner = THIS_MODULE, 15349edbd4a0SFrançois Tigeot .open = drm_open, 15359edbd4a0SFrançois Tigeot .release = drm_release, 15369edbd4a0SFrançois Tigeot .unlocked_ioctl = drm_ioctl, 15379edbd4a0SFrançois Tigeot .mmap = drm_gem_mmap, 15389edbd4a0SFrançois Tigeot .poll = drm_poll, 15399edbd4a0SFrançois Tigeot .read = drm_read, 15409edbd4a0SFrançois Tigeot #ifdef CONFIG_COMPAT 15419edbd4a0SFrançois Tigeot .compat_ioctl = i915_compat_ioctl, 15429edbd4a0SFrançois Tigeot #endif 15439edbd4a0SFrançois Tigeot .llseek = noop_llseek, 15449edbd4a0SFrançois Tigeot }; 15459edbd4a0SFrançois Tigeot #endif 15469edbd4a0SFrançois Tigeot 1547e9587a4eSFrançois Tigeot static struct cdev_pager_ops i915_gem_vm_ops = { 1548e9587a4eSFrançois Tigeot .cdev_pg_fault = i915_gem_fault, 1549e9587a4eSFrançois Tigeot .cdev_pg_ctor = i915_gem_pager_ctor, 1550e9587a4eSFrançois Tigeot .cdev_pg_dtor = i915_gem_pager_dtor 1551e9587a4eSFrançois Tigeot }; 1552e9587a4eSFrançois Tigeot 1553f0b54121SFrançois Tigeot static struct drm_driver driver = { 15549edbd4a0SFrançois Tigeot /* Don't use MTRRs here; the Xserver or userspace app should 15559edbd4a0SFrançois Tigeot * deal with them for Intel hardware. 15569edbd4a0SFrançois Tigeot */ 15579edbd4a0SFrançois Tigeot .driver_features = 15589edbd4a0SFrançois Tigeot DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | 15599edbd4a0SFrançois Tigeot DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, 156079f713b0SFrançois Tigeot 1561f0b54121SFrançois Tigeot .load = i915_driver_load, 156279f713b0SFrançois Tigeot .unload = i915_driver_unload, 1563ba55f2f5SFrançois Tigeot .open = i915_driver_open, 156479f713b0SFrançois Tigeot .lastclose = i915_driver_lastclose, 1565ba55f2f5SFrançois Tigeot .preclose = i915_driver_preclose, 1566f0b54121SFrançois Tigeot .postclose = i915_driver_postclose, 1567ba55f2f5SFrançois Tigeot 1568f0b54121SFrançois Tigeot .device_is_agp = i915_driver_device_is_agp, 1569f0b54121SFrançois Tigeot .gem_free_object = i915_gem_free_object, 1570e9587a4eSFrançois Tigeot .gem_pager_ops = &i915_gem_vm_ops, 1571f0b54121SFrançois Tigeot .dumb_create = i915_gem_dumb_create, 1572f0b54121SFrançois Tigeot .dumb_map_offset = i915_gem_mmap_gtt, 15739edbd4a0SFrançois Tigeot .dumb_destroy = drm_gem_dumb_destroy, 1574f0b54121SFrançois Tigeot .ioctls = i915_ioctls, 1575f0b54121SFrançois Tigeot 1576f0b54121SFrançois Tigeot .name = DRIVER_NAME, 1577f0b54121SFrançois Tigeot .desc = DRIVER_DESC, 1578f0b54121SFrançois Tigeot .date = DRIVER_DATE, 1579f0b54121SFrançois Tigeot .major = DRIVER_MAJOR, 1580f0b54121SFrançois Tigeot .minor = DRIVER_MINOR, 1581f0b54121SFrançois Tigeot .patchlevel = DRIVER_PATCHLEVEL, 1582f0b54121SFrançois Tigeot }; 1583f0b54121SFrançois Tigeot 1584ba55f2f5SFrançois Tigeot static int __init i915_init(void); 1585ba55f2f5SFrançois Tigeot 1586ba55f2f5SFrançois Tigeot static int 1587ba55f2f5SFrançois Tigeot i915_attach(device_t kdev) 1588ba55f2f5SFrançois Tigeot { 1589ba55f2f5SFrançois Tigeot struct drm_device *dev = device_get_softc(kdev); 1590ba55f2f5SFrançois Tigeot 1591ba55f2f5SFrançois Tigeot i915_init(); 1592ba55f2f5SFrançois Tigeot 1593ba55f2f5SFrançois Tigeot dev->driver = &driver; 1594ba55f2f5SFrançois Tigeot return (drm_attach(kdev, i915_attach_list)); 1595ba55f2f5SFrançois Tigeot } 1596ba55f2f5SFrançois Tigeot 1597a2fdbec6SFrançois Tigeot static device_method_t i915_methods[] = { 1598a2fdbec6SFrançois Tigeot /* Device interface */ 1599a2fdbec6SFrançois Tigeot DEVMETHOD(device_probe, i915_pci_probe), 1600a2fdbec6SFrançois Tigeot DEVMETHOD(device_attach, i915_attach), 1601a2fdbec6SFrançois Tigeot DEVMETHOD(device_suspend, i915_suspend), 1602a2fdbec6SFrançois Tigeot DEVMETHOD(device_resume, i915_resume), 1603d0cc45b6SFrançois Tigeot DEVMETHOD(device_detach, drm_release), 1604a2fdbec6SFrançois Tigeot DEVMETHOD_END 1605a2fdbec6SFrançois Tigeot }; 1606a2fdbec6SFrançois Tigeot 1607a2fdbec6SFrançois Tigeot static driver_t i915_driver = { 1608a2fdbec6SFrançois Tigeot "drm", 1609a2fdbec6SFrançois Tigeot i915_methods, 1610a2fdbec6SFrançois Tigeot sizeof(struct drm_device) 1611a2fdbec6SFrançois Tigeot }; 1612a2fdbec6SFrançois Tigeot 1613ba55f2f5SFrançois Tigeot static int __init i915_init(void) 1614ba55f2f5SFrançois Tigeot { 1615ba55f2f5SFrançois Tigeot driver.num_ioctls = i915_max_ioctl; 1616ba55f2f5SFrançois Tigeot 1617ba55f2f5SFrançois Tigeot /* 1618ba55f2f5SFrançois Tigeot * If CONFIG_DRM_I915_KMS is set, default to KMS unless 1619ba55f2f5SFrançois Tigeot * explicitly disabled with the module pararmeter. 1620ba55f2f5SFrançois Tigeot * 1621ba55f2f5SFrançois Tigeot * Otherwise, just follow the parameter (defaulting to off). 1622ba55f2f5SFrançois Tigeot * 1623ba55f2f5SFrançois Tigeot * Allow optional vga_text_mode_force boot option to override 1624ba55f2f5SFrançois Tigeot * the default behavior. 1625ba55f2f5SFrançois Tigeot */ 1626ba55f2f5SFrançois Tigeot #if defined(CONFIG_DRM_I915_KMS) 1627ba55f2f5SFrançois Tigeot if (i915.modeset != 0) 1628ba55f2f5SFrançois Tigeot driver.driver_features |= DRIVER_MODESET; 1629ba55f2f5SFrançois Tigeot #endif 1630ba55f2f5SFrançois Tigeot if (i915.modeset == 1) 1631ba55f2f5SFrançois Tigeot driver.driver_features |= DRIVER_MODESET; 1632ba55f2f5SFrançois Tigeot 1633ba55f2f5SFrançois Tigeot #ifdef CONFIG_VGA_CONSOLE 1634ba55f2f5SFrançois Tigeot if (vgacon_text_force() && i915.modeset == -1) 1635ba55f2f5SFrançois Tigeot driver.driver_features &= ~DRIVER_MODESET; 1636ba55f2f5SFrançois Tigeot #endif 1637ba55f2f5SFrançois Tigeot 1638ba55f2f5SFrançois Tigeot if (!(driver.driver_features & DRIVER_MODESET)) { 1639ba55f2f5SFrançois Tigeot driver.get_vblank_timestamp = NULL; 1640ba55f2f5SFrançois Tigeot #ifndef CONFIG_DRM_I915_UMS 1641ba55f2f5SFrançois Tigeot /* Silently fail loading to not upset userspace. */ 1642ba55f2f5SFrançois Tigeot DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); 1643ba55f2f5SFrançois Tigeot return 0; 1644ba55f2f5SFrançois Tigeot #endif 1645ba55f2f5SFrançois Tigeot } 1646ba55f2f5SFrançois Tigeot 1647ba55f2f5SFrançois Tigeot #if 0 1648ba55f2f5SFrançois Tigeot return drm_pci_init(&driver, &i915_pci_driver); 1649ba55f2f5SFrançois Tigeot #else 1650ba55f2f5SFrançois Tigeot return 1; 1651ba55f2f5SFrançois Tigeot #endif 1652ba55f2f5SFrançois Tigeot } 1653ba55f2f5SFrançois Tigeot 1654a2fdbec6SFrançois Tigeot DRIVER_MODULE_ORDERED(i915kms, vgapci, i915_driver, drm_devclass, 0, 0, 1655a2fdbec6SFrançois Tigeot SI_ORDER_ANY); 1656a2fdbec6SFrançois Tigeot MODULE_DEPEND(i915kms, drm, 1, 1, 1); 1657a2fdbec6SFrançois Tigeot MODULE_DEPEND(i915kms, agp, 1, 1, 1); 1658a2fdbec6SFrançois Tigeot MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); 1659a2fdbec6SFrançois Tigeot MODULE_DEPEND(i915kms, iic, 1, 1, 1); 1660a2fdbec6SFrançois Tigeot MODULE_DEPEND(i915kms, iicbb, 1, 1, 1); 1661