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 308621f407SFrançois Tigeot #include <linux/device.h> 31*922e7c40SFrançois Tigeot #include <linux/acpi.h> 3218e26a6dSFrançois Tigeot #include <drm/drmP.h> 335c6c6f23SFrançois Tigeot #include <drm/i915_drm.h> 34c4a9e910SFrançois Tigeot #include "i915_drv.h" 358621f407SFrançois Tigeot #include "i915_trace.h" 36e3adcf8fSFrançois Tigeot #include "intel_drv.h" 37c4a9e910SFrançois Tigeot 38*922e7c40SFrançois Tigeot #include <linux/apple-gmux.h> 398621f407SFrançois Tigeot #include <linux/console.h> 409edbd4a0SFrançois Tigeot #include <linux/module.h> 41*922e7c40SFrançois Tigeot #include <linux/pm_runtime.h> 42*922e7c40SFrançois Tigeot #include <linux/vgaarb.h> 438621f407SFrançois Tigeot #include <linux/vga_switcheroo.h> 449edbd4a0SFrançois Tigeot #include <drm/drm_crtc_helper.h> 459edbd4a0SFrançois Tigeot 46f0b54121SFrançois Tigeot static struct drm_driver driver; 47f0b54121SFrançois Tigeot 48ba55f2f5SFrançois Tigeot #define GEN_DEFAULT_PIPEOFFSETS \ 49ba55f2f5SFrançois Tigeot .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ 50ba55f2f5SFrançois Tigeot PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ 51ba55f2f5SFrançois Tigeot .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ 52ba55f2f5SFrançois Tigeot TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ 53ba55f2f5SFrançois Tigeot .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } 54ba55f2f5SFrançois Tigeot 55ba55f2f5SFrançois Tigeot #define GEN_CHV_PIPEOFFSETS \ 56ba55f2f5SFrançois Tigeot .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ 57ba55f2f5SFrançois Tigeot CHV_PIPE_C_OFFSET }, \ 58ba55f2f5SFrançois Tigeot .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ 59ba55f2f5SFrançois Tigeot CHV_TRANSCODER_C_OFFSET, }, \ 60ba55f2f5SFrançois Tigeot .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ 61ba55f2f5SFrançois Tigeot CHV_PALETTE_C_OFFSET } 62ba55f2f5SFrançois Tigeot 63ba55f2f5SFrançois Tigeot #define CURSOR_OFFSETS \ 64ba55f2f5SFrançois Tigeot .cursor_offsets = { CURSOR_A_OFFSET, CURSOR_B_OFFSET, CHV_CURSOR_C_OFFSET } 65ba55f2f5SFrançois Tigeot 66ba55f2f5SFrançois Tigeot #define IVB_CURSOR_OFFSETS \ 67ba55f2f5SFrançois Tigeot .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } 68ba55f2f5SFrançois Tigeot 698621f407SFrançois Tigeot #define BDW_COLORS \ 708621f407SFrançois Tigeot .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } 718621f407SFrançois Tigeot #define CHV_COLORS \ 728621f407SFrançois Tigeot .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } 738621f407SFrançois Tigeot 74e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i830_info = { 758e26cdf6SFrançois Tigeot .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, 76e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 779edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 78ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 79ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 80e3adcf8fSFrançois Tigeot }; 81c4a9e910SFrançois Tigeot 82e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_845g_info = { 838e26cdf6SFrançois Tigeot .gen = 2, .num_pipes = 1, 84e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 859edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 86ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 87ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 88e3adcf8fSFrançois Tigeot }; 89e3adcf8fSFrançois Tigeot 90e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i85x_info = { 918e26cdf6SFrançois Tigeot .gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2, 92e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 93e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 949edbd4a0SFrançois Tigeot .has_fbc = 1, 959edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 96ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 97ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 98e3adcf8fSFrançois Tigeot }; 99e3adcf8fSFrançois Tigeot 100e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i865g_info = { 1018e26cdf6SFrançois Tigeot .gen = 2, .num_pipes = 1, 102e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 1039edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 104ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 105ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 106e3adcf8fSFrançois Tigeot }; 107e3adcf8fSFrançois Tigeot 108e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915g_info = { 1098e26cdf6SFrançois Tigeot .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2, 110e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 1119edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 112ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 113ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 114e3adcf8fSFrançois Tigeot }; 115e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i915gm_info = { 1168e26cdf6SFrançois Tigeot .gen = 3, .is_mobile = 1, .num_pipes = 2, 117e3adcf8fSFrançois Tigeot .cursor_needs_physical = 1, 118e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 119e3adcf8fSFrançois Tigeot .supports_tv = 1, 1209edbd4a0SFrançois Tigeot .has_fbc = 1, 1219edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 122ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 123ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 124e3adcf8fSFrançois Tigeot }; 125e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945g_info = { 1268e26cdf6SFrançois Tigeot .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2, 127e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 1289edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 129ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 130ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 131e3adcf8fSFrançois Tigeot }; 132e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i945gm_info = { 1338e26cdf6SFrançois Tigeot .gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2, 134e3adcf8fSFrançois Tigeot .has_hotplug = 1, .cursor_needs_physical = 1, 135e3adcf8fSFrançois Tigeot .has_overlay = 1, .overlay_needs_physical = 1, 136e3adcf8fSFrançois Tigeot .supports_tv = 1, 1379edbd4a0SFrançois Tigeot .has_fbc = 1, 1389edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 139ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 140ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 141e3adcf8fSFrançois Tigeot }; 142e3adcf8fSFrançois Tigeot 143e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965g_info = { 1448e26cdf6SFrançois Tigeot .gen = 4, .is_broadwater = 1, .num_pipes = 2, 145e3adcf8fSFrançois Tigeot .has_hotplug = 1, 146e3adcf8fSFrançois Tigeot .has_overlay = 1, 1479edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 148ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 149ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 150e3adcf8fSFrançois Tigeot }; 151e3adcf8fSFrançois Tigeot 152e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_i965gm_info = { 1538e26cdf6SFrançois Tigeot .gen = 4, .is_crestline = 1, .num_pipes = 2, 154e3adcf8fSFrançois Tigeot .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, 155e3adcf8fSFrançois Tigeot .has_overlay = 1, 156e3adcf8fSFrançois Tigeot .supports_tv = 1, 1579edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 158ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 159ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 160e3adcf8fSFrançois Tigeot }; 161e3adcf8fSFrançois Tigeot 162e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g33_info = { 1638e26cdf6SFrançois Tigeot .gen = 3, .is_g33 = 1, .num_pipes = 2, 164e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 165e3adcf8fSFrançois Tigeot .has_overlay = 1, 1669edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING, 167ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 168ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 169e3adcf8fSFrançois Tigeot }; 170e3adcf8fSFrançois Tigeot 171e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_g45_info = { 1728e26cdf6SFrançois Tigeot .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2, 173e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 1749edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 175ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 176ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 177e3adcf8fSFrançois Tigeot }; 178e3adcf8fSFrançois Tigeot 179e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_gm45_info = { 1808e26cdf6SFrançois Tigeot .gen = 4, .is_g4x = 1, .num_pipes = 2, 181e3adcf8fSFrançois Tigeot .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, 182e3adcf8fSFrançois Tigeot .has_pipe_cxsr = 1, .has_hotplug = 1, 183e3adcf8fSFrançois Tigeot .supports_tv = 1, 1849edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 185ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 186ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 187e3adcf8fSFrançois Tigeot }; 188e3adcf8fSFrançois Tigeot 189e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_pineview_info = { 1908e26cdf6SFrançois Tigeot .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2, 191e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 192e3adcf8fSFrançois Tigeot .has_overlay = 1, 193ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 194ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 195e3adcf8fSFrançois Tigeot }; 196e3adcf8fSFrançois Tigeot 197e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_d_info = { 1988e26cdf6SFrançois Tigeot .gen = 5, .num_pipes = 2, 199e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 2009edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 201ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 202ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 203e3adcf8fSFrançois Tigeot }; 204e3adcf8fSFrançois Tigeot 205e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ironlake_m_info = { 2068e26cdf6SFrançois Tigeot .gen = 5, .is_mobile = 1, .num_pipes = 2, 207e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 20800dca1bbSFrançois Tigeot .has_fbc = 1, 2099edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING, 210ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 211ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 212e3adcf8fSFrançois Tigeot }; 213e3adcf8fSFrançois Tigeot 214e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_d_info = { 2158e26cdf6SFrançois Tigeot .gen = 6, .num_pipes = 2, 216e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 2179edbd4a0SFrançois Tigeot .has_fbc = 1, 2189edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, 219e3adcf8fSFrançois Tigeot .has_llc = 1, 220ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 221ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 222e3adcf8fSFrançois Tigeot }; 223e3adcf8fSFrançois Tigeot 224e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_sandybridge_m_info = { 2258e26cdf6SFrançois Tigeot .gen = 6, .is_mobile = 1, .num_pipes = 2, 226e3adcf8fSFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 227e3adcf8fSFrançois Tigeot .has_fbc = 1, 2289edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, 229e3adcf8fSFrançois Tigeot .has_llc = 1, 230ba55f2f5SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 231ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 232e3adcf8fSFrançois Tigeot }; 233e3adcf8fSFrançois Tigeot 2348e26cdf6SFrançois Tigeot #define GEN7_FEATURES \ 2358e26cdf6SFrançois Tigeot .gen = 7, .num_pipes = 3, \ 2368e26cdf6SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, \ 2379edbd4a0SFrançois Tigeot .has_fbc = 1, \ 2389edbd4a0SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ 239aee94f86SFrançois Tigeot .has_llc = 1, \ 240aee94f86SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, \ 241aee94f86SFrançois Tigeot IVB_CURSOR_OFFSETS 2428e26cdf6SFrançois Tigeot 243e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_d_info = { 2448e26cdf6SFrançois Tigeot GEN7_FEATURES, 2458e26cdf6SFrançois Tigeot .is_ivybridge = 1, 246e3adcf8fSFrançois Tigeot }; 247e3adcf8fSFrançois Tigeot 248e3adcf8fSFrançois Tigeot static const struct intel_device_info intel_ivybridge_m_info = { 2498e26cdf6SFrançois Tigeot GEN7_FEATURES, 2508e26cdf6SFrançois Tigeot .is_ivybridge = 1, 2518e26cdf6SFrançois Tigeot .is_mobile = 1, 2528e26cdf6SFrançois Tigeot }; 2538e26cdf6SFrançois Tigeot 2548e26cdf6SFrançois Tigeot static const struct intel_device_info intel_ivybridge_q_info = { 2558e26cdf6SFrançois Tigeot GEN7_FEATURES, 2568e26cdf6SFrançois Tigeot .is_ivybridge = 1, 2578e26cdf6SFrançois Tigeot .num_pipes = 0, /* legal, last one wins */ 258e3adcf8fSFrançois Tigeot }; 259e3adcf8fSFrançois Tigeot 260aee94f86SFrançois Tigeot #define VLV_FEATURES \ 261aee94f86SFrançois Tigeot .gen = 7, .num_pipes = 2, \ 262aee94f86SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, \ 263aee94f86SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ 264aee94f86SFrançois Tigeot .display_mmio_offset = VLV_DISPLAY_BASE, \ 265aee94f86SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, \ 266aee94f86SFrançois Tigeot CURSOR_OFFSETS 267aee94f86SFrançois Tigeot 268e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_m_info = { 269aee94f86SFrançois Tigeot VLV_FEATURES, 270e9243325SFrançois Tigeot .is_valleyview = 1, 271aee94f86SFrançois Tigeot .is_mobile = 1, 272e9243325SFrançois Tigeot }; 273e9243325SFrançois Tigeot 274e9243325SFrançois Tigeot static const struct intel_device_info intel_valleyview_d_info = { 275aee94f86SFrançois Tigeot VLV_FEATURES, 276e9243325SFrançois Tigeot .is_valleyview = 1, 277e9243325SFrançois Tigeot }; 278e9243325SFrançois Tigeot 279aee94f86SFrançois Tigeot #define HSW_FEATURES \ 280aee94f86SFrançois Tigeot GEN7_FEATURES, \ 281aee94f86SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ 282aee94f86SFrançois Tigeot .has_ddi = 1, \ 283aee94f86SFrançois Tigeot .has_fpga_dbg = 1 284aee94f86SFrançois Tigeot 285e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_d_info = { 286aee94f86SFrançois Tigeot HSW_FEATURES, 2878e26cdf6SFrançois Tigeot .is_haswell = 1, 288e9243325SFrançois Tigeot }; 289e9243325SFrançois Tigeot 290e9243325SFrançois Tigeot static const struct intel_device_info intel_haswell_m_info = { 291aee94f86SFrançois Tigeot HSW_FEATURES, 2928e26cdf6SFrançois Tigeot .is_haswell = 1, 2938e26cdf6SFrançois Tigeot .is_mobile = 1, 294e9243325SFrançois Tigeot }; 295e3adcf8fSFrançois Tigeot 2968621f407SFrançois Tigeot #define BDW_FEATURES \ 2978621f407SFrançois Tigeot HSW_FEATURES, \ 2988621f407SFrançois Tigeot BDW_COLORS 2998621f407SFrançois Tigeot 3009edbd4a0SFrançois Tigeot static const struct intel_device_info intel_broadwell_d_info = { 3018621f407SFrançois Tigeot BDW_FEATURES, 302aee94f86SFrançois Tigeot .gen = 8, 3039edbd4a0SFrançois Tigeot }; 3049edbd4a0SFrançois Tigeot 3059edbd4a0SFrançois Tigeot static const struct intel_device_info intel_broadwell_m_info = { 3068621f407SFrançois Tigeot BDW_FEATURES, 307aee94f86SFrançois Tigeot .gen = 8, .is_mobile = 1, 308ba55f2f5SFrançois Tigeot }; 309ba55f2f5SFrançois Tigeot 310ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_broadwell_gt3d_info = { 3118621f407SFrançois Tigeot BDW_FEATURES, 312aee94f86SFrançois Tigeot .gen = 8, 313ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 314ba55f2f5SFrançois Tigeot }; 315ba55f2f5SFrançois Tigeot 316ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_broadwell_gt3m_info = { 3178621f407SFrançois Tigeot BDW_FEATURES, 318aee94f86SFrançois Tigeot .gen = 8, .is_mobile = 1, 319ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 320ba55f2f5SFrançois Tigeot }; 321ba55f2f5SFrançois Tigeot 322ba55f2f5SFrançois Tigeot static const struct intel_device_info intel_cherryview_info = { 323ba55f2f5SFrançois Tigeot .gen = 8, .num_pipes = 3, 324ba55f2f5SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 325ba55f2f5SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 326aee94f86SFrançois Tigeot .is_cherryview = 1, 327ba55f2f5SFrançois Tigeot .display_mmio_offset = VLV_DISPLAY_BASE, 328ba55f2f5SFrançois Tigeot GEN_CHV_PIPEOFFSETS, 329ba55f2f5SFrançois Tigeot CURSOR_OFFSETS, 3308621f407SFrançois Tigeot CHV_COLORS, 3319edbd4a0SFrançois Tigeot }; 3329edbd4a0SFrançois Tigeot 3332c9916cdSFrançois Tigeot static const struct intel_device_info intel_skylake_info = { 3348621f407SFrançois Tigeot BDW_FEATURES, 3352c9916cdSFrançois Tigeot .is_skylake = 1, 336aee94f86SFrançois Tigeot .gen = 9, 3372c9916cdSFrançois Tigeot }; 3382c9916cdSFrançois Tigeot 339477eb7f9SFrançois Tigeot static const struct intel_device_info intel_skylake_gt3_info = { 3408621f407SFrançois Tigeot BDW_FEATURES, 341477eb7f9SFrançois Tigeot .is_skylake = 1, 342aee94f86SFrançois Tigeot .gen = 9, 343477eb7f9SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 344477eb7f9SFrançois Tigeot }; 345477eb7f9SFrançois Tigeot 34619c468b4SFrançois Tigeot static const struct intel_device_info intel_broxton_info = { 34719c468b4SFrançois Tigeot .is_preliminary = 1, 348aee94f86SFrançois Tigeot .is_broxton = 1, 34919c468b4SFrançois Tigeot .gen = 9, 35019c468b4SFrançois Tigeot .need_gfx_hws = 1, .has_hotplug = 1, 35119c468b4SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, 35219c468b4SFrançois Tigeot .num_pipes = 3, 35319c468b4SFrançois Tigeot .has_ddi = 1, 354352ff8bdSFrançois Tigeot .has_fpga_dbg = 1, 35519c468b4SFrançois Tigeot .has_fbc = 1, 35619c468b4SFrançois Tigeot GEN_DEFAULT_PIPEOFFSETS, 35719c468b4SFrançois Tigeot IVB_CURSOR_OFFSETS, 3588621f407SFrançois Tigeot BDW_COLORS, 35919c468b4SFrançois Tigeot }; 36019c468b4SFrançois Tigeot 361aee94f86SFrançois Tigeot static const struct intel_device_info intel_kabylake_info = { 3628621f407SFrançois Tigeot BDW_FEATURES, 363aee94f86SFrançois Tigeot .is_kabylake = 1, 364aee94f86SFrançois Tigeot .gen = 9, 365aee94f86SFrançois Tigeot }; 366aee94f86SFrançois Tigeot 367198d2d2aSFrançois Tigeot static const struct intel_device_info intel_kabylake_gt2_info = { 368198d2d2aSFrançois Tigeot BDW_FEATURES, 369198d2d2aSFrançois Tigeot .is_kabylake = 1, 370198d2d2aSFrançois Tigeot .gen = 9, 371198d2d2aSFrançois Tigeot }; 372198d2d2aSFrançois Tigeot 373aee94f86SFrançois Tigeot static const struct intel_device_info intel_kabylake_gt3_info = { 3748621f407SFrançois Tigeot BDW_FEATURES, 375aee94f86SFrançois Tigeot .is_kabylake = 1, 376aee94f86SFrançois Tigeot .gen = 9, 377aee94f86SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 378aee94f86SFrançois Tigeot }; 379aee94f86SFrançois Tigeot 38018a1af58SFrançois Tigeot static const struct intel_device_info intel_coffeelake_gt1_info = { 38118a1af58SFrançois Tigeot BDW_FEATURES, \ 38218a1af58SFrançois Tigeot .is_kabylake = 1, 38318a1af58SFrançois Tigeot .gen = 9, 38418a1af58SFrançois Tigeot }; 38518a1af58SFrançois Tigeot 38618a1af58SFrançois Tigeot static const struct intel_device_info intel_coffeelake_gt2_info = { 3878bbe1960SFrançois Tigeot BDW_FEATURES, \ 3888bbe1960SFrançois Tigeot .is_kabylake = 1, 3898bbe1960SFrançois Tigeot .gen = 9, 3908bbe1960SFrançois Tigeot }; 3918bbe1960SFrançois Tigeot 3928bbe1960SFrançois Tigeot static const struct intel_device_info intel_coffeelake_gt3_info = { 3938bbe1960SFrançois Tigeot BDW_FEATURES, \ 3948bbe1960SFrançois Tigeot .is_kabylake = 1, 3958bbe1960SFrançois Tigeot .gen = 9, 3968bbe1960SFrançois Tigeot .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, 3978bbe1960SFrançois Tigeot }; 3988bbe1960SFrançois Tigeot 3999edbd4a0SFrançois Tigeot /* 4009edbd4a0SFrançois Tigeot * Make sure any device matches here are from most specific to most 4019edbd4a0SFrançois Tigeot * general. For example, since the Quanta match is based on the subsystem 4029edbd4a0SFrançois Tigeot * and subvendor IDs, we need it to come before the more general IVB 4039edbd4a0SFrançois Tigeot * PCI ID matches, otherwise we'll use the wrong info struct above. 4049edbd4a0SFrançois Tigeot */ 4059edbd4a0SFrançois Tigeot 406aee94f86SFrançois Tigeot static const struct pci_device_id pciidlist[] = { 407aee94f86SFrançois Tigeot INTEL_I830_IDS(&intel_i830_info), 408aee94f86SFrançois Tigeot INTEL_I845G_IDS(&intel_845g_info), 409aee94f86SFrançois Tigeot INTEL_I85X_IDS(&intel_i85x_info), 410aee94f86SFrançois Tigeot INTEL_I865G_IDS(&intel_i865g_info), 411aee94f86SFrançois Tigeot INTEL_I915G_IDS(&intel_i915g_info), 412aee94f86SFrançois Tigeot INTEL_I915GM_IDS(&intel_i915gm_info), 413aee94f86SFrançois Tigeot INTEL_I945G_IDS(&intel_i945g_info), 414aee94f86SFrançois Tigeot INTEL_I945GM_IDS(&intel_i945gm_info), 415aee94f86SFrançois Tigeot INTEL_I965G_IDS(&intel_i965g_info), 416aee94f86SFrançois Tigeot INTEL_G33_IDS(&intel_g33_info), 417aee94f86SFrançois Tigeot INTEL_I965GM_IDS(&intel_i965gm_info), 418aee94f86SFrançois Tigeot INTEL_GM45_IDS(&intel_gm45_info), 419aee94f86SFrançois Tigeot INTEL_G45_IDS(&intel_g45_info), 420aee94f86SFrançois Tigeot INTEL_PINEVIEW_IDS(&intel_pineview_info), 421aee94f86SFrançois Tigeot INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), 422aee94f86SFrançois Tigeot INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), 423aee94f86SFrançois Tigeot INTEL_SNB_D_IDS(&intel_sandybridge_d_info), 424aee94f86SFrançois Tigeot INTEL_SNB_M_IDS(&intel_sandybridge_m_info), 425aee94f86SFrançois Tigeot INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ 426aee94f86SFrançois Tigeot INTEL_IVB_M_IDS(&intel_ivybridge_m_info), 427aee94f86SFrançois Tigeot INTEL_IVB_D_IDS(&intel_ivybridge_d_info), 428aee94f86SFrançois Tigeot INTEL_HSW_D_IDS(&intel_haswell_d_info), 429aee94f86SFrançois Tigeot INTEL_HSW_M_IDS(&intel_haswell_m_info), 430aee94f86SFrançois Tigeot INTEL_VLV_M_IDS(&intel_valleyview_m_info), 431aee94f86SFrançois Tigeot INTEL_VLV_D_IDS(&intel_valleyview_d_info), 432aee94f86SFrançois Tigeot INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), 433aee94f86SFrançois Tigeot INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), 434aee94f86SFrançois Tigeot INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), 435aee94f86SFrançois Tigeot INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), 436aee94f86SFrançois Tigeot INTEL_CHV_IDS(&intel_cherryview_info), 437aee94f86SFrançois Tigeot INTEL_SKL_GT1_IDS(&intel_skylake_info), 438aee94f86SFrançois Tigeot INTEL_SKL_GT2_IDS(&intel_skylake_info), 439aee94f86SFrançois Tigeot INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), 440aee94f86SFrançois Tigeot INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info), 441aee94f86SFrançois Tigeot INTEL_BXT_IDS(&intel_broxton_info), 442aee94f86SFrançois Tigeot INTEL_KBL_GT1_IDS(&intel_kabylake_info), 443aee94f86SFrançois Tigeot INTEL_KBL_GT2_IDS(&intel_kabylake_info), 444aee94f86SFrançois Tigeot INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), 445aee94f86SFrançois Tigeot INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), 446198d2d2aSFrançois Tigeot INTEL_AML_GT2_IDS(&intel_kabylake_gt2_info), 44718a1af58SFrançois Tigeot INTEL_CFL_S_GT1_IDS(&intel_coffeelake_gt1_info), 44818a1af58SFrançois Tigeot INTEL_CFL_S_GT2_IDS(&intel_coffeelake_gt2_info), 44918a1af58SFrançois Tigeot INTEL_CFL_H_GT2_IDS(&intel_coffeelake_gt2_info), 45018a1af58SFrançois Tigeot INTEL_CFL_U_GT2_IDS(&intel_coffeelake_gt2_info), 45118a1af58SFrançois Tigeot INTEL_CFL_U_GT3_IDS(&intel_coffeelake_gt3_info), 452e755878bSFrançois Tigeot INTEL_WHL_U_GT1_IDS(&intel_coffeelake_gt1_info), 453e755878bSFrançois Tigeot INTEL_WHL_U_GT2_IDS(&intel_coffeelake_gt2_info), 454e755878bSFrançois Tigeot INTEL_WHL_U_GT3_IDS(&intel_coffeelake_gt3_info), 455aee94f86SFrançois Tigeot {0, 0, 0} 456e3adcf8fSFrançois Tigeot }; 457e3adcf8fSFrançois Tigeot 458e9243325SFrançois Tigeot #define PCI_VENDOR_INTEL 0x8086 459e9243325SFrançois Tigeot 460352ff8bdSFrançois Tigeot static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) 461352ff8bdSFrançois Tigeot { 462352ff8bdSFrançois Tigeot enum intel_pch ret = PCH_NOP; 463352ff8bdSFrançois Tigeot 464352ff8bdSFrançois Tigeot /* 465352ff8bdSFrançois Tigeot * In a virtualized passthrough environment we can be in a 466352ff8bdSFrançois Tigeot * setup where the ISA bridge is not able to be passed through. 467352ff8bdSFrançois Tigeot * In this case, a south bridge can be emulated and we have to 468352ff8bdSFrançois Tigeot * make an educated guess as to which PCH is really there. 469352ff8bdSFrançois Tigeot */ 470352ff8bdSFrançois Tigeot 471352ff8bdSFrançois Tigeot if (IS_GEN5(dev)) { 472352ff8bdSFrançois Tigeot ret = PCH_IBX; 473352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n"); 474352ff8bdSFrançois Tigeot } else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { 475352ff8bdSFrançois Tigeot ret = PCH_CPT; 476352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming CouarPoint PCH\n"); 477352ff8bdSFrançois Tigeot } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { 478352ff8bdSFrançois Tigeot ret = PCH_LPT; 479352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming LynxPoint PCH\n"); 480aee94f86SFrançois Tigeot } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { 481352ff8bdSFrançois Tigeot ret = PCH_SPT; 482352ff8bdSFrançois Tigeot DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); 483352ff8bdSFrançois Tigeot } 484352ff8bdSFrançois Tigeot 485352ff8bdSFrançois Tigeot return ret; 486352ff8bdSFrançois Tigeot } 487352ff8bdSFrançois Tigeot 488e9243325SFrançois Tigeot void intel_detect_pch(struct drm_device *dev) 489e9243325SFrançois Tigeot { 490e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 4915d302545SFrançois Tigeot device_t pch = NULL; 49227a0f882SMatthew Dillon struct pci_devinfo *di; 493e9243325SFrançois Tigeot 4948e26cdf6SFrançois Tigeot /* In all current cases, num_pipes is equivalent to the PCH_NOP setting 4958e26cdf6SFrançois Tigeot * (which really amounts to a PCH but no South Display). 4968e26cdf6SFrançois Tigeot */ 4978e26cdf6SFrançois Tigeot if (INTEL_INFO(dev)->num_pipes == 0) { 4988e26cdf6SFrançois Tigeot dev_priv->pch_type = PCH_NOP; 4998e26cdf6SFrançois Tigeot return; 5008e26cdf6SFrançois Tigeot } 5018e26cdf6SFrançois Tigeot 5029edbd4a0SFrançois Tigeot /* XXX The ISA bridge probe causes some old Core2 machines to hang */ 5039edbd4a0SFrançois Tigeot if (INTEL_INFO(dev)->gen < 5) 5049edbd4a0SFrançois Tigeot return; 5059edbd4a0SFrançois Tigeot 506e9243325SFrançois Tigeot /* 507e9243325SFrançois Tigeot * The reason to probe ISA bridge instead of Dev31:Fun0 is to 508e9243325SFrançois Tigeot * make graphics device passthrough work easy for VMM, that only 509e9243325SFrançois Tigeot * need to expose ISA bridge to let driver know the real hardware 510e9243325SFrançois Tigeot * underneath. This is a requirement from virtualization team. 5119edbd4a0SFrançois Tigeot * 5129edbd4a0SFrançois Tigeot * In some virtualized environments (e.g. XEN), there is irrelevant 5139edbd4a0SFrançois Tigeot * ISA bridge in the system. To work reliably, we should scan trhough 5149edbd4a0SFrançois Tigeot * all the ISA bridge devices and check for the first match, instead 5159edbd4a0SFrançois Tigeot * of only checking the first one. 516e9243325SFrançois Tigeot */ 51727a0f882SMatthew Dillon di = NULL; 51827a0f882SMatthew Dillon 51927a0f882SMatthew Dillon while ((pch = pci_iterate_class(&di, PCIC_BRIDGE, PCIS_BRIDGE_ISA))) { 520e9243325SFrançois Tigeot if (pci_get_vendor(pch) == PCI_VENDOR_INTEL) { 5219edbd4a0SFrançois Tigeot unsigned short id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK; 522e9243325SFrançois Tigeot dev_priv->pch_id = id; 523e9243325SFrançois Tigeot 524e9243325SFrançois Tigeot if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { 525e9243325SFrançois Tigeot dev_priv->pch_type = PCH_IBX; 526e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); 527e9243325SFrançois Tigeot WARN_ON(!IS_GEN5(dev)); 528e9243325SFrançois Tigeot } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { 529e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 530e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found CougarPoint PCH\n"); 531e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 532e9243325SFrançois Tigeot } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { 533e9243325SFrançois Tigeot /* PantherPoint is CPT compatible */ 534e9243325SFrançois Tigeot dev_priv->pch_type = PCH_CPT; 5359edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Found PantherPoint PCH\n"); 536e9243325SFrançois Tigeot WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev))); 537e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { 538e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 539e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint PCH\n"); 5402c9916cdSFrançois Tigeot WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); 5412c9916cdSFrançois Tigeot WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); 542e9243325SFrançois Tigeot } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { 543e9243325SFrançois Tigeot dev_priv->pch_type = PCH_LPT; 544e9243325SFrançois Tigeot DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); 5452c9916cdSFrançois Tigeot WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); 5462c9916cdSFrançois Tigeot WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); 5472c9916cdSFrançois Tigeot } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { 5482c9916cdSFrançois Tigeot dev_priv->pch_type = PCH_SPT; 5492c9916cdSFrançois Tigeot DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); 550aee94f86SFrançois Tigeot WARN_ON(!IS_SKYLAKE(dev) && 551aee94f86SFrançois Tigeot !IS_KABYLAKE(dev)); 5522c9916cdSFrançois Tigeot } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) { 5532c9916cdSFrançois Tigeot dev_priv->pch_type = PCH_SPT; 5542c9916cdSFrançois Tigeot DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); 555aee94f86SFrançois Tigeot WARN_ON(!IS_SKYLAKE(dev) && 556aee94f86SFrançois Tigeot !IS_KABYLAKE(dev)); 5578621f407SFrançois Tigeot } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) { 5588621f407SFrançois Tigeot dev_priv->pch_type = PCH_KBP; 5598621f407SFrançois Tigeot DRM_DEBUG_KMS("Found KabyPoint PCH\n"); 5608621f407SFrançois Tigeot WARN_ON(!IS_KABYLAKE(dev)); 561aee94f86SFrançois Tigeot } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || 5628621f407SFrançois Tigeot (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) || 5638621f407SFrançois Tigeot ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && 5648621f407SFrançois Tigeot 1)) { 565352ff8bdSFrançois Tigeot dev_priv->pch_type = intel_virt_detect_pch(dev); 5669edbd4a0SFrançois Tigeot } else 5679edbd4a0SFrançois Tigeot continue; 5689edbd4a0SFrançois Tigeot 5699edbd4a0SFrançois Tigeot break; 570e9243325SFrançois Tigeot } 571e9243325SFrançois Tigeot } 5729edbd4a0SFrançois Tigeot if (!pch) 5739edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("No PCH found.\n"); 5749edbd4a0SFrançois Tigeot 575e9243325SFrançois Tigeot #if 0 576e9243325SFrançois Tigeot pci_dev_put(pch); 577e9243325SFrançois Tigeot #endif 578e9243325SFrançois Tigeot } 579e9243325SFrançois Tigeot 5803d4007e0SFrançois Tigeot bool i915_semaphore_is_enabled(struct drm_device *dev) 5813d4007e0SFrançois Tigeot { 5823d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen < 6) 5839edbd4a0SFrançois Tigeot return false; 5849edbd4a0SFrançois Tigeot 585ba55f2f5SFrançois Tigeot if (i915.semaphores >= 0) 586ba55f2f5SFrançois Tigeot return i915.semaphores; 5873d4007e0SFrançois Tigeot 5881b13d190SFrançois Tigeot /* TODO: make semaphores and Execlists play nicely together */ 5891b13d190SFrançois Tigeot if (i915.enable_execlists) 5901b13d190SFrançois Tigeot return false; 5911b13d190SFrançois Tigeot 592ba55f2f5SFrançois Tigeot /* Until we get further testing... */ 593ba55f2f5SFrançois Tigeot if (IS_GEN8(dev)) 594ba55f2f5SFrançois Tigeot return false; 5953d4007e0SFrançois Tigeot 5963d4007e0SFrançois Tigeot #ifdef CONFIG_INTEL_IOMMU 5973d4007e0SFrançois Tigeot /* Enable semaphores on SNB when IO remapping is off */ 5983d4007e0SFrançois Tigeot if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) 5993d4007e0SFrançois Tigeot return false; 6003d4007e0SFrançois Tigeot #endif 6013d4007e0SFrançois Tigeot 6029edbd4a0SFrançois Tigeot return true; 6033d4007e0SFrançois Tigeot } 6043d4007e0SFrançois Tigeot 60519c468b4SFrançois Tigeot #ifdef __DragonFly__ 60619c468b4SFrançois Tigeot #define IS_BUILTIN(blah) 0 60719c468b4SFrançois Tigeot #endif 60819c468b4SFrançois Tigeot 60924edb884SFrançois Tigeot static void intel_suspend_encoders(struct drm_i915_private *dev_priv) 61024edb884SFrançois Tigeot { 61124edb884SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 612aee94f86SFrançois Tigeot struct intel_encoder *encoder; 61324edb884SFrançois Tigeot 61424edb884SFrançois Tigeot drm_modeset_lock_all(dev); 615aee94f86SFrançois Tigeot for_each_intel_encoder(dev, encoder) 616aee94f86SFrançois Tigeot if (encoder->suspend) 617aee94f86SFrançois Tigeot encoder->suspend(encoder); 61824edb884SFrançois Tigeot drm_modeset_unlock_all(dev); 61924edb884SFrançois Tigeot } 62024edb884SFrançois Tigeot 6212c9916cdSFrançois Tigeot static int vlv_resume_prepare(struct drm_i915_private *dev_priv, 6221b13d190SFrançois Tigeot bool rpm_resume); 6238621f407SFrançois Tigeot static int vlv_suspend_complete(struct drm_i915_private *dev_priv); 62419c468b4SFrançois Tigeot 625aee94f86SFrançois Tigeot static bool suspend_to_idle(struct drm_i915_private *dev_priv) 626aee94f86SFrançois Tigeot { 627aee94f86SFrançois Tigeot #if IS_ENABLED(CONFIG_ACPI_SLEEP) 628aee94f86SFrançois Tigeot if (acpi_target_system_state() < ACPI_STATE_S3) 629aee94f86SFrançois Tigeot return true; 630aee94f86SFrançois Tigeot #endif 631aee94f86SFrançois Tigeot return false; 632aee94f86SFrançois Tigeot } 6331b13d190SFrançois Tigeot 6342c9916cdSFrançois Tigeot static int i915_drm_suspend(struct drm_device *dev) 635e3adcf8fSFrançois Tigeot { 636e9243325SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 63724edb884SFrançois Tigeot pci_power_t opregion_target_state; 638477eb7f9SFrançois Tigeot int error; 6399edbd4a0SFrançois Tigeot 640a2fdbec6SFrançois Tigeot /* ignore lid events during suspend */ 641a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock); 642a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_SUSPENDED; 643a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock); 644a2fdbec6SFrançois Tigeot 645aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 646aee94f86SFrançois Tigeot 6479edbd4a0SFrançois Tigeot /* We do a lot of poking in a lot of registers, make sure they work 6489edbd4a0SFrançois Tigeot * properly. */ 649ba55f2f5SFrançois Tigeot intel_display_set_init_power(dev_priv, true); 650a2fdbec6SFrançois Tigeot 651e3adcf8fSFrançois Tigeot drm_kms_helper_poll_disable(dev); 652e3adcf8fSFrançois Tigeot 653e3adcf8fSFrançois Tigeot #if 0 654e3adcf8fSFrançois Tigeot pci_save_state(dev->pdev); 655e3adcf8fSFrançois Tigeot #endif 656e3adcf8fSFrançois Tigeot 6579edbd4a0SFrançois Tigeot error = i915_gem_suspend(dev); 658e3adcf8fSFrançois Tigeot if (error) { 659fb572d17SFrançois Tigeot dev_err(dev->dev, 660a2fdbec6SFrançois Tigeot "GEM idle failed, resume might fail\n"); 661aee94f86SFrançois Tigeot goto out; 662e3adcf8fSFrançois Tigeot } 663a2fdbec6SFrançois Tigeot 664352ff8bdSFrançois Tigeot intel_guc_suspend(dev); 665352ff8bdSFrançois Tigeot 6662c9916cdSFrançois Tigeot intel_suspend_gt_powersave(dev); 6672c9916cdSFrançois Tigeot 668a05eeebfSFrançois Tigeot intel_display_suspend(dev); 6695d0b1887SFrançois Tigeot 67024edb884SFrançois Tigeot #if 0 67124edb884SFrançois Tigeot intel_dp_mst_suspend(dev); 67224edb884SFrançois Tigeot #endif 67324edb884SFrançois Tigeot 6742c9916cdSFrançois Tigeot intel_runtime_pm_disable_interrupts(dev_priv); 67524edb884SFrançois Tigeot intel_hpd_cancel_work(dev_priv); 67624edb884SFrançois Tigeot 67724edb884SFrançois Tigeot intel_suspend_encoders(dev_priv); 67824edb884SFrançois Tigeot 6792c9916cdSFrançois Tigeot intel_suspend_hw(dev); 680e3adcf8fSFrançois Tigeot 6819edbd4a0SFrançois Tigeot i915_gem_suspend_gtt_mappings(dev); 6829edbd4a0SFrançois Tigeot 683e3adcf8fSFrançois Tigeot i915_save_state(dev); 684e3adcf8fSFrançois Tigeot 685aee94f86SFrançois Tigeot opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold; 68624edb884SFrançois Tigeot intel_opregion_notify_adapter(dev, opregion_target_state); 68724edb884SFrançois Tigeot 68824edb884SFrançois Tigeot intel_uncore_forcewake_reset(dev, false); 689e3adcf8fSFrançois Tigeot intel_opregion_fini(dev); 690e3adcf8fSFrançois Tigeot 6915d0b1887SFrançois Tigeot #if 0 692477eb7f9SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true); 6935d0b1887SFrançois Tigeot #endif 6945d0b1887SFrançois Tigeot 695ba55f2f5SFrançois Tigeot dev_priv->suspend_count++; 696ba55f2f5SFrançois Tigeot 69724edb884SFrançois Tigeot intel_display_set_init_power(dev_priv, false); 69824edb884SFrançois Tigeot 6998621f407SFrançois Tigeot intel_csr_ucode_suspend(dev_priv); 700aee94f86SFrançois Tigeot 701aee94f86SFrançois Tigeot out: 702aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 703aee94f86SFrançois Tigeot 704aee94f86SFrançois Tigeot return error; 705e3adcf8fSFrançois Tigeot } 706e3adcf8fSFrançois Tigeot 7072c9916cdSFrançois Tigeot static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation) 7082c9916cdSFrançois Tigeot { 7092c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = drm_dev->dev_private; 710aee94f86SFrançois Tigeot bool fw_csr; 7112c9916cdSFrançois Tigeot int ret; 7122c9916cdSFrançois Tigeot 713aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 714aee94f86SFrançois Tigeot 7158621f407SFrançois Tigeot fw_csr = !IS_BROXTON(dev_priv) && 7168621f407SFrançois Tigeot suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload; 717aee94f86SFrançois Tigeot /* 718aee94f86SFrançois Tigeot * In case of firmware assisted context save/restore don't manually 719aee94f86SFrançois Tigeot * deinit the power domains. This also means the CSR/DMC firmware will 720aee94f86SFrançois Tigeot * stay active, it will power down any HW resources as required and 721aee94f86SFrançois Tigeot * also enable deeper system power states that would be blocked if the 722aee94f86SFrançois Tigeot * firmware was inactive. 723aee94f86SFrançois Tigeot */ 724aee94f86SFrançois Tigeot if (!fw_csr) 725aee94f86SFrançois Tigeot intel_power_domains_suspend(dev_priv); 726aee94f86SFrançois Tigeot 7278621f407SFrançois Tigeot ret = 0; 7288621f407SFrançois Tigeot if (IS_BROXTON(dev_priv)) 7298621f407SFrançois Tigeot bxt_enable_dc9(dev_priv); 7308621f407SFrançois Tigeot else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 7318621f407SFrançois Tigeot hsw_enable_pc8(dev_priv); 7328621f407SFrançois Tigeot else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 7338621f407SFrançois Tigeot ret = vlv_suspend_complete(dev_priv); 7342c9916cdSFrançois Tigeot 7352c9916cdSFrançois Tigeot if (ret) { 7362c9916cdSFrançois Tigeot DRM_ERROR("Suspend complete failed: %d\n", ret); 737aee94f86SFrançois Tigeot if (!fw_csr) 738aee94f86SFrançois Tigeot intel_power_domains_init_hw(dev_priv, true); 7392c9916cdSFrançois Tigeot 740aee94f86SFrançois Tigeot goto out; 7412c9916cdSFrançois Tigeot } 7422c9916cdSFrançois Tigeot 7432c9916cdSFrançois Tigeot #if 0 7442c9916cdSFrançois Tigeot pci_disable_device(drm_dev->pdev); 7452c9916cdSFrançois Tigeot /* 746a05eeebfSFrançois Tigeot * During hibernation on some platforms the BIOS may try to access 7472c9916cdSFrançois Tigeot * the device even though it's already in D3 and hang the machine. So 7482c9916cdSFrançois Tigeot * leave the device in D0 on those platforms and hope the BIOS will 749a05eeebfSFrançois Tigeot * power down the device properly. The issue was seen on multiple old 750a05eeebfSFrançois Tigeot * GENs with different BIOS vendors, so having an explicit blacklist 751a05eeebfSFrançois Tigeot * is inpractical; apply the workaround on everything pre GEN6. The 752a05eeebfSFrançois Tigeot * platforms where the issue was seen: 753a05eeebfSFrançois Tigeot * Lenovo Thinkpad X301, X61s, X60, T60, X41 754a05eeebfSFrançois Tigeot * Fujitsu FSC S7110 755a05eeebfSFrançois Tigeot * Acer Aspire 1830T 7562c9916cdSFrançois Tigeot */ 757a05eeebfSFrançois Tigeot if (!(hibernation && INTEL_INFO(dev_priv)->gen < 6)) 7582c9916cdSFrançois Tigeot pci_set_power_state(drm_dev->pdev, PCI_D3hot); 7592c9916cdSFrançois Tigeot #endif 7602c9916cdSFrançois Tigeot 761aee94f86SFrançois Tigeot dev_priv->suspended_to_idle = suspend_to_idle(dev_priv); 762aee94f86SFrançois Tigeot 763aee94f86SFrançois Tigeot out: 764aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 765aee94f86SFrançois Tigeot 766aee94f86SFrançois Tigeot return ret; 7672c9916cdSFrançois Tigeot } 7682c9916cdSFrançois Tigeot 769352ff8bdSFrançois Tigeot int i915_suspend_switcheroo(device_t kdev) 770e3adcf8fSFrançois Tigeot { 7719edbd4a0SFrançois Tigeot struct drm_device *dev = device_get_softc(kdev); 772e3adcf8fSFrançois Tigeot int error; 773e3adcf8fSFrançois Tigeot 7749edbd4a0SFrançois Tigeot if (!dev || !dev->dev_private) { 7759edbd4a0SFrançois Tigeot DRM_ERROR("dev: %p\n", dev); 776c4a9e910SFrançois Tigeot DRM_ERROR("DRM not initialized, aborting suspend.\n"); 777c4a9e910SFrançois Tigeot return -ENODEV; 778c4a9e910SFrançois Tigeot } 779c4a9e910SFrançois Tigeot 7802c9916cdSFrançois Tigeot #if 0 7812c9916cdSFrançois Tigeot if (WARN_ON_ONCE(state.event != PM_EVENT_SUSPEND && 7822c9916cdSFrançois Tigeot state.event != PM_EVENT_FREEZE)) 7832c9916cdSFrançois Tigeot return -EINVAL; 7842c9916cdSFrançois Tigeot #endif 7852c9916cdSFrançois Tigeot 7869edbd4a0SFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 7879edbd4a0SFrançois Tigeot return 0; 7889edbd4a0SFrançois Tigeot 7892c9916cdSFrançois Tigeot error = i915_drm_suspend(dev); 790e3adcf8fSFrançois Tigeot if (error) 7919edbd4a0SFrançois Tigeot return error; 7929edbd4a0SFrançois Tigeot 7932c9916cdSFrançois Tigeot return i915_drm_suspend_late(dev, false); 794c4a9e910SFrançois Tigeot } 795c4a9e910SFrançois Tigeot 7962c9916cdSFrançois Tigeot static int i915_drm_resume(struct drm_device *dev) 797c4a9e910SFrançois Tigeot { 798e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 7998621f407SFrançois Tigeot int ret; 8009edbd4a0SFrançois Tigeot 801aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 802aee94f86SFrançois Tigeot 8038621f407SFrançois Tigeot ret = i915_ggtt_enable_hw(dev); 8048621f407SFrançois Tigeot if (ret) 8058621f407SFrançois Tigeot DRM_ERROR("failed to re-enable GGTT\n"); 8068621f407SFrançois Tigeot 8078621f407SFrançois Tigeot intel_csr_ucode_resume(dev_priv); 8088621f407SFrançois Tigeot 8099edbd4a0SFrançois Tigeot mutex_lock(&dev->struct_mutex); 8109edbd4a0SFrançois Tigeot i915_gem_restore_gtt_mappings(dev); 8119edbd4a0SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 8129edbd4a0SFrançois Tigeot 813c4a9e910SFrançois Tigeot i915_restore_state(dev); 814e3adcf8fSFrançois Tigeot intel_opregion_setup(dev); 815c4a9e910SFrançois Tigeot 81619df918dSFrançois Tigeot intel_init_pch_refclk(dev); 817ba55f2f5SFrançois Tigeot drm_mode_config_reset(dev); 81819df918dSFrançois Tigeot 819477eb7f9SFrançois Tigeot /* 820477eb7f9SFrançois Tigeot * Interrupts have to be enabled before any batches are run. If not the 821477eb7f9SFrançois Tigeot * GPU will hang. i915_gem_init_hw() will initiate batches to 822477eb7f9SFrançois Tigeot * update/restore the context. 823477eb7f9SFrançois Tigeot * 824477eb7f9SFrançois Tigeot * Modeset enabling in intel_modeset_init_hw() also needs working 825477eb7f9SFrançois Tigeot * interrupts. 826477eb7f9SFrançois Tigeot */ 827477eb7f9SFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv); 828477eb7f9SFrançois Tigeot 829a2fdbec6SFrançois Tigeot mutex_lock(&dev->struct_mutex); 830ba55f2f5SFrançois Tigeot if (i915_gem_init_hw(dev)) { 831ba55f2f5SFrançois Tigeot DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); 832a05eeebfSFrançois Tigeot atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter); 833ba55f2f5SFrançois Tigeot } 834a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 835a2fdbec6SFrançois Tigeot 836352ff8bdSFrançois Tigeot intel_guc_resume(dev); 837352ff8bdSFrançois Tigeot 83819df918dSFrançois Tigeot intel_modeset_init_hw(dev); 8398e26cdf6SFrançois Tigeot 8405e269720SFrançois Tigeot spin_lock_irq(&dev_priv->irq_lock); 8412c9916cdSFrançois Tigeot if (dev_priv->display.hpd_irq_setup) 8422c9916cdSFrançois Tigeot dev_priv->display.hpd_irq_setup(dev); 8435e269720SFrançois Tigeot spin_unlock_irq(&dev_priv->irq_lock); 8442c9916cdSFrançois Tigeot 8452c9916cdSFrançois Tigeot intel_dp_mst_resume(dev); 8462c9916cdSFrançois Tigeot 847c0e85e96SFrançois Tigeot intel_display_resume(dev); 848c0e85e96SFrançois Tigeot 849a2fdbec6SFrançois Tigeot /* 850a2fdbec6SFrançois Tigeot * ... but also need to make sure that hotplug processing 851a2fdbec6SFrançois Tigeot * doesn't cause havoc. Like in the driver load code we don't 852a2fdbec6SFrançois Tigeot * bother with the tiny race here where we might loose hotplug 853a2fdbec6SFrançois Tigeot * notifications. 854a2fdbec6SFrançois Tigeot * */ 8552c9916cdSFrançois Tigeot intel_hpd_init(dev_priv); 8568e26cdf6SFrançois Tigeot /* Config may have changed between suspend and resume */ 857ba55f2f5SFrançois Tigeot drm_helper_hpd_irq_event(dev); 858c4a9e910SFrançois Tigeot 859e3adcf8fSFrançois Tigeot intel_opregion_init(dev); 860e3adcf8fSFrançois Tigeot 8611b13d190SFrançois Tigeot intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false); 862a2fdbec6SFrançois Tigeot 863a2fdbec6SFrançois Tigeot mutex_lock(&dev_priv->modeset_restore_lock); 864a2fdbec6SFrançois Tigeot dev_priv->modeset_restore = MODESET_DONE; 865a2fdbec6SFrançois Tigeot mutex_unlock(&dev_priv->modeset_restore_lock); 8669edbd4a0SFrançois Tigeot 86724edb884SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D0); 86824edb884SFrançois Tigeot 8692c9916cdSFrançois Tigeot drm_kms_helper_poll_enable(dev); 8702c9916cdSFrançois Tigeot 871aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 872aee94f86SFrançois Tigeot 873ba55f2f5SFrançois Tigeot return 0; 874a2fdbec6SFrançois Tigeot } 875a2fdbec6SFrançois Tigeot 8762c9916cdSFrançois Tigeot static int i915_drm_resume_early(struct drm_device *dev) 877c4a9e910SFrançois Tigeot { 8785d0b1887SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 8792c9916cdSFrançois Tigeot int ret = 0; 880c4a9e910SFrançois Tigeot 8815d0b1887SFrançois Tigeot /* 8822c9916cdSFrançois Tigeot * We have a resume ordering issue with the snd-hda driver also 8832c9916cdSFrançois Tigeot * requiring our device to be power up. Due to the lack of a 8842c9916cdSFrançois Tigeot * parent/child relationship we currently solve this with an early 8852c9916cdSFrançois Tigeot * resume hook. 8862c9916cdSFrançois Tigeot * 8872c9916cdSFrançois Tigeot * FIXME: This should be solved with a special hdmi sink device or 8882c9916cdSFrançois Tigeot * similar so that power domains can be employed. 8895d0b1887SFrançois Tigeot */ 890c0e85e96SFrançois Tigeot 891c0e85e96SFrançois Tigeot /* 892c0e85e96SFrançois Tigeot * Note that we need to set the power state explicitly, since we 893c0e85e96SFrançois Tigeot * powered off the device during freeze and the PCI core won't power 894c0e85e96SFrançois Tigeot * it back up for us during thaw. Powering off the device during 895c0e85e96SFrançois Tigeot * freeze is not a hard requirement though, and during the 896c0e85e96SFrançois Tigeot * suspend/resume phases the PCI core makes sure we get here with the 897c0e85e96SFrançois Tigeot * device powered on. So in case we change our freeze logic and keep 898c0e85e96SFrançois Tigeot * the device powered we can also remove the following set power state 899c0e85e96SFrançois Tigeot * call. 900c0e85e96SFrançois Tigeot */ 9012c9916cdSFrançois Tigeot #if 0 902c0e85e96SFrançois Tigeot ret = pci_set_power_state(dev->pdev, PCI_D0); 903c0e85e96SFrançois Tigeot if (ret) { 904c0e85e96SFrançois Tigeot DRM_ERROR("failed to set PCI D0 power state (%d)\n", ret); 905c0e85e96SFrançois Tigeot goto out; 906c0e85e96SFrançois Tigeot } 907c0e85e96SFrançois Tigeot 908c0e85e96SFrançois Tigeot /* 909c0e85e96SFrançois Tigeot * Note that pci_enable_device() first enables any parent bridge 910c0e85e96SFrançois Tigeot * device and only then sets the power state for this device. The 911c0e85e96SFrançois Tigeot * bridge enabling is a nop though, since bridge devices are resumed 912c0e85e96SFrançois Tigeot * first. The order of enabling power and enabling the device is 913c0e85e96SFrançois Tigeot * imposed by the PCI core as described above, so here we preserve the 914c0e85e96SFrançois Tigeot * same order for the freeze/thaw phases. 915c0e85e96SFrançois Tigeot * 916c0e85e96SFrançois Tigeot * TODO: eventually we should remove pci_disable_device() / 917c0e85e96SFrançois Tigeot * pci_enable_enable_device() from suspend/resume. Due to how they 918c0e85e96SFrançois Tigeot * depend on the device enable refcount we can't anyway depend on them 919c0e85e96SFrançois Tigeot * disabling/enabling the device. 920c0e85e96SFrançois Tigeot */ 921aee94f86SFrançois Tigeot if (pci_enable_device(dev->pdev)) { 922aee94f86SFrançois Tigeot ret = -EIO; 923aee94f86SFrançois Tigeot goto out; 924aee94f86SFrançois Tigeot } 9252c9916cdSFrançois Tigeot 9262c9916cdSFrançois Tigeot pci_set_master(dev->pdev); 9272c9916cdSFrançois Tigeot #endif 9282c9916cdSFrançois Tigeot 929aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 930aee94f86SFrançois Tigeot 931aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 9322c9916cdSFrançois Tigeot ret = vlv_resume_prepare(dev_priv, false); 9332c9916cdSFrançois Tigeot if (ret) 93419c468b4SFrançois Tigeot DRM_ERROR("Resume prepare failed: %d, continuing anyway\n", 93519c468b4SFrançois Tigeot ret); 9362c9916cdSFrançois Tigeot 9372c9916cdSFrançois Tigeot intel_uncore_early_sanitize(dev, true); 9382c9916cdSFrançois Tigeot 9398621f407SFrançois Tigeot if (IS_BROXTON(dev)) { 9408621f407SFrançois Tigeot if (!dev_priv->suspended_to_idle) 9418621f407SFrançois Tigeot gen9_sanitize_dc_state(dev_priv); 9428621f407SFrançois Tigeot bxt_disable_dc9(dev_priv); 9438621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 9442c9916cdSFrançois Tigeot hsw_disable_pc8(dev_priv); 9458621f407SFrançois Tigeot } 9462c9916cdSFrançois Tigeot 9472c9916cdSFrançois Tigeot intel_uncore_sanitize(dev); 948aee94f86SFrançois Tigeot 9498621f407SFrançois Tigeot if (IS_BROXTON(dev_priv) || 9508621f407SFrançois Tigeot !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload)) 951aee94f86SFrançois Tigeot intel_power_domains_init_hw(dev_priv, true); 952aee94f86SFrançois Tigeot 9538621f407SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 9548621f407SFrançois Tigeot 955aee94f86SFrançois Tigeot #if 0 956aee94f86SFrançois Tigeot out: 957aee94f86SFrançois Tigeot #endif 958aee94f86SFrançois Tigeot dev_priv->suspended_to_idle = false; 959aee94f86SFrançois Tigeot 9602c9916cdSFrançois Tigeot return ret; 9612c9916cdSFrançois Tigeot } 9622c9916cdSFrançois Tigeot 963352ff8bdSFrançois Tigeot int i915_resume_switcheroo(struct drm_device *dev) 9642c9916cdSFrançois Tigeot { 9652c9916cdSFrançois Tigeot int ret; 9662c9916cdSFrançois Tigeot 9672c9916cdSFrançois Tigeot if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) 9682c9916cdSFrançois Tigeot return 0; 9692c9916cdSFrançois Tigeot 9702c9916cdSFrançois Tigeot ret = i915_drm_resume_early(dev); 9715d0b1887SFrançois Tigeot if (ret) 9725d0b1887SFrançois Tigeot return ret; 973e3adcf8fSFrançois Tigeot 9742c9916cdSFrançois Tigeot return i915_drm_resume(dev); 975c4a9e910SFrançois Tigeot } 976c4a9e910SFrançois Tigeot 97762e5f8e8SFrançois Tigeot /* XXX Hack for the old *BSD drm code base 97862e5f8e8SFrançois Tigeot * The device id field is set at probe time */ 97962e5f8e8SFrançois Tigeot static drm_pci_id_list_t i915_attach_list[] = { 98062e5f8e8SFrançois Tigeot {0x8086, 0, 0, "Intel i915 GPU"}, 98162e5f8e8SFrançois Tigeot {0, 0, 0, NULL} 98262e5f8e8SFrançois Tigeot }; 98362e5f8e8SFrançois Tigeot 984ba55f2f5SFrançois Tigeot struct intel_device_info * 985e3adcf8fSFrançois Tigeot i915_get_device_id(int device) 986c4a9e910SFrançois Tigeot { 9878e26cdf6SFrançois Tigeot const struct pci_device_id *did; 988c4a9e910SFrançois Tigeot 989e3adcf8fSFrançois Tigeot for (did = &pciidlist[0]; did->device != 0; did++) { 990e3adcf8fSFrançois Tigeot if (did->device != device) 991e3adcf8fSFrançois Tigeot continue; 9928e26cdf6SFrançois Tigeot return (struct intel_device_info *)did->driver_data; 993e3adcf8fSFrançois Tigeot } 994e3adcf8fSFrançois Tigeot return (NULL); 995c4a9e910SFrançois Tigeot } 996c4a9e910SFrançois Tigeot 997998e2cc6SPeeter Must static int i915_sysctl_init(struct drm_device *dev, struct sysctl_ctx_list *ctx, 998998e2cc6SPeeter Must struct sysctl_oid *top) 999998e2cc6SPeeter Must { 1000998e2cc6SPeeter Must return drm_add_busid_modesetting(dev, ctx, top); 1001998e2cc6SPeeter Must } 1002998e2cc6SPeeter Must 1003c4a9e910SFrançois Tigeot extern devclass_t drm_devclass; 1004e3adcf8fSFrançois Tigeot 1005e9243325SFrançois Tigeot /** 1006e9243325SFrançois Tigeot * i915_reset - reset chip after a hang 1007e9243325SFrançois Tigeot * @dev: drm device to reset 1008e9243325SFrançois Tigeot * 1009e9243325SFrançois Tigeot * Reset the chip. Useful if a hang is detected. Returns zero on successful 1010e9243325SFrançois Tigeot * reset or otherwise an error code. 1011e9243325SFrançois Tigeot * 1012e9243325SFrançois Tigeot * Procedure is fairly simple: 1013e9243325SFrançois Tigeot * - reset the chip using the reset reg 1014e9243325SFrançois Tigeot * - re-init context state 1015e9243325SFrançois Tigeot * - re-init hardware status page 1016e9243325SFrançois Tigeot * - re-init ring buffer 1017e9243325SFrançois Tigeot * - re-init interrupt state 1018e9243325SFrançois Tigeot * - re-init display 1019e9243325SFrançois Tigeot */ 102000640ec9SFrançois Tigeot int i915_reset(struct drm_device *dev) 1021e3adcf8fSFrançois Tigeot { 1022ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 10238621f407SFrançois Tigeot struct i915_gpu_error *error = &dev_priv->gpu_error; 10248621f407SFrançois Tigeot unsigned reset_counter; 1025e9243325SFrançois Tigeot int ret; 1026e9243325SFrançois Tigeot 10272c9916cdSFrançois Tigeot intel_reset_gt_powersave(dev); 10282c9916cdSFrançois Tigeot 1029a2fdbec6SFrançois Tigeot mutex_lock(&dev->struct_mutex); 1030e3adcf8fSFrançois Tigeot 10318621f407SFrançois Tigeot /* Clear any previous failed attempts at recovery. Time to try again. */ 10328621f407SFrançois Tigeot atomic_andnot(I915_WEDGED, &error->reset_counter); 10338621f407SFrançois Tigeot 10348621f407SFrançois Tigeot /* Clear the reset-in-progress flag and increment the reset epoch. */ 10358621f407SFrançois Tigeot reset_counter = atomic_inc_return(&error->reset_counter); 10368621f407SFrançois Tigeot if (WARN_ON(__i915_reset_in_progress(reset_counter))) { 10378621f407SFrançois Tigeot ret = -EIO; 10388621f407SFrançois Tigeot goto error; 10398621f407SFrançois Tigeot } 10408621f407SFrançois Tigeot 1041e3adcf8fSFrançois Tigeot i915_gem_reset(dev); 1042e3adcf8fSFrançois Tigeot 10438621f407SFrançois Tigeot ret = intel_gpu_reset(dev, ALL_ENGINES); 104400640ec9SFrançois Tigeot 10455d0b1887SFrançois Tigeot /* Also reset the gpu hangman. */ 10468621f407SFrançois Tigeot if (error->stop_rings != 0) { 10475d0b1887SFrançois Tigeot DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); 10488621f407SFrançois Tigeot error->stop_rings = 0; 10495d0b1887SFrançois Tigeot if (ret == -ENODEV) { 10509edbd4a0SFrançois Tigeot DRM_INFO("Reset not implemented, but ignoring " 10515d0b1887SFrançois Tigeot "error for simulated gpu hangs\n"); 10525d0b1887SFrançois Tigeot ret = 0; 10535d0b1887SFrançois Tigeot } 10545d0b1887SFrançois Tigeot } 10559edbd4a0SFrançois Tigeot 10562c9916cdSFrançois Tigeot if (i915_stop_ring_allow_warn(dev_priv)) 10572c9916cdSFrançois Tigeot pr_notice("drm/i915: Resetting chip after gpu hang\n"); 10582c9916cdSFrançois Tigeot 1059e3adcf8fSFrançois Tigeot if (ret) { 10608621f407SFrançois Tigeot if (ret != -ENODEV) 10619edbd4a0SFrançois Tigeot DRM_ERROR("Failed to reset chip: %i\n", ret); 10628621f407SFrançois Tigeot else 10638621f407SFrançois Tigeot DRM_DEBUG_DRIVER("GPU reset disabled\n"); 10648621f407SFrançois Tigeot goto error; 1065e3adcf8fSFrançois Tigeot } 1066e3adcf8fSFrançois Tigeot 10672c9916cdSFrançois Tigeot intel_overlay_reset(dev_priv); 10682c9916cdSFrançois Tigeot 1069e9243325SFrançois Tigeot /* Ok, now get things going again... */ 1070e9243325SFrançois Tigeot 1071e9243325SFrançois Tigeot /* 1072e9243325SFrançois Tigeot * Everything depends on having the GTT running, so we need to start 1073e9243325SFrançois Tigeot * there. Fortunately we don't need to do this unless we reset the 1074e9243325SFrançois Tigeot * chip at a PCI level. 1075e9243325SFrançois Tigeot * 1076e9243325SFrançois Tigeot * Next we need to restore the context, but we don't use those 1077e9243325SFrançois Tigeot * yet either... 1078e9243325SFrançois Tigeot * 1079e9243325SFrançois Tigeot * Ring buffer needs to be re-initialized in the KMS case, or if X 1080e9243325SFrançois Tigeot * was running at the time of the reset (i.e. we weren't VT 1081e9243325SFrançois Tigeot * switched away). 1082e9243325SFrançois Tigeot */ 10839edbd4a0SFrançois Tigeot ret = i915_gem_init_hw(dev); 10849edbd4a0SFrançois Tigeot if (ret) { 10859edbd4a0SFrançois Tigeot DRM_ERROR("Failed hw init on reset %d\n", ret); 10868621f407SFrançois Tigeot goto error; 10879edbd4a0SFrançois Tigeot } 1088e3adcf8fSFrançois Tigeot 10898621f407SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 10908621f407SFrançois Tigeot 1091ba55f2f5SFrançois Tigeot /* 1092ba55f2f5SFrançois Tigeot * rps/rc6 re-init is necessary to restore state lost after the 1093ba55f2f5SFrançois Tigeot * reset and the re-install of gt irqs. Skip for ironlake per 1094ba55f2f5SFrançois Tigeot * previous concerns that it doesn't respond well to some forms 1095ba55f2f5SFrançois Tigeot * of re-init after reset. 1096ba55f2f5SFrançois Tigeot */ 1097ba55f2f5SFrançois Tigeot if (INTEL_INFO(dev)->gen > 5) 10982c9916cdSFrançois Tigeot intel_enable_gt_powersave(dev); 1099e3adcf8fSFrançois Tigeot 1100e9243325SFrançois Tigeot return 0; 11018621f407SFrançois Tigeot 11028621f407SFrançois Tigeot error: 11038621f407SFrançois Tigeot atomic_or(I915_WEDGED, &error->reset_counter); 11048621f407SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 11058621f407SFrançois Tigeot return ret; 1106e9243325SFrançois Tigeot } 1107e9243325SFrançois Tigeot 1108ba55f2f5SFrançois Tigeot static int i915_pci_probe(device_t kdev) 1109a2fdbec6SFrançois Tigeot { 1110a2fdbec6SFrançois Tigeot int device, i = 0; 1111a2fdbec6SFrançois Tigeot 1112a2fdbec6SFrançois Tigeot if (pci_get_class(kdev) != PCIC_DISPLAY) 1113a2fdbec6SFrançois Tigeot return ENXIO; 1114a2fdbec6SFrançois Tigeot 1115a2fdbec6SFrançois Tigeot if (pci_get_vendor(kdev) != PCI_VENDOR_INTEL) 1116a2fdbec6SFrançois Tigeot return ENXIO; 1117a2fdbec6SFrançois Tigeot 1118a2fdbec6SFrançois Tigeot device = pci_get_device(kdev); 1119a2fdbec6SFrançois Tigeot 1120a2fdbec6SFrançois Tigeot for (i = 0; pciidlist[i].device != 0; i++) { 1121a2fdbec6SFrançois Tigeot if (pciidlist[i].device == device) { 1122a2fdbec6SFrançois Tigeot i915_attach_list[0].device = device; 1123a2fdbec6SFrançois Tigeot return 0; 1124a2fdbec6SFrançois Tigeot } 1125a2fdbec6SFrançois Tigeot } 1126a2fdbec6SFrançois Tigeot 1127a2fdbec6SFrançois Tigeot return ENXIO; 1128a2fdbec6SFrançois Tigeot } 1129a2fdbec6SFrançois Tigeot 11309edbd4a0SFrançois Tigeot #if 0 11319edbd4a0SFrançois Tigeot static void 11329edbd4a0SFrançois Tigeot i915_pci_remove(struct pci_dev *pdev) 11339edbd4a0SFrançois Tigeot { 11349edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 11359edbd4a0SFrançois Tigeot 11369edbd4a0SFrançois Tigeot drm_put_dev(dev); 11379edbd4a0SFrançois Tigeot } 11389edbd4a0SFrançois Tigeot 11399edbd4a0SFrançois Tigeot static int i915_pm_suspend(struct device *dev) 11409edbd4a0SFrançois Tigeot { 11419edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(dev); 11429edbd4a0SFrançois Tigeot struct drm_device *drm_dev = pci_get_drvdata(pdev); 11439edbd4a0SFrançois Tigeot 11449edbd4a0SFrançois Tigeot if (!drm_dev || !drm_dev->dev_private) { 11459edbd4a0SFrançois Tigeot dev_err(dev, "DRM not initialized, aborting suspend.\n"); 11469edbd4a0SFrançois Tigeot return -ENODEV; 11479edbd4a0SFrançois Tigeot } 11489edbd4a0SFrançois Tigeot 11499edbd4a0SFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 11509edbd4a0SFrançois Tigeot return 0; 11519edbd4a0SFrançois Tigeot 11522c9916cdSFrançois Tigeot return i915_drm_suspend(drm_dev); 11539edbd4a0SFrançois Tigeot } 11549edbd4a0SFrançois Tigeot 115524edb884SFrançois Tigeot static int i915_pm_suspend_late(struct device *dev) 115624edb884SFrançois Tigeot { 11572c9916cdSFrançois Tigeot struct drm_device *drm_dev = dev_to_i915(dev)->dev; 115824edb884SFrançois Tigeot 115924edb884SFrançois Tigeot /* 116019c468b4SFrançois Tigeot * We have a suspend ordering issue with the snd-hda driver also 116124edb884SFrançois Tigeot * requiring our device to be power up. Due to the lack of a 116224edb884SFrançois Tigeot * parent/child relationship we currently solve this with an late 116324edb884SFrançois Tigeot * suspend hook. 116424edb884SFrançois Tigeot * 116524edb884SFrançois Tigeot * FIXME: This should be solved with a special hdmi sink device or 116624edb884SFrançois Tigeot * similar so that power domains can be employed. 116724edb884SFrançois Tigeot */ 116824edb884SFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 116924edb884SFrançois Tigeot return 0; 117024edb884SFrançois Tigeot 11712c9916cdSFrançois Tigeot return i915_drm_suspend_late(drm_dev, false); 11721b13d190SFrançois Tigeot } 117324edb884SFrançois Tigeot 11742c9916cdSFrançois Tigeot static int i915_pm_poweroff_late(struct device *dev) 11752c9916cdSFrançois Tigeot { 11762c9916cdSFrançois Tigeot struct drm_device *drm_dev = dev_to_i915(dev)->dev; 11772c9916cdSFrançois Tigeot 11782c9916cdSFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 11792c9916cdSFrançois Tigeot return 0; 11802c9916cdSFrançois Tigeot 11812c9916cdSFrançois Tigeot return i915_drm_suspend_late(drm_dev, true); 11822c9916cdSFrançois Tigeot } 11832c9916cdSFrançois Tigeot 11842c9916cdSFrançois Tigeot static int i915_pm_resume_early(struct device *dev) 11852c9916cdSFrançois Tigeot { 11862c9916cdSFrançois Tigeot struct drm_device *drm_dev = dev_to_i915(dev)->dev; 11872c9916cdSFrançois Tigeot 11882c9916cdSFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 11892c9916cdSFrançois Tigeot return 0; 11902c9916cdSFrançois Tigeot 11912c9916cdSFrançois Tigeot return i915_drm_resume_early(drm_dev); 119224edb884SFrançois Tigeot } 119324edb884SFrançois Tigeot 11949edbd4a0SFrançois Tigeot static int i915_pm_resume(struct device *dev) 11959edbd4a0SFrançois Tigeot { 11962c9916cdSFrançois Tigeot struct drm_device *drm_dev = dev_to_i915(dev)->dev; 11979edbd4a0SFrançois Tigeot 11982c9916cdSFrançois Tigeot if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) 11992c9916cdSFrançois Tigeot return 0; 12002c9916cdSFrançois Tigeot 12012c9916cdSFrançois Tigeot return i915_drm_resume(drm_dev); 12029edbd4a0SFrançois Tigeot } 12032c9916cdSFrançois Tigeot #endif 12049edbd4a0SFrançois Tigeot 1205ba55f2f5SFrançois Tigeot /* 1206ba55f2f5SFrançois Tigeot * Save all Gunit registers that may be lost after a D3 and a subsequent 1207ba55f2f5SFrançois Tigeot * S0i[R123] transition. The list of registers needing a save/restore is 1208ba55f2f5SFrançois Tigeot * defined in the VLV2_S0IXRegs document. This documents marks all Gunit 1209ba55f2f5SFrançois Tigeot * registers in the following way: 1210ba55f2f5SFrançois Tigeot * - Driver: saved/restored by the driver 1211ba55f2f5SFrançois Tigeot * - Punit : saved/restored by the Punit firmware 1212ba55f2f5SFrançois Tigeot * - No, w/o marking: no need to save/restore, since the register is R/O or 1213ba55f2f5SFrançois Tigeot * used internally by the HW in a way that doesn't depend 1214ba55f2f5SFrançois Tigeot * keeping the content across a suspend/resume. 1215ba55f2f5SFrançois Tigeot * - Debug : used for debugging 1216ba55f2f5SFrançois Tigeot * 1217ba55f2f5SFrançois Tigeot * We save/restore all registers marked with 'Driver', with the following 1218ba55f2f5SFrançois Tigeot * exceptions: 1219ba55f2f5SFrançois Tigeot * - Registers out of use, including also registers marked with 'Debug'. 1220ba55f2f5SFrançois Tigeot * These have no effect on the driver's operation, so we don't save/restore 1221ba55f2f5SFrançois Tigeot * them to reduce the overhead. 1222ba55f2f5SFrançois Tigeot * - Registers that are fully setup by an initialization function called from 1223ba55f2f5SFrançois Tigeot * the resume path. For example many clock gating and RPS/RC6 registers. 1224ba55f2f5SFrançois Tigeot * - Registers that provide the right functionality with their reset defaults. 1225ba55f2f5SFrançois Tigeot * 1226ba55f2f5SFrançois Tigeot * TODO: Except for registers that based on the above 3 criteria can be safely 1227ba55f2f5SFrançois Tigeot * ignored, we save/restore all others, practically treating the HW context as 1228ba55f2f5SFrançois Tigeot * a black-box for the driver. Further investigation is needed to reduce the 1229ba55f2f5SFrançois Tigeot * saved/restored registers even further, by following the same 3 criteria. 1230ba55f2f5SFrançois Tigeot */ 1231ba55f2f5SFrançois Tigeot static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv) 1232ba55f2f5SFrançois Tigeot { 1233ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state; 1234ba55f2f5SFrançois Tigeot int i; 1235ba55f2f5SFrançois Tigeot 1236ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */ 1237ba55f2f5SFrançois Tigeot s->wr_watermark = I915_READ(GEN7_WR_WATERMARK); 1238ba55f2f5SFrançois Tigeot s->gfx_prio_ctrl = I915_READ(GEN7_GFX_PRIO_CTRL); 1239ba55f2f5SFrançois Tigeot s->arb_mode = I915_READ(ARB_MODE); 1240ba55f2f5SFrançois Tigeot s->gfx_pend_tlb0 = I915_READ(GEN7_GFX_PEND_TLB0); 1241ba55f2f5SFrançois Tigeot s->gfx_pend_tlb1 = I915_READ(GEN7_GFX_PEND_TLB1); 1242ba55f2f5SFrançois Tigeot 1243ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) 1244352ff8bdSFrançois Tigeot s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS(i)); 1245ba55f2f5SFrançois Tigeot 1246ba55f2f5SFrançois Tigeot s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); 1247477eb7f9SFrançois Tigeot s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT); 1248ba55f2f5SFrançois Tigeot 1249ba55f2f5SFrançois Tigeot s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7); 1250ba55f2f5SFrançois Tigeot s->ecochk = I915_READ(GAM_ECOCHK); 1251ba55f2f5SFrançois Tigeot s->bsd_hwsp = I915_READ(BSD_HWS_PGA_GEN7); 1252ba55f2f5SFrançois Tigeot s->blt_hwsp = I915_READ(BLT_HWS_PGA_GEN7); 1253ba55f2f5SFrançois Tigeot 1254ba55f2f5SFrançois Tigeot s->tlb_rd_addr = I915_READ(GEN7_TLB_RD_ADDR); 1255ba55f2f5SFrançois Tigeot 1256ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */ 1257ba55f2f5SFrançois Tigeot s->g3dctl = I915_READ(VLV_G3DCTL); 1258ba55f2f5SFrançois Tigeot s->gsckgctl = I915_READ(VLV_GSCKGCTL); 1259ba55f2f5SFrançois Tigeot s->mbctl = I915_READ(GEN6_MBCTL); 1260ba55f2f5SFrançois Tigeot 1261ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */ 1262ba55f2f5SFrançois Tigeot s->ucgctl1 = I915_READ(GEN6_UCGCTL1); 1263ba55f2f5SFrançois Tigeot s->ucgctl3 = I915_READ(GEN6_UCGCTL3); 1264ba55f2f5SFrançois Tigeot s->rcgctl1 = I915_READ(GEN6_RCGCTL1); 1265ba55f2f5SFrançois Tigeot s->rcgctl2 = I915_READ(GEN6_RCGCTL2); 1266ba55f2f5SFrançois Tigeot s->rstctl = I915_READ(GEN6_RSTCTL); 1267ba55f2f5SFrançois Tigeot s->misccpctl = I915_READ(GEN7_MISCCPCTL); 1268ba55f2f5SFrançois Tigeot 1269ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */ 1270ba55f2f5SFrançois Tigeot s->gfxpause = I915_READ(GEN6_GFXPAUSE); 1271ba55f2f5SFrançois Tigeot s->rpdeuhwtc = I915_READ(GEN6_RPDEUHWTC); 1272ba55f2f5SFrançois Tigeot s->rpdeuc = I915_READ(GEN6_RPDEUC); 1273ba55f2f5SFrançois Tigeot s->ecobus = I915_READ(ECOBUS); 1274ba55f2f5SFrançois Tigeot s->pwrdwnupctl = I915_READ(VLV_PWRDWNUPCTL); 1275ba55f2f5SFrançois Tigeot s->rp_down_timeout = I915_READ(GEN6_RP_DOWN_TIMEOUT); 1276ba55f2f5SFrançois Tigeot s->rp_deucsw = I915_READ(GEN6_RPDEUCSW); 1277ba55f2f5SFrançois Tigeot s->rcubmabdtmr = I915_READ(GEN6_RCUBMABDTMR); 1278ba55f2f5SFrançois Tigeot s->rcedata = I915_READ(VLV_RCEDATA); 1279ba55f2f5SFrançois Tigeot s->spare2gh = I915_READ(VLV_SPAREG2H); 1280ba55f2f5SFrançois Tigeot 1281ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */ 1282ba55f2f5SFrançois Tigeot s->gt_imr = I915_READ(GTIMR); 1283ba55f2f5SFrançois Tigeot s->gt_ier = I915_READ(GTIER); 1284ba55f2f5SFrançois Tigeot s->pm_imr = I915_READ(GEN6_PMIMR); 1285ba55f2f5SFrançois Tigeot s->pm_ier = I915_READ(GEN6_PMIER); 1286ba55f2f5SFrançois Tigeot 1287ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) 1288352ff8bdSFrançois Tigeot s->gt_scratch[i] = I915_READ(GEN7_GT_SCRATCH(i)); 1289ba55f2f5SFrançois Tigeot 1290ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */ 1291ba55f2f5SFrançois Tigeot s->tilectl = I915_READ(TILECTL); 1292ba55f2f5SFrançois Tigeot s->gt_fifoctl = I915_READ(GTFIFOCTL); 1293ba55f2f5SFrançois Tigeot s->gtlc_wake_ctrl = I915_READ(VLV_GTLC_WAKE_CTRL); 1294ba55f2f5SFrançois Tigeot s->gtlc_survive = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1295ba55f2f5SFrançois Tigeot s->pmwgicz = I915_READ(VLV_PMWGICZ); 1296ba55f2f5SFrançois Tigeot 1297ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */ 1298ba55f2f5SFrançois Tigeot s->gu_ctl0 = I915_READ(VLV_GU_CTL0); 1299ba55f2f5SFrançois Tigeot s->gu_ctl1 = I915_READ(VLV_GU_CTL1); 13002c9916cdSFrançois Tigeot s->pcbr = I915_READ(VLV_PCBR); 1301ba55f2f5SFrançois Tigeot s->clock_gate_dis2 = I915_READ(VLV_GUNIT_CLOCK_GATE2); 1302ba55f2f5SFrançois Tigeot 1303ba55f2f5SFrançois Tigeot /* 1304ba55f2f5SFrançois Tigeot * Not saving any of: 1305ba55f2f5SFrançois Tigeot * DFT, 0x9800-0x9EC0 1306ba55f2f5SFrançois Tigeot * SARB, 0xB000-0xB1FC 1307ba55f2f5SFrançois Tigeot * GAC, 0x5208-0x524C, 0x14000-0x14C000 1308ba55f2f5SFrançois Tigeot * PCI CFG 1309ba55f2f5SFrançois Tigeot */ 1310ba55f2f5SFrançois Tigeot } 1311ba55f2f5SFrançois Tigeot 1312ba55f2f5SFrançois Tigeot static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) 1313ba55f2f5SFrançois Tigeot { 1314ba55f2f5SFrançois Tigeot struct vlv_s0ix_state *s = &dev_priv->vlv_s0ix_state; 1315ba55f2f5SFrançois Tigeot u32 val; 1316ba55f2f5SFrançois Tigeot int i; 1317ba55f2f5SFrançois Tigeot 1318ba55f2f5SFrançois Tigeot /* GAM 0x4000-0x4770 */ 1319ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_WR_WATERMARK, s->wr_watermark); 1320ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PRIO_CTRL, s->gfx_prio_ctrl); 1321ba55f2f5SFrançois Tigeot I915_WRITE(ARB_MODE, s->arb_mode | (0xffff << 16)); 1322ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB0, s->gfx_pend_tlb0); 1323ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_GFX_PEND_TLB1, s->gfx_pend_tlb1); 1324ba55f2f5SFrançois Tigeot 1325ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->lra_limits); i++) 1326352ff8bdSFrançois Tigeot I915_WRITE(GEN7_LRA_LIMITS(i), s->lra_limits[i]); 1327ba55f2f5SFrançois Tigeot 1328ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); 1329477eb7f9SFrançois Tigeot I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count); 1330ba55f2f5SFrançois Tigeot 1331ba55f2f5SFrançois Tigeot I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); 1332ba55f2f5SFrançois Tigeot I915_WRITE(GAM_ECOCHK, s->ecochk); 1333ba55f2f5SFrançois Tigeot I915_WRITE(BSD_HWS_PGA_GEN7, s->bsd_hwsp); 1334ba55f2f5SFrançois Tigeot I915_WRITE(BLT_HWS_PGA_GEN7, s->blt_hwsp); 1335ba55f2f5SFrançois Tigeot 1336ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_TLB_RD_ADDR, s->tlb_rd_addr); 1337ba55f2f5SFrançois Tigeot 1338ba55f2f5SFrançois Tigeot /* MBC 0x9024-0x91D0, 0x8500 */ 1339ba55f2f5SFrançois Tigeot I915_WRITE(VLV_G3DCTL, s->g3dctl); 1340ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GSCKGCTL, s->gsckgctl); 1341ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_MBCTL, s->mbctl); 1342ba55f2f5SFrançois Tigeot 1343ba55f2f5SFrançois Tigeot /* GCP 0x9400-0x9424, 0x8100-0x810C */ 1344ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL1, s->ucgctl1); 1345ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_UCGCTL3, s->ucgctl3); 1346ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL1, s->rcgctl1); 1347ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCGCTL2, s->rcgctl2); 1348ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RSTCTL, s->rstctl); 1349ba55f2f5SFrançois Tigeot I915_WRITE(GEN7_MISCCPCTL, s->misccpctl); 1350ba55f2f5SFrançois Tigeot 1351ba55f2f5SFrançois Tigeot /* GPM 0xA000-0xAA84, 0x8000-0x80FC */ 1352ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_GFXPAUSE, s->gfxpause); 1353ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUHWTC, s->rpdeuhwtc); 1354ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUC, s->rpdeuc); 1355ba55f2f5SFrançois Tigeot I915_WRITE(ECOBUS, s->ecobus); 1356ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PWRDWNUPCTL, s->pwrdwnupctl); 1357ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RP_DOWN_TIMEOUT,s->rp_down_timeout); 1358ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RPDEUCSW, s->rp_deucsw); 1359ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_RCUBMABDTMR, s->rcubmabdtmr); 1360ba55f2f5SFrançois Tigeot I915_WRITE(VLV_RCEDATA, s->rcedata); 1361ba55f2f5SFrançois Tigeot I915_WRITE(VLV_SPAREG2H, s->spare2gh); 1362ba55f2f5SFrançois Tigeot 1363ba55f2f5SFrançois Tigeot /* Display CZ domain, 0x4400C-0x4402C, 0x4F000-0x4F11F */ 1364ba55f2f5SFrançois Tigeot I915_WRITE(GTIMR, s->gt_imr); 1365ba55f2f5SFrançois Tigeot I915_WRITE(GTIER, s->gt_ier); 1366ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIMR, s->pm_imr); 1367ba55f2f5SFrançois Tigeot I915_WRITE(GEN6_PMIER, s->pm_ier); 1368ba55f2f5SFrançois Tigeot 1369ba55f2f5SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(s->gt_scratch); i++) 1370352ff8bdSFrançois Tigeot I915_WRITE(GEN7_GT_SCRATCH(i), s->gt_scratch[i]); 1371ba55f2f5SFrançois Tigeot 1372ba55f2f5SFrançois Tigeot /* GT SA CZ domain, 0x100000-0x138124 */ 1373ba55f2f5SFrançois Tigeot I915_WRITE(TILECTL, s->tilectl); 1374ba55f2f5SFrançois Tigeot I915_WRITE(GTFIFOCTL, s->gt_fifoctl); 1375ba55f2f5SFrançois Tigeot /* 1376ba55f2f5SFrançois Tigeot * Preserve the GT allow wake and GFX force clock bit, they are not 1377ba55f2f5SFrançois Tigeot * be restored, as they are used to control the s0ix suspend/resume 1378ba55f2f5SFrançois Tigeot * sequence by the caller. 1379ba55f2f5SFrançois Tigeot */ 1380ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL); 1381ba55f2f5SFrançois Tigeot val &= VLV_GTLC_ALLOWWAKEREQ; 1382ba55f2f5SFrançois Tigeot val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ; 1383ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val); 1384ba55f2f5SFrançois Tigeot 1385ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1386ba55f2f5SFrançois Tigeot val &= VLV_GFX_CLK_FORCE_ON_BIT; 1387ba55f2f5SFrançois Tigeot val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT; 1388ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); 1389ba55f2f5SFrançois Tigeot 1390ba55f2f5SFrançois Tigeot I915_WRITE(VLV_PMWGICZ, s->pmwgicz); 1391ba55f2f5SFrançois Tigeot 1392ba55f2f5SFrançois Tigeot /* Gunit-Display CZ domain, 0x182028-0x1821CF */ 1393ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL0, s->gu_ctl0); 1394ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GU_CTL1, s->gu_ctl1); 13952c9916cdSFrançois Tigeot I915_WRITE(VLV_PCBR, s->pcbr); 1396ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GUNIT_CLOCK_GATE2, s->clock_gate_dis2); 1397ba55f2f5SFrançois Tigeot } 1398ba55f2f5SFrançois Tigeot 1399ba55f2f5SFrançois Tigeot int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) 1400ba55f2f5SFrançois Tigeot { 1401ba55f2f5SFrançois Tigeot u32 val; 1402ba55f2f5SFrançois Tigeot int err; 1403ba55f2f5SFrançois Tigeot 1404ba55f2f5SFrançois Tigeot #define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT) 1405ba55f2f5SFrançois Tigeot 1406ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); 1407ba55f2f5SFrançois Tigeot val &= ~VLV_GFX_CLK_FORCE_ON_BIT; 1408ba55f2f5SFrançois Tigeot if (force_on) 1409ba55f2f5SFrançois Tigeot val |= VLV_GFX_CLK_FORCE_ON_BIT; 1410ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_SURVIVABILITY_REG, val); 1411ba55f2f5SFrançois Tigeot 1412ba55f2f5SFrançois Tigeot if (!force_on) 1413ba55f2f5SFrançois Tigeot return 0; 1414ba55f2f5SFrançois Tigeot 1415ba55f2f5SFrançois Tigeot err = wait_for(COND, 20); 1416ba55f2f5SFrançois Tigeot if (err) 1417ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n", 1418ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_SURVIVABILITY_REG)); 1419ba55f2f5SFrançois Tigeot 1420ba55f2f5SFrançois Tigeot return err; 1421ba55f2f5SFrançois Tigeot #undef COND 1422ba55f2f5SFrançois Tigeot } 1423ba55f2f5SFrançois Tigeot 1424ba55f2f5SFrançois Tigeot static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow) 1425ba55f2f5SFrançois Tigeot { 1426ba55f2f5SFrançois Tigeot u32 val; 1427ba55f2f5SFrançois Tigeot int err = 0; 1428ba55f2f5SFrançois Tigeot 1429ba55f2f5SFrançois Tigeot val = I915_READ(VLV_GTLC_WAKE_CTRL); 1430ba55f2f5SFrançois Tigeot val &= ~VLV_GTLC_ALLOWWAKEREQ; 1431ba55f2f5SFrançois Tigeot if (allow) 1432ba55f2f5SFrançois Tigeot val |= VLV_GTLC_ALLOWWAKEREQ; 1433ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_WAKE_CTRL, val); 1434ba55f2f5SFrançois Tigeot POSTING_READ(VLV_GTLC_WAKE_CTRL); 1435ba55f2f5SFrançois Tigeot 1436ba55f2f5SFrançois Tigeot #define COND (!!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEACK) == \ 1437ba55f2f5SFrançois Tigeot allow) 1438ba55f2f5SFrançois Tigeot err = wait_for(COND, 1); 1439ba55f2f5SFrançois Tigeot if (err) 1440ba55f2f5SFrançois Tigeot DRM_ERROR("timeout disabling GT waking\n"); 1441ba55f2f5SFrançois Tigeot return err; 1442ba55f2f5SFrançois Tigeot #undef COND 1443ba55f2f5SFrançois Tigeot } 1444ba55f2f5SFrançois Tigeot 1445ba55f2f5SFrançois Tigeot static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, 1446ba55f2f5SFrançois Tigeot bool wait_for_on) 1447ba55f2f5SFrançois Tigeot { 1448ba55f2f5SFrançois Tigeot u32 mask; 1449ba55f2f5SFrançois Tigeot u32 val; 1450ba55f2f5SFrançois Tigeot int err; 1451ba55f2f5SFrançois Tigeot 1452ba55f2f5SFrançois Tigeot mask = VLV_GTLC_PW_MEDIA_STATUS_MASK | VLV_GTLC_PW_RENDER_STATUS_MASK; 1453ba55f2f5SFrançois Tigeot val = wait_for_on ? mask : 0; 1454ba55f2f5SFrançois Tigeot #define COND ((I915_READ(VLV_GTLC_PW_STATUS) & mask) == val) 1455ba55f2f5SFrançois Tigeot if (COND) 1456ba55f2f5SFrançois Tigeot return 0; 1457ba55f2f5SFrançois Tigeot 1458ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("waiting for GT wells to go %s (%08x)\n", 1459c0e85e96SFrançois Tigeot onoff(wait_for_on), 1460ba55f2f5SFrançois Tigeot I915_READ(VLV_GTLC_PW_STATUS)); 1461ba55f2f5SFrançois Tigeot 1462ba55f2f5SFrançois Tigeot /* 1463ba55f2f5SFrançois Tigeot * RC6 transitioning can be delayed up to 2 msec (see 1464ba55f2f5SFrançois Tigeot * valleyview_enable_rps), use 3 msec for safety. 1465ba55f2f5SFrançois Tigeot */ 1466ba55f2f5SFrançois Tigeot err = wait_for(COND, 3); 1467ba55f2f5SFrançois Tigeot if (err) 1468ba55f2f5SFrançois Tigeot DRM_ERROR("timeout waiting for GT wells to go %s\n", 1469c0e85e96SFrançois Tigeot onoff(wait_for_on)); 1470ba55f2f5SFrançois Tigeot 1471ba55f2f5SFrançois Tigeot return err; 1472ba55f2f5SFrançois Tigeot #undef COND 1473ba55f2f5SFrançois Tigeot } 1474ba55f2f5SFrançois Tigeot 1475ba55f2f5SFrançois Tigeot static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) 1476ba55f2f5SFrançois Tigeot { 1477ba55f2f5SFrançois Tigeot if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR)) 1478ba55f2f5SFrançois Tigeot return; 1479ba55f2f5SFrançois Tigeot 1480c0e85e96SFrançois Tigeot DRM_DEBUG_DRIVER("GT register access while GT waking disabled\n"); 1481ba55f2f5SFrançois Tigeot I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); 1482ba55f2f5SFrançois Tigeot } 1483ba55f2f5SFrançois Tigeot 14841b13d190SFrançois Tigeot static int vlv_suspend_complete(struct drm_i915_private *dev_priv) 1485ba55f2f5SFrançois Tigeot { 1486ba55f2f5SFrançois Tigeot u32 mask; 1487ba55f2f5SFrançois Tigeot int err; 1488ba55f2f5SFrançois Tigeot 1489ba55f2f5SFrançois Tigeot /* 1490ba55f2f5SFrançois Tigeot * Bspec defines the following GT well on flags as debug only, so 1491ba55f2f5SFrançois Tigeot * don't treat them as hard failures. 1492ba55f2f5SFrançois Tigeot */ 1493ba55f2f5SFrançois Tigeot (void)vlv_wait_for_gt_wells(dev_priv, false); 1494ba55f2f5SFrançois Tigeot 1495ba55f2f5SFrançois Tigeot mask = VLV_GTLC_RENDER_CTX_EXISTS | VLV_GTLC_MEDIA_CTX_EXISTS; 1496ba55f2f5SFrançois Tigeot WARN_ON((I915_READ(VLV_GTLC_WAKE_CTRL) & mask) != mask); 1497ba55f2f5SFrançois Tigeot 1498ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv); 1499ba55f2f5SFrançois Tigeot 1500ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, true); 1501ba55f2f5SFrançois Tigeot if (err) 1502ba55f2f5SFrançois Tigeot goto err1; 1503ba55f2f5SFrançois Tigeot 1504ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, false); 1505ba55f2f5SFrançois Tigeot if (err) 1506ba55f2f5SFrançois Tigeot goto err2; 15072c9916cdSFrançois Tigeot 15088621f407SFrançois Tigeot if (!IS_CHERRYVIEW(dev_priv)) 1509ba55f2f5SFrançois Tigeot vlv_save_gunit_s0ix_state(dev_priv); 1510ba55f2f5SFrançois Tigeot 1511ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false); 1512ba55f2f5SFrançois Tigeot if (err) 1513ba55f2f5SFrançois Tigeot goto err2; 1514ba55f2f5SFrançois Tigeot 1515ba55f2f5SFrançois Tigeot return 0; 1516ba55f2f5SFrançois Tigeot 1517ba55f2f5SFrançois Tigeot err2: 1518ba55f2f5SFrançois Tigeot /* For safety always re-enable waking and disable gfx clock forcing */ 1519ba55f2f5SFrançois Tigeot vlv_allow_gt_wake(dev_priv, true); 1520ba55f2f5SFrançois Tigeot err1: 1521ba55f2f5SFrançois Tigeot vlv_force_gfx_clock(dev_priv, false); 1522ba55f2f5SFrançois Tigeot 1523ba55f2f5SFrançois Tigeot return err; 1524ba55f2f5SFrançois Tigeot } 1525ba55f2f5SFrançois Tigeot 15261b13d190SFrançois Tigeot static int vlv_resume_prepare(struct drm_i915_private *dev_priv, 15271b13d190SFrançois Tigeot bool rpm_resume) 1528ba55f2f5SFrançois Tigeot { 1529ba55f2f5SFrançois Tigeot struct drm_device *dev = dev_priv->dev; 1530ba55f2f5SFrançois Tigeot int err; 1531ba55f2f5SFrançois Tigeot int ret; 1532ba55f2f5SFrançois Tigeot 1533ba55f2f5SFrançois Tigeot /* 1534ba55f2f5SFrançois Tigeot * If any of the steps fail just try to continue, that's the best we 1535ba55f2f5SFrançois Tigeot * can do at this point. Return the first error code (which will also 1536ba55f2f5SFrançois Tigeot * leave RPM permanently disabled). 1537ba55f2f5SFrançois Tigeot */ 1538ba55f2f5SFrançois Tigeot ret = vlv_force_gfx_clock(dev_priv, true); 1539ba55f2f5SFrançois Tigeot 15408621f407SFrançois Tigeot if (!IS_CHERRYVIEW(dev_priv)) 1541ba55f2f5SFrançois Tigeot vlv_restore_gunit_s0ix_state(dev_priv); 1542ba55f2f5SFrançois Tigeot 1543ba55f2f5SFrançois Tigeot err = vlv_allow_gt_wake(dev_priv, true); 1544ba55f2f5SFrançois Tigeot if (!ret) 1545ba55f2f5SFrançois Tigeot ret = err; 1546ba55f2f5SFrançois Tigeot 1547ba55f2f5SFrançois Tigeot err = vlv_force_gfx_clock(dev_priv, false); 1548ba55f2f5SFrançois Tigeot if (!ret) 1549ba55f2f5SFrançois Tigeot ret = err; 1550ba55f2f5SFrançois Tigeot 1551ba55f2f5SFrançois Tigeot vlv_check_no_gt_access(dev_priv); 1552ba55f2f5SFrançois Tigeot 15531b13d190SFrançois Tigeot if (rpm_resume) { 1554ba55f2f5SFrançois Tigeot intel_init_clock_gating(dev); 1555ba55f2f5SFrançois Tigeot i915_gem_restore_fences(dev); 15561b13d190SFrançois Tigeot } 1557ba55f2f5SFrançois Tigeot 1558ba55f2f5SFrançois Tigeot return ret; 1559ba55f2f5SFrançois Tigeot } 1560ba55f2f5SFrançois Tigeot 15612c9916cdSFrançois Tigeot #if 0 1562ba55f2f5SFrançois Tigeot static int intel_runtime_suspend(struct device *device) 15639edbd4a0SFrançois Tigeot { 15649edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(device); 15659edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 15669edbd4a0SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 1567ba55f2f5SFrançois Tigeot int ret; 1568ba55f2f5SFrançois Tigeot 1569ba55f2f5SFrançois Tigeot if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev)))) 1570ba55f2f5SFrançois Tigeot return -ENODEV; 15719edbd4a0SFrançois Tigeot 15721b13d190SFrançois Tigeot if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev))) 15731b13d190SFrançois Tigeot return -ENODEV; 15741b13d190SFrançois Tigeot 15759edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Suspending device\n"); 15769edbd4a0SFrançois Tigeot 1577ba55f2f5SFrançois Tigeot /* 1578ba55f2f5SFrançois Tigeot * We could deadlock here in case another thread holding struct_mutex 1579ba55f2f5SFrançois Tigeot * calls RPM suspend concurrently, since the RPM suspend will wait 1580ba55f2f5SFrançois Tigeot * first for this RPM suspend to finish. In this case the concurrent 1581ba55f2f5SFrançois Tigeot * RPM resume will be followed by its RPM suspend counterpart. Still 1582ba55f2f5SFrançois Tigeot * for consistency return -EAGAIN, which will reschedule this suspend. 1583ba55f2f5SFrançois Tigeot */ 1584ba55f2f5SFrançois Tigeot if (!mutex_trylock(&dev->struct_mutex)) { 1585ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("device lock contention, deffering suspend\n"); 1586ba55f2f5SFrançois Tigeot /* 1587ba55f2f5SFrançois Tigeot * Bump the expiration timestamp, otherwise the suspend won't 1588ba55f2f5SFrançois Tigeot * be rescheduled. 1589ba55f2f5SFrançois Tigeot */ 1590ba55f2f5SFrançois Tigeot pm_runtime_mark_last_busy(device); 1591ba55f2f5SFrançois Tigeot 1592ba55f2f5SFrançois Tigeot return -EAGAIN; 1593ba55f2f5SFrançois Tigeot } 1594aee94f86SFrançois Tigeot 1595aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 1596aee94f86SFrançois Tigeot 1597ba55f2f5SFrançois Tigeot /* 1598ba55f2f5SFrançois Tigeot * We are safe here against re-faults, since the fault handler takes 1599ba55f2f5SFrançois Tigeot * an RPM reference. 1600ba55f2f5SFrançois Tigeot */ 16019edbd4a0SFrançois Tigeot i915_gem_release_all_mmaps(dev_priv); 1602ba55f2f5SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 1603ba55f2f5SFrançois Tigeot 1604aee94f86SFrançois Tigeot cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); 1605aee94f86SFrançois Tigeot 1606352ff8bdSFrançois Tigeot intel_guc_suspend(dev); 1607352ff8bdSFrançois Tigeot 16082c9916cdSFrançois Tigeot intel_suspend_gt_powersave(dev); 16092c9916cdSFrançois Tigeot intel_runtime_pm_disable_interrupts(dev_priv); 1610ba55f2f5SFrançois Tigeot 16118621f407SFrançois Tigeot ret = 0; 16128621f407SFrançois Tigeot if (IS_BROXTON(dev_priv)) { 16138621f407SFrançois Tigeot bxt_display_core_uninit(dev_priv); 16148621f407SFrançois Tigeot bxt_enable_dc9(dev_priv); 16158621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 16168621f407SFrançois Tigeot hsw_enable_pc8(dev_priv); 16178621f407SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 16188621f407SFrançois Tigeot ret = vlv_suspend_complete(dev_priv); 16198621f407SFrançois Tigeot } 16208621f407SFrançois Tigeot 1621ba55f2f5SFrançois Tigeot if (ret) { 1622ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); 16232c9916cdSFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv); 1624ba55f2f5SFrançois Tigeot 1625aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 1626aee94f86SFrançois Tigeot 1627ba55f2f5SFrançois Tigeot return ret; 1628ba55f2f5SFrançois Tigeot } 16299edbd4a0SFrançois Tigeot 16302c9916cdSFrançois Tigeot intel_uncore_forcewake_reset(dev, false); 1631aee94f86SFrançois Tigeot 1632aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 1633aee94f86SFrançois Tigeot WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); 1634c0e85e96SFrançois Tigeot 1635c0e85e96SFrançois Tigeot if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv)) 1636c0e85e96SFrançois Tigeot DRM_ERROR("Unclaimed access detected prior to suspending\n"); 1637c0e85e96SFrançois Tigeot 16389edbd4a0SFrançois Tigeot dev_priv->pm.suspended = true; 16399edbd4a0SFrançois Tigeot 16409edbd4a0SFrançois Tigeot /* 16411b13d190SFrançois Tigeot * FIXME: We really should find a document that references the arguments 16421b13d190SFrançois Tigeot * used below! 16431b13d190SFrançois Tigeot */ 1644a05eeebfSFrançois Tigeot if (IS_BROADWELL(dev)) { 1645a05eeebfSFrançois Tigeot /* 1646a05eeebfSFrançois Tigeot * On Broadwell, if we use PCI_D1 the PCH DDI ports will stop 1647a05eeebfSFrançois Tigeot * being detected, and the call we do at intel_runtime_resume() 1648a05eeebfSFrançois Tigeot * won't be able to restore them. Since PCI_D3hot matches the 1649a05eeebfSFrançois Tigeot * actual specification and appears to be working, use it. 1650a05eeebfSFrançois Tigeot */ 1651a05eeebfSFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D3hot); 1652a05eeebfSFrançois Tigeot } else { 16531b13d190SFrançois Tigeot /* 16549edbd4a0SFrançois Tigeot * current versions of firmware which depend on this opregion 16559edbd4a0SFrançois Tigeot * notification have repurposed the D1 definition to mean 16569edbd4a0SFrançois Tigeot * "runtime suspended" vs. what you would normally expect (D3) 16571b13d190SFrançois Tigeot * to distinguish it from notifications that might be sent via 16581b13d190SFrançois Tigeot * the suspend path. 16599edbd4a0SFrançois Tigeot */ 16609edbd4a0SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D1); 16611b13d190SFrançois Tigeot } 16629edbd4a0SFrançois Tigeot 16632c9916cdSFrançois Tigeot assert_forcewakes_inactive(dev_priv); 16642c9916cdSFrançois Tigeot 16658621f407SFrançois Tigeot if (!IS_VALLEYVIEW(dev_priv) || !IS_CHERRYVIEW(dev_priv)) 16668621f407SFrançois Tigeot intel_hpd_poll_init(dev_priv); 16678621f407SFrançois Tigeot 1668ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device suspended\n"); 16699edbd4a0SFrançois Tigeot return 0; 16709edbd4a0SFrançois Tigeot } 16719edbd4a0SFrançois Tigeot 1672ba55f2f5SFrançois Tigeot static int intel_runtime_resume(struct device *device) 16739edbd4a0SFrançois Tigeot { 16749edbd4a0SFrançois Tigeot struct pci_dev *pdev = to_pci_dev(device); 16759edbd4a0SFrançois Tigeot struct drm_device *dev = pci_get_drvdata(pdev); 16769edbd4a0SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 16772c9916cdSFrançois Tigeot int ret = 0; 16789edbd4a0SFrançois Tigeot 16791b13d190SFrançois Tigeot if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev))) 16801b13d190SFrançois Tigeot return -ENODEV; 16819edbd4a0SFrançois Tigeot 16829edbd4a0SFrançois Tigeot DRM_DEBUG_KMS("Resuming device\n"); 16839edbd4a0SFrançois Tigeot 1684aee94f86SFrançois Tigeot WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); 1685aee94f86SFrançois Tigeot disable_rpm_wakeref_asserts(dev_priv); 1686aee94f86SFrançois Tigeot 16879edbd4a0SFrançois Tigeot intel_opregion_notify_adapter(dev, PCI_D0); 16889edbd4a0SFrançois Tigeot dev_priv->pm.suspended = false; 1689c0e85e96SFrançois Tigeot if (intel_uncore_unclaimed_mmio(dev_priv)) 1690c0e85e96SFrançois Tigeot DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n"); 16919edbd4a0SFrançois Tigeot 1692352ff8bdSFrançois Tigeot intel_guc_resume(dev); 1693352ff8bdSFrançois Tigeot 16942c9916cdSFrançois Tigeot if (IS_GEN6(dev_priv)) 16952c9916cdSFrançois Tigeot intel_init_pch_refclk(dev); 169619c468b4SFrançois Tigeot 16978621f407SFrançois Tigeot if (IS_BROXTON(dev)) { 16988621f407SFrançois Tigeot bxt_disable_dc9(dev_priv); 16998621f407SFrançois Tigeot bxt_display_core_init(dev_priv, true); 17008621f407SFrançois Tigeot if (dev_priv->csr.dmc_payload && 17018621f407SFrançois Tigeot (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)) 17028621f407SFrançois Tigeot gen9_enable_dc5(dev_priv); 17038621f407SFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 17042c9916cdSFrançois Tigeot hsw_disable_pc8(dev_priv); 17058621f407SFrançois Tigeot } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 17062c9916cdSFrançois Tigeot ret = vlv_resume_prepare(dev_priv, true); 17078621f407SFrançois Tigeot } 17082c9916cdSFrançois Tigeot 1709ba55f2f5SFrançois Tigeot /* 1710ba55f2f5SFrançois Tigeot * No point of rolling back things in case of an error, as the best 1711ba55f2f5SFrançois Tigeot * we can do is to hope that things will still work (and disable RPM). 1712ba55f2f5SFrançois Tigeot */ 1713ba55f2f5SFrançois Tigeot i915_gem_init_swizzling(dev); 1714ba55f2f5SFrançois Tigeot gen6_update_ring_freq(dev); 1715ba55f2f5SFrançois Tigeot 17162c9916cdSFrançois Tigeot intel_runtime_pm_enable_interrupts(dev_priv); 1717352ff8bdSFrançois Tigeot 1718352ff8bdSFrançois Tigeot /* 1719352ff8bdSFrançois Tigeot * On VLV/CHV display interrupts are part of the display 1720352ff8bdSFrançois Tigeot * power well, so hpd is reinitialized from there. For 1721352ff8bdSFrançois Tigeot * everyone else do it here. 1722352ff8bdSFrançois Tigeot */ 1723aee94f86SFrançois Tigeot if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) 1724352ff8bdSFrançois Tigeot intel_hpd_init(dev_priv); 1725352ff8bdSFrançois Tigeot 17262c9916cdSFrançois Tigeot intel_enable_gt_powersave(dev); 1727ba55f2f5SFrançois Tigeot 1728aee94f86SFrançois Tigeot enable_rpm_wakeref_asserts(dev_priv); 1729aee94f86SFrançois Tigeot 1730ba55f2f5SFrançois Tigeot if (ret) 1731ba55f2f5SFrançois Tigeot DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret); 1732ba55f2f5SFrançois Tigeot else 1733ba55f2f5SFrançois Tigeot DRM_DEBUG_KMS("Device resumed\n"); 1734ba55f2f5SFrançois Tigeot 1735ba55f2f5SFrançois Tigeot return ret; 17369edbd4a0SFrançois Tigeot } 17379edbd4a0SFrançois Tigeot 17389edbd4a0SFrançois Tigeot static const struct dev_pm_ops i915_pm_ops = { 17392c9916cdSFrançois Tigeot /* 17402c9916cdSFrançois Tigeot * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND, 17412c9916cdSFrançois Tigeot * PMSG_RESUME] 17422c9916cdSFrançois Tigeot */ 17439edbd4a0SFrançois Tigeot .suspend = i915_pm_suspend, 17442c9916cdSFrançois Tigeot .suspend_late = i915_pm_suspend_late, 17452c9916cdSFrançois Tigeot .resume_early = i915_pm_resume_early, 17469edbd4a0SFrançois Tigeot .resume = i915_pm_resume, 17472c9916cdSFrançois Tigeot 17482c9916cdSFrançois Tigeot /* 17492c9916cdSFrançois Tigeot * S4 event handlers 17502c9916cdSFrançois Tigeot * @freeze, @freeze_late : called (1) before creating the 17512c9916cdSFrançois Tigeot * hibernation image [PMSG_FREEZE] and 17522c9916cdSFrançois Tigeot * (2) after rebooting, before restoring 17532c9916cdSFrançois Tigeot * the image [PMSG_QUIESCE] 17542c9916cdSFrançois Tigeot * @thaw, @thaw_early : called (1) after creating the hibernation 17552c9916cdSFrançois Tigeot * image, before writing it [PMSG_THAW] 17562c9916cdSFrançois Tigeot * and (2) after failing to create or 17572c9916cdSFrançois Tigeot * restore the image [PMSG_RECOVER] 17582c9916cdSFrançois Tigeot * @poweroff, @poweroff_late: called after writing the hibernation 17592c9916cdSFrançois Tigeot * image, before rebooting [PMSG_HIBERNATE] 17602c9916cdSFrançois Tigeot * @restore, @restore_early : called after rebooting and restoring the 17612c9916cdSFrançois Tigeot * hibernation image [PMSG_RESTORE] 17622c9916cdSFrançois Tigeot */ 17632c9916cdSFrançois Tigeot .freeze = i915_pm_suspend, 17642c9916cdSFrançois Tigeot .freeze_late = i915_pm_suspend_late, 17652c9916cdSFrançois Tigeot .thaw_early = i915_pm_resume_early, 17662c9916cdSFrançois Tigeot .thaw = i915_pm_resume, 17672c9916cdSFrançois Tigeot .poweroff = i915_pm_suspend, 17682c9916cdSFrançois Tigeot .poweroff_late = i915_pm_poweroff_late, 17692c9916cdSFrançois Tigeot .restore_early = i915_pm_resume_early, 17709edbd4a0SFrançois Tigeot .restore = i915_pm_resume, 17712c9916cdSFrançois Tigeot 17722c9916cdSFrançois Tigeot /* S0ix (via runtime suspend) event handlers */ 1773ba55f2f5SFrançois Tigeot .runtime_suspend = intel_runtime_suspend, 1774ba55f2f5SFrançois Tigeot .runtime_resume = intel_runtime_resume, 17759edbd4a0SFrançois Tigeot }; 17769edbd4a0SFrançois Tigeot 17779edbd4a0SFrançois Tigeot static const struct vm_operations_struct i915_gem_vm_ops = { 17789edbd4a0SFrançois Tigeot .fault = i915_gem_fault, 17799edbd4a0SFrançois Tigeot .open = drm_gem_vm_open, 17809edbd4a0SFrançois Tigeot .close = drm_gem_vm_close, 17819edbd4a0SFrançois Tigeot }; 1782*922e7c40SFrançois Tigeot #endif 17839edbd4a0SFrançois Tigeot 17849edbd4a0SFrançois Tigeot static const struct file_operations i915_driver_fops = { 17859edbd4a0SFrançois Tigeot .owner = THIS_MODULE, 1786*922e7c40SFrançois Tigeot #if 0 17879edbd4a0SFrançois Tigeot .open = drm_open, 17889edbd4a0SFrançois Tigeot .release = drm_release, 17899edbd4a0SFrançois Tigeot .unlocked_ioctl = drm_ioctl, 17909edbd4a0SFrançois Tigeot .mmap = drm_gem_mmap, 17919edbd4a0SFrançois Tigeot .poll = drm_poll, 17929edbd4a0SFrançois Tigeot .read = drm_read, 17939edbd4a0SFrançois Tigeot #ifdef CONFIG_COMPAT 17949edbd4a0SFrançois Tigeot .compat_ioctl = i915_compat_ioctl, 17959edbd4a0SFrançois Tigeot #endif 17969edbd4a0SFrançois Tigeot .llseek = noop_llseek, 17979edbd4a0SFrançois Tigeot #endif 1798*922e7c40SFrançois Tigeot }; 17999edbd4a0SFrançois Tigeot 1800e9587a4eSFrançois Tigeot static struct cdev_pager_ops i915_gem_vm_ops = { 1801e9587a4eSFrançois Tigeot .cdev_pg_fault = i915_gem_fault, 1802e9587a4eSFrançois Tigeot .cdev_pg_ctor = i915_gem_pager_ctor, 1803e9587a4eSFrançois Tigeot .cdev_pg_dtor = i915_gem_pager_dtor 1804e9587a4eSFrançois Tigeot }; 1805e9587a4eSFrançois Tigeot 1806f0b54121SFrançois Tigeot static struct drm_driver driver = { 18079edbd4a0SFrançois Tigeot /* Don't use MTRRs here; the Xserver or userspace app should 18089edbd4a0SFrançois Tigeot * deal with them for Intel hardware. 18099edbd4a0SFrançois Tigeot */ 18109edbd4a0SFrançois Tigeot .driver_features = 181163a4d045SFrançois Tigeot DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | 1812352ff8bdSFrançois Tigeot DRIVER_RENDER | DRIVER_MODESET, 1813f0b54121SFrançois Tigeot .load = i915_driver_load, 181479f713b0SFrançois Tigeot .unload = i915_driver_unload, 1815ba55f2f5SFrançois Tigeot .open = i915_driver_open, 181679f713b0SFrançois Tigeot .lastclose = i915_driver_lastclose, 1817ba55f2f5SFrançois Tigeot .preclose = i915_driver_preclose, 1818f0b54121SFrançois Tigeot .postclose = i915_driver_postclose, 1819*922e7c40SFrançois Tigeot .set_busid = drm_pci_set_busid, 1820ba55f2f5SFrançois Tigeot 18212c9916cdSFrançois Tigeot #if defined(CONFIG_DEBUG_FS) 18222c9916cdSFrançois Tigeot .debugfs_init = i915_debugfs_init, 18232c9916cdSFrançois Tigeot .debugfs_cleanup = i915_debugfs_cleanup, 18242c9916cdSFrançois Tigeot #endif 1825f0b54121SFrançois Tigeot .gem_free_object = i915_gem_free_object, 1826d4d73b30SFrançois Tigeot .gem_vm_ops = &i915_gem_vm_ops, 18272c9916cdSFrançois Tigeot 1828*922e7c40SFrançois Tigeot .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 1829*922e7c40SFrançois Tigeot .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 1830*922e7c40SFrançois Tigeot .gem_prime_export = i915_gem_prime_export, 1831*922e7c40SFrançois Tigeot .gem_prime_import = i915_gem_prime_import, 1832*922e7c40SFrançois Tigeot 1833f0b54121SFrançois Tigeot .dumb_create = i915_gem_dumb_create, 1834f0b54121SFrançois Tigeot .dumb_map_offset = i915_gem_mmap_gtt, 18359edbd4a0SFrançois Tigeot .dumb_destroy = drm_gem_dumb_destroy, 1836f0b54121SFrançois Tigeot .ioctls = i915_ioctls, 1837998e2cc6SPeeter Must .sysctl_init = i915_sysctl_init, 1838*922e7c40SFrançois Tigeot .fops = &i915_driver_fops, 1839f0b54121SFrançois Tigeot .name = DRIVER_NAME, 1840f0b54121SFrançois Tigeot .desc = DRIVER_DESC, 1841f0b54121SFrançois Tigeot .date = DRIVER_DATE, 1842f0b54121SFrançois Tigeot .major = DRIVER_MAJOR, 1843f0b54121SFrançois Tigeot .minor = DRIVER_MINOR, 1844f0b54121SFrançois Tigeot .patchlevel = DRIVER_PATCHLEVEL, 1845f0b54121SFrançois Tigeot }; 1846f0b54121SFrançois Tigeot 1847ba55f2f5SFrançois Tigeot static int __init i915_init(void); 1848ba55f2f5SFrançois Tigeot 1849ba55f2f5SFrançois Tigeot static int 1850ba55f2f5SFrançois Tigeot i915_attach(device_t kdev) 1851ba55f2f5SFrançois Tigeot { 1852ba55f2f5SFrançois Tigeot struct drm_device *dev = device_get_softc(kdev); 1853bcd3cd8cSMatthew Dillon int error; 1854bcd3cd8cSMatthew Dillon int dummy; 1855ba55f2f5SFrançois Tigeot 1856ba55f2f5SFrançois Tigeot dev->driver = &driver; 1857bcd3cd8cSMatthew Dillon error = drm_attach(kdev, i915_attach_list); 1858bcd3cd8cSMatthew Dillon 1859bcd3cd8cSMatthew Dillon /* 1860bcd3cd8cSMatthew Dillon * XXX hack - give the kvm_console time to come up before X starts 1861bcd3cd8cSMatthew Dillon * messing with everything, avoiding at least one deadlock. 1862bcd3cd8cSMatthew Dillon */ 1863bcd3cd8cSMatthew Dillon tsleep(&dummy, 0, "i915_attach", hz*2); 1864bcd3cd8cSMatthew Dillon 1865bcd3cd8cSMatthew Dillon return error; 1866ba55f2f5SFrançois Tigeot } 1867ba55f2f5SFrançois Tigeot 1868a2fdbec6SFrançois Tigeot static device_method_t i915_methods[] = { 1869a2fdbec6SFrançois Tigeot /* Device interface */ 1870a2fdbec6SFrançois Tigeot DEVMETHOD(device_probe, i915_pci_probe), 1871a2fdbec6SFrançois Tigeot DEVMETHOD(device_attach, i915_attach), 1872352ff8bdSFrançois Tigeot DEVMETHOD(device_suspend, i915_suspend_switcheroo), 1873352ff8bdSFrançois Tigeot DEVMETHOD(device_resume, i915_resume_switcheroo), 1874d0cc45b6SFrançois Tigeot DEVMETHOD(device_detach, drm_release), 1875a2fdbec6SFrançois Tigeot DEVMETHOD_END 1876a2fdbec6SFrançois Tigeot }; 1877a2fdbec6SFrançois Tigeot 1878a2fdbec6SFrançois Tigeot static driver_t i915_driver = { 1879a2fdbec6SFrançois Tigeot "drm", 1880a2fdbec6SFrançois Tigeot i915_methods, 1881a2fdbec6SFrançois Tigeot sizeof(struct drm_device) 1882a2fdbec6SFrançois Tigeot }; 1883a2fdbec6SFrançois Tigeot 1884ba55f2f5SFrançois Tigeot static int __init i915_init(void) 1885ba55f2f5SFrançois Tigeot { 1886ba55f2f5SFrançois Tigeot driver.num_ioctls = i915_max_ioctl; 1887ba55f2f5SFrançois Tigeot 1888ba55f2f5SFrançois Tigeot /* 1889a05eeebfSFrançois Tigeot * Enable KMS by default, unless explicitly overriden by 1890a05eeebfSFrançois Tigeot * either the i915.modeset prarameter or by the 1891a05eeebfSFrançois Tigeot * vga_text_mode_force boot option. 1892ba55f2f5SFrançois Tigeot */ 1893a05eeebfSFrançois Tigeot 1894a05eeebfSFrançois Tigeot if (i915.modeset == 0) 1895a05eeebfSFrançois Tigeot driver.driver_features &= ~DRIVER_MODESET; 1896ba55f2f5SFrançois Tigeot 1897ba55f2f5SFrançois Tigeot if (vgacon_text_force() && i915.modeset == -1) 1898ba55f2f5SFrançois Tigeot driver.driver_features &= ~DRIVER_MODESET; 1899ba55f2f5SFrançois Tigeot 1900ba55f2f5SFrançois Tigeot if (!(driver.driver_features & DRIVER_MODESET)) { 1901ba55f2f5SFrançois Tigeot /* Silently fail loading to not upset userspace. */ 1902ba55f2f5SFrançois Tigeot DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); 1903ba55f2f5SFrançois Tigeot return 0; 1904ba55f2f5SFrançois Tigeot } 1905ba55f2f5SFrançois Tigeot 1906352ff8bdSFrançois Tigeot if (i915.nuclear_pageflip) 19072c9916cdSFrançois Tigeot driver.driver_features |= DRIVER_ATOMIC; 19082c9916cdSFrançois Tigeot 1909ba55f2f5SFrançois Tigeot #if 0 1910ba55f2f5SFrançois Tigeot return drm_pci_init(&driver, &i915_pci_driver); 1911ba55f2f5SFrançois Tigeot #else 1912ba55f2f5SFrançois Tigeot return 1; 1913ba55f2f5SFrançois Tigeot #endif 1914ba55f2f5SFrançois Tigeot } 1915ba55f2f5SFrançois Tigeot 1916477eb7f9SFrançois Tigeot #if 0 1917477eb7f9SFrançois Tigeot static void __exit i915_exit(void) 1918477eb7f9SFrançois Tigeot { 1919477eb7f9SFrançois Tigeot if (!(driver.driver_features & DRIVER_MODESET)) 1920477eb7f9SFrançois Tigeot return; /* Never loaded a driver. */ 1921477eb7f9SFrançois Tigeot 1922477eb7f9SFrançois Tigeot drm_pci_exit(&driver, &i915_pci_driver); 1923477eb7f9SFrançois Tigeot } 1924477eb7f9SFrançois Tigeot #endif 1925477eb7f9SFrançois Tigeot 1926bd1f95dfSFrançois Tigeot module_init(i915_init); 1927bd1f95dfSFrançois Tigeot 19280e9fd563SFrançois Tigeot DRIVER_MODULE_ORDERED(i915, vgapci, i915_driver, drm_devclass, NULL, NULL, SI_ORDER_ANY); 19290e9fd563SFrançois Tigeot MODULE_DEPEND(i915, drm, 1, 1, 1); 19308035dd14SFrançois Tigeot #ifdef CONFIG_ACPI 19318035dd14SFrançois Tigeot MODULE_DEPEND(i915, acpi, 1, 1, 1); 19328035dd14SFrançois Tigeot #endif 1933