diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 206 |
1 files changed, 137 insertions, 69 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e9b57893db2b..9ebe895c17d6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -121,9 +121,7 @@ MODULE_PARM_DESC(i915_enable_ppgtt, | |||
121 | unsigned int i915_preliminary_hw_support __read_mostly = 0; | 121 | unsigned int i915_preliminary_hw_support __read_mostly = 0; |
122 | module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); | 122 | module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600); |
123 | MODULE_PARM_DESC(preliminary_hw_support, | 123 | MODULE_PARM_DESC(preliminary_hw_support, |
124 | "Enable preliminary hardware support. " | 124 | "Enable preliminary hardware support. (default: false)"); |
125 | "Enable Haswell and ValleyView Support. " | ||
126 | "(default: false)"); | ||
127 | 125 | ||
128 | int i915_disable_power_well __read_mostly = 0; | 126 | int i915_disable_power_well __read_mostly = 0; |
129 | module_param_named(disable_power_well, i915_disable_power_well, int, 0600); | 127 | module_param_named(disable_power_well, i915_disable_power_well, int, 0600); |
@@ -142,75 +140,85 @@ extern int intel_agp_enabled; | |||
142 | .subdevice = PCI_ANY_ID, \ | 140 | .subdevice = PCI_ANY_ID, \ |
143 | .driver_data = (unsigned long) info } | 141 | .driver_data = (unsigned long) info } |
144 | 142 | ||
143 | #define INTEL_QUANTA_VGA_DEVICE(info) { \ | ||
144 | .class = PCI_BASE_CLASS_DISPLAY << 16, \ | ||
145 | .class_mask = 0xff0000, \ | ||
146 | .vendor = 0x8086, \ | ||
147 | .device = 0x16a, \ | ||
148 | .subvendor = 0x152d, \ | ||
149 | .subdevice = 0x8990, \ | ||
150 | .driver_data = (unsigned long) info } | ||
151 | |||
152 | |||
145 | static const struct intel_device_info intel_i830_info = { | 153 | static const struct intel_device_info intel_i830_info = { |
146 | .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, | 154 | .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, |
147 | .has_overlay = 1, .overlay_needs_physical = 1, | 155 | .has_overlay = 1, .overlay_needs_physical = 1, |
148 | }; | 156 | }; |
149 | 157 | ||
150 | static const struct intel_device_info intel_845g_info = { | 158 | static const struct intel_device_info intel_845g_info = { |
151 | .gen = 2, | 159 | .gen = 2, .num_pipes = 1, |
152 | .has_overlay = 1, .overlay_needs_physical = 1, | 160 | .has_overlay = 1, .overlay_needs_physical = 1, |
153 | }; | 161 | }; |
154 | 162 | ||
155 | static const struct intel_device_info intel_i85x_info = { | 163 | static const struct intel_device_info intel_i85x_info = { |
156 | .gen = 2, .is_i85x = 1, .is_mobile = 1, | 164 | .gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2, |
157 | .cursor_needs_physical = 1, | 165 | .cursor_needs_physical = 1, |
158 | .has_overlay = 1, .overlay_needs_physical = 1, | 166 | .has_overlay = 1, .overlay_needs_physical = 1, |
159 | }; | 167 | }; |
160 | 168 | ||
161 | static const struct intel_device_info intel_i865g_info = { | 169 | static const struct intel_device_info intel_i865g_info = { |
162 | .gen = 2, | 170 | .gen = 2, .num_pipes = 1, |
163 | .has_overlay = 1, .overlay_needs_physical = 1, | 171 | .has_overlay = 1, .overlay_needs_physical = 1, |
164 | }; | 172 | }; |
165 | 173 | ||
166 | static const struct intel_device_info intel_i915g_info = { | 174 | static const struct intel_device_info intel_i915g_info = { |
167 | .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, | 175 | .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2, |
168 | .has_overlay = 1, .overlay_needs_physical = 1, | 176 | .has_overlay = 1, .overlay_needs_physical = 1, |
169 | }; | 177 | }; |
170 | static const struct intel_device_info intel_i915gm_info = { | 178 | static const struct intel_device_info intel_i915gm_info = { |
171 | .gen = 3, .is_mobile = 1, | 179 | .gen = 3, .is_mobile = 1, .num_pipes = 2, |
172 | .cursor_needs_physical = 1, | 180 | .cursor_needs_physical = 1, |
173 | .has_overlay = 1, .overlay_needs_physical = 1, | 181 | .has_overlay = 1, .overlay_needs_physical = 1, |
174 | .supports_tv = 1, | 182 | .supports_tv = 1, |
175 | }; | 183 | }; |
176 | static const struct intel_device_info intel_i945g_info = { | 184 | static const struct intel_device_info intel_i945g_info = { |
177 | .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, | 185 | .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2, |
178 | .has_overlay = 1, .overlay_needs_physical = 1, | 186 | .has_overlay = 1, .overlay_needs_physical = 1, |
179 | }; | 187 | }; |
180 | static const struct intel_device_info intel_i945gm_info = { | 188 | static const struct intel_device_info intel_i945gm_info = { |
181 | .gen = 3, .is_i945gm = 1, .is_mobile = 1, | 189 | .gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2, |
182 | .has_hotplug = 1, .cursor_needs_physical = 1, | 190 | .has_hotplug = 1, .cursor_needs_physical = 1, |
183 | .has_overlay = 1, .overlay_needs_physical = 1, | 191 | .has_overlay = 1, .overlay_needs_physical = 1, |
184 | .supports_tv = 1, | 192 | .supports_tv = 1, |
185 | }; | 193 | }; |
186 | 194 | ||
187 | static const struct intel_device_info intel_i965g_info = { | 195 | static const struct intel_device_info intel_i965g_info = { |
188 | .gen = 4, .is_broadwater = 1, | 196 | .gen = 4, .is_broadwater = 1, .num_pipes = 2, |
189 | .has_hotplug = 1, | 197 | .has_hotplug = 1, |
190 | .has_overlay = 1, | 198 | .has_overlay = 1, |
191 | }; | 199 | }; |
192 | 200 | ||
193 | static const struct intel_device_info intel_i965gm_info = { | 201 | static const struct intel_device_info intel_i965gm_info = { |
194 | .gen = 4, .is_crestline = 1, | 202 | .gen = 4, .is_crestline = 1, .num_pipes = 2, |
195 | .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, | 203 | .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, |
196 | .has_overlay = 1, | 204 | .has_overlay = 1, |
197 | .supports_tv = 1, | 205 | .supports_tv = 1, |
198 | }; | 206 | }; |
199 | 207 | ||
200 | static const struct intel_device_info intel_g33_info = { | 208 | static const struct intel_device_info intel_g33_info = { |
201 | .gen = 3, .is_g33 = 1, | 209 | .gen = 3, .is_g33 = 1, .num_pipes = 2, |
202 | .need_gfx_hws = 1, .has_hotplug = 1, | 210 | .need_gfx_hws = 1, .has_hotplug = 1, |
203 | .has_overlay = 1, | 211 | .has_overlay = 1, |
204 | }; | 212 | }; |
205 | 213 | ||
206 | static const struct intel_device_info intel_g45_info = { | 214 | static const struct intel_device_info intel_g45_info = { |
207 | .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, | 215 | .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2, |
208 | .has_pipe_cxsr = 1, .has_hotplug = 1, | 216 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
209 | .has_bsd_ring = 1, | 217 | .has_bsd_ring = 1, |
210 | }; | 218 | }; |
211 | 219 | ||
212 | static const struct intel_device_info intel_gm45_info = { | 220 | static const struct intel_device_info intel_gm45_info = { |
213 | .gen = 4, .is_g4x = 1, | 221 | .gen = 4, .is_g4x = 1, .num_pipes = 2, |
214 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, | 222 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, |
215 | .has_pipe_cxsr = 1, .has_hotplug = 1, | 223 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
216 | .supports_tv = 1, | 224 | .supports_tv = 1, |
@@ -218,26 +226,26 @@ static const struct intel_device_info intel_gm45_info = { | |||
218 | }; | 226 | }; |
219 | 227 | ||
220 | static const struct intel_device_info intel_pineview_info = { | 228 | static const struct intel_device_info intel_pineview_info = { |
221 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, | 229 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2, |
222 | .need_gfx_hws = 1, .has_hotplug = 1, | 230 | .need_gfx_hws = 1, .has_hotplug = 1, |
223 | .has_overlay = 1, | 231 | .has_overlay = 1, |
224 | }; | 232 | }; |
225 | 233 | ||
226 | static const struct intel_device_info intel_ironlake_d_info = { | 234 | static const struct intel_device_info intel_ironlake_d_info = { |
227 | .gen = 5, | 235 | .gen = 5, .num_pipes = 2, |
228 | .need_gfx_hws = 1, .has_hotplug = 1, | 236 | .need_gfx_hws = 1, .has_hotplug = 1, |
229 | .has_bsd_ring = 1, | 237 | .has_bsd_ring = 1, |
230 | }; | 238 | }; |
231 | 239 | ||
232 | static const struct intel_device_info intel_ironlake_m_info = { | 240 | static const struct intel_device_info intel_ironlake_m_info = { |
233 | .gen = 5, .is_mobile = 1, | 241 | .gen = 5, .is_mobile = 1, .num_pipes = 2, |
234 | .need_gfx_hws = 1, .has_hotplug = 1, | 242 | .need_gfx_hws = 1, .has_hotplug = 1, |
235 | .has_fbc = 1, | 243 | .has_fbc = 1, |
236 | .has_bsd_ring = 1, | 244 | .has_bsd_ring = 1, |
237 | }; | 245 | }; |
238 | 246 | ||
239 | static const struct intel_device_info intel_sandybridge_d_info = { | 247 | static const struct intel_device_info intel_sandybridge_d_info = { |
240 | .gen = 6, | 248 | .gen = 6, .num_pipes = 2, |
241 | .need_gfx_hws = 1, .has_hotplug = 1, | 249 | .need_gfx_hws = 1, .has_hotplug = 1, |
242 | .has_bsd_ring = 1, | 250 | .has_bsd_ring = 1, |
243 | .has_blt_ring = 1, | 251 | .has_blt_ring = 1, |
@@ -246,7 +254,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { | |||
246 | }; | 254 | }; |
247 | 255 | ||
248 | static const struct intel_device_info intel_sandybridge_m_info = { | 256 | static const struct intel_device_info intel_sandybridge_m_info = { |
249 | .gen = 6, .is_mobile = 1, | 257 | .gen = 6, .is_mobile = 1, .num_pipes = 2, |
250 | .need_gfx_hws = 1, .has_hotplug = 1, | 258 | .need_gfx_hws = 1, .has_hotplug = 1, |
251 | .has_fbc = 1, | 259 | .has_fbc = 1, |
252 | .has_bsd_ring = 1, | 260 | .has_bsd_ring = 1, |
@@ -255,61 +263,57 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
255 | .has_force_wake = 1, | 263 | .has_force_wake = 1, |
256 | }; | 264 | }; |
257 | 265 | ||
266 | #define GEN7_FEATURES \ | ||
267 | .gen = 7, .num_pipes = 3, \ | ||
268 | .need_gfx_hws = 1, .has_hotplug = 1, \ | ||
269 | .has_bsd_ring = 1, \ | ||
270 | .has_blt_ring = 1, \ | ||
271 | .has_llc = 1, \ | ||
272 | .has_force_wake = 1 | ||
273 | |||
258 | static const struct intel_device_info intel_ivybridge_d_info = { | 274 | static const struct intel_device_info intel_ivybridge_d_info = { |
259 | .is_ivybridge = 1, .gen = 7, | 275 | GEN7_FEATURES, |
260 | .need_gfx_hws = 1, .has_hotplug = 1, | 276 | .is_ivybridge = 1, |
261 | .has_bsd_ring = 1, | ||
262 | .has_blt_ring = 1, | ||
263 | .has_llc = 1, | ||
264 | .has_force_wake = 1, | ||
265 | }; | 277 | }; |
266 | 278 | ||
267 | static const struct intel_device_info intel_ivybridge_m_info = { | 279 | static const struct intel_device_info intel_ivybridge_m_info = { |
268 | .is_ivybridge = 1, .gen = 7, .is_mobile = 1, | 280 | GEN7_FEATURES, |
269 | .need_gfx_hws = 1, .has_hotplug = 1, | 281 | .is_ivybridge = 1, |
270 | .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ | 282 | .is_mobile = 1, |
271 | .has_bsd_ring = 1, | 283 | }; |
272 | .has_blt_ring = 1, | 284 | |
273 | .has_llc = 1, | 285 | static const struct intel_device_info intel_ivybridge_q_info = { |
274 | .has_force_wake = 1, | 286 | GEN7_FEATURES, |
287 | .is_ivybridge = 1, | ||
288 | .num_pipes = 0, /* legal, last one wins */ | ||
275 | }; | 289 | }; |
276 | 290 | ||
277 | static const struct intel_device_info intel_valleyview_m_info = { | 291 | static const struct intel_device_info intel_valleyview_m_info = { |
278 | .gen = 7, .is_mobile = 1, | 292 | GEN7_FEATURES, |
279 | .need_gfx_hws = 1, .has_hotplug = 1, | 293 | .is_mobile = 1, |
280 | .has_fbc = 0, | 294 | .num_pipes = 2, |
281 | .has_bsd_ring = 1, | ||
282 | .has_blt_ring = 1, | ||
283 | .is_valleyview = 1, | 295 | .is_valleyview = 1, |
284 | .display_mmio_offset = VLV_DISPLAY_BASE, | 296 | .display_mmio_offset = VLV_DISPLAY_BASE, |
297 | .has_llc = 0, /* legal, last one wins */ | ||
285 | }; | 298 | }; |
286 | 299 | ||
287 | static const struct intel_device_info intel_valleyview_d_info = { | 300 | static const struct intel_device_info intel_valleyview_d_info = { |
288 | .gen = 7, | 301 | GEN7_FEATURES, |
289 | .need_gfx_hws = 1, .has_hotplug = 1, | 302 | .num_pipes = 2, |
290 | .has_fbc = 0, | ||
291 | .has_bsd_ring = 1, | ||
292 | .has_blt_ring = 1, | ||
293 | .is_valleyview = 1, | 303 | .is_valleyview = 1, |
294 | .display_mmio_offset = VLV_DISPLAY_BASE, | 304 | .display_mmio_offset = VLV_DISPLAY_BASE, |
305 | .has_llc = 0, /* legal, last one wins */ | ||
295 | }; | 306 | }; |
296 | 307 | ||
297 | static const struct intel_device_info intel_haswell_d_info = { | 308 | static const struct intel_device_info intel_haswell_d_info = { |
298 | .is_haswell = 1, .gen = 7, | 309 | GEN7_FEATURES, |
299 | .need_gfx_hws = 1, .has_hotplug = 1, | 310 | .is_haswell = 1, |
300 | .has_bsd_ring = 1, | ||
301 | .has_blt_ring = 1, | ||
302 | .has_llc = 1, | ||
303 | .has_force_wake = 1, | ||
304 | }; | 311 | }; |
305 | 312 | ||
306 | static const struct intel_device_info intel_haswell_m_info = { | 313 | static const struct intel_device_info intel_haswell_m_info = { |
307 | .is_haswell = 1, .gen = 7, .is_mobile = 1, | 314 | GEN7_FEATURES, |
308 | .need_gfx_hws = 1, .has_hotplug = 1, | 315 | .is_haswell = 1, |
309 | .has_bsd_ring = 1, | 316 | .is_mobile = 1, |
310 | .has_blt_ring = 1, | ||
311 | .has_llc = 1, | ||
312 | .has_force_wake = 1, | ||
313 | }; | 317 | }; |
314 | 318 | ||
315 | static const struct pci_device_id pciidlist[] = { /* aka */ | 319 | static const struct pci_device_id pciidlist[] = { /* aka */ |
@@ -356,6 +360,7 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
356 | INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ | 360 | INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ |
357 | INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ | 361 | INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ |
358 | INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ | 362 | INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ |
363 | INTEL_QUANTA_VGA_DEVICE(&intel_ivybridge_q_info), /* Quanta transcode */ | ||
359 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ | 364 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ |
360 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ | 365 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ |
361 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ | 366 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ |
@@ -394,6 +399,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
394 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ | 399 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ |
395 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ | 400 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ |
396 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | 401 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), |
402 | INTEL_VGA_DEVICE(0x0f31, &intel_valleyview_m_info), | ||
403 | INTEL_VGA_DEVICE(0x0f32, &intel_valleyview_m_info), | ||
404 | INTEL_VGA_DEVICE(0x0f33, &intel_valleyview_m_info), | ||
397 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | 405 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), |
398 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | 406 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), |
399 | {0, 0, 0} | 407 | {0, 0, 0} |
@@ -408,6 +416,15 @@ void intel_detect_pch(struct drm_device *dev) | |||
408 | struct drm_i915_private *dev_priv = dev->dev_private; | 416 | struct drm_i915_private *dev_priv = dev->dev_private; |
409 | struct pci_dev *pch; | 417 | struct pci_dev *pch; |
410 | 418 | ||
419 | /* In all current cases, num_pipes is equivalent to the PCH_NOP setting | ||
420 | * (which really amounts to a PCH but no South Display). | ||
421 | */ | ||
422 | if (INTEL_INFO(dev)->num_pipes == 0) { | ||
423 | dev_priv->pch_type = PCH_NOP; | ||
424 | dev_priv->num_pch_pll = 0; | ||
425 | return; | ||
426 | } | ||
427 | |||
411 | /* | 428 | /* |
412 | * The reason to probe ISA bridge instead of Dev31:Fun0 is to | 429 | * The reason to probe ISA bridge instead of Dev31:Fun0 is to |
413 | * make graphics device passthrough work easy for VMM, that only | 430 | * make graphics device passthrough work easy for VMM, that only |
@@ -442,11 +459,13 @@ void intel_detect_pch(struct drm_device *dev) | |||
442 | dev_priv->num_pch_pll = 0; | 459 | dev_priv->num_pch_pll = 0; |
443 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); | 460 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); |
444 | WARN_ON(!IS_HASWELL(dev)); | 461 | WARN_ON(!IS_HASWELL(dev)); |
462 | WARN_ON(IS_ULT(dev)); | ||
445 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { | 463 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { |
446 | dev_priv->pch_type = PCH_LPT; | 464 | dev_priv->pch_type = PCH_LPT; |
447 | dev_priv->num_pch_pll = 0; | 465 | dev_priv->num_pch_pll = 0; |
448 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); | 466 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); |
449 | WARN_ON(!IS_HASWELL(dev)); | 467 | WARN_ON(!IS_HASWELL(dev)); |
468 | WARN_ON(!IS_ULT(dev)); | ||
450 | } | 469 | } |
451 | BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS); | 470 | BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS); |
452 | } | 471 | } |
@@ -474,6 +493,7 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
474 | static int i915_drm_freeze(struct drm_device *dev) | 493 | static int i915_drm_freeze(struct drm_device *dev) |
475 | { | 494 | { |
476 | struct drm_i915_private *dev_priv = dev->dev_private; | 495 | struct drm_i915_private *dev_priv = dev->dev_private; |
496 | struct drm_crtc *crtc; | ||
477 | 497 | ||
478 | /* ignore lid events during suspend */ | 498 | /* ignore lid events during suspend */ |
479 | mutex_lock(&dev_priv->modeset_restore_lock); | 499 | mutex_lock(&dev_priv->modeset_restore_lock); |
@@ -497,10 +517,14 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
497 | 517 | ||
498 | cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); | 518 | cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work); |
499 | 519 | ||
500 | intel_modeset_disable(dev); | ||
501 | |||
502 | drm_irq_uninstall(dev); | 520 | drm_irq_uninstall(dev); |
503 | dev_priv->enable_hotplug_processing = false; | 521 | dev_priv->enable_hotplug_processing = false; |
522 | /* | ||
523 | * Disable CRTCs directly since we want to preserve sw state | ||
524 | * for _thaw. | ||
525 | */ | ||
526 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
527 | dev_priv->display.crtc_disable(crtc); | ||
504 | } | 528 | } |
505 | 529 | ||
506 | i915_save_state(dev); | 530 | i915_save_state(dev); |
@@ -556,6 +580,24 @@ void intel_console_resume(struct work_struct *work) | |||
556 | console_unlock(); | 580 | console_unlock(); |
557 | } | 581 | } |
558 | 582 | ||
583 | static void intel_resume_hotplug(struct drm_device *dev) | ||
584 | { | ||
585 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
586 | struct intel_encoder *encoder; | ||
587 | |||
588 | mutex_lock(&mode_config->mutex); | ||
589 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); | ||
590 | |||
591 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) | ||
592 | if (encoder->hot_plug) | ||
593 | encoder->hot_plug(encoder); | ||
594 | |||
595 | mutex_unlock(&mode_config->mutex); | ||
596 | |||
597 | /* Just fire off a uevent and let userspace tell us what to do */ | ||
598 | drm_helper_hpd_irq_event(dev); | ||
599 | } | ||
600 | |||
559 | static int __i915_drm_thaw(struct drm_device *dev) | 601 | static int __i915_drm_thaw(struct drm_device *dev) |
560 | { | 602 | { |
561 | struct drm_i915_private *dev_priv = dev->dev_private; | 603 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -578,7 +620,10 @@ static int __i915_drm_thaw(struct drm_device *dev) | |||
578 | drm_irq_install(dev); | 620 | drm_irq_install(dev); |
579 | 621 | ||
580 | intel_modeset_init_hw(dev); | 622 | intel_modeset_init_hw(dev); |
581 | intel_modeset_setup_hw_state(dev, false); | 623 | |
624 | drm_modeset_lock_all(dev); | ||
625 | intel_modeset_setup_hw_state(dev, true); | ||
626 | drm_modeset_unlock_all(dev); | ||
582 | 627 | ||
583 | /* | 628 | /* |
584 | * ... but also need to make sure that hotplug processing | 629 | * ... but also need to make sure that hotplug processing |
@@ -588,6 +633,8 @@ static int __i915_drm_thaw(struct drm_device *dev) | |||
588 | * */ | 633 | * */ |
589 | intel_hpd_init(dev); | 634 | intel_hpd_init(dev); |
590 | dev_priv->enable_hotplug_processing = true; | 635 | dev_priv->enable_hotplug_processing = true; |
636 | /* Config may have changed between suspend and resume */ | ||
637 | intel_resume_hotplug(dev); | ||
591 | } | 638 | } |
592 | 639 | ||
593 | intel_opregion_init(dev); | 640 | intel_opregion_init(dev); |
@@ -732,6 +779,7 @@ static int ironlake_do_reset(struct drm_device *dev) | |||
732 | int ret; | 779 | int ret; |
733 | 780 | ||
734 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); | 781 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); |
782 | gdrst &= ~GRDOM_MASK; | ||
735 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, | 783 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
736 | gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); | 784 | gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); |
737 | ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); | 785 | ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); |
@@ -740,6 +788,7 @@ static int ironlake_do_reset(struct drm_device *dev) | |||
740 | 788 | ||
741 | /* We can't reset render&media without also resetting display ... */ | 789 | /* We can't reset render&media without also resetting display ... */ |
742 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); | 790 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); |
791 | gdrst &= ~GRDOM_MASK; | ||
743 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, | 792 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
744 | gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); | 793 | gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); |
745 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); | 794 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); |
@@ -803,7 +852,7 @@ int intel_gpu_reset(struct drm_device *dev) | |||
803 | 852 | ||
804 | /* Also reset the gpu hangman. */ | 853 | /* Also reset the gpu hangman. */ |
805 | if (dev_priv->gpu_error.stop_rings) { | 854 | if (dev_priv->gpu_error.stop_rings) { |
806 | DRM_DEBUG("Simulated gpu hang, resetting stop_rings\n"); | 855 | DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); |
807 | dev_priv->gpu_error.stop_rings = 0; | 856 | dev_priv->gpu_error.stop_rings = 0; |
808 | if (ret == -ENODEV) { | 857 | if (ret == -ENODEV) { |
809 | DRM_ERROR("Reset not implemented, but ignoring " | 858 | DRM_ERROR("Reset not implemented, but ignoring " |
@@ -882,7 +931,11 @@ int i915_reset(struct drm_device *dev) | |||
882 | ring->init(ring); | 931 | ring->init(ring); |
883 | 932 | ||
884 | i915_gem_context_init(dev); | 933 | i915_gem_context_init(dev); |
885 | i915_gem_init_ppgtt(dev); | 934 | if (dev_priv->mm.aliasing_ppgtt) { |
935 | ret = dev_priv->mm.aliasing_ppgtt->enable(dev); | ||
936 | if (ret) | ||
937 | i915_gem_cleanup_aliasing_ppgtt(dev); | ||
938 | } | ||
886 | 939 | ||
887 | /* | 940 | /* |
888 | * It would make sense to re-init all the other hw state, at | 941 | * It would make sense to re-init all the other hw state, at |
@@ -1147,6 +1200,27 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) | |||
1147 | I915_WRITE_NOTRACE(MI_MODE, 0); | 1200 | I915_WRITE_NOTRACE(MI_MODE, 0); |
1148 | } | 1201 | } |
1149 | 1202 | ||
1203 | static void | ||
1204 | hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) | ||
1205 | { | ||
1206 | if (IS_HASWELL(dev_priv->dev) && | ||
1207 | (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { | ||
1208 | DRM_ERROR("Unknown unclaimed register before writing to %x\n", | ||
1209 | reg); | ||
1210 | I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | static void | ||
1215 | hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) | ||
1216 | { | ||
1217 | if (IS_HASWELL(dev_priv->dev) && | ||
1218 | (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { | ||
1219 | DRM_ERROR("Unclaimed write to %x\n", reg); | ||
1220 | I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM); | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1150 | #define __i915_read(x, y) \ | 1224 | #define __i915_read(x, y) \ |
1151 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 1225 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
1152 | u##x val = 0; \ | 1226 | u##x val = 0; \ |
@@ -1183,18 +1257,12 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ | |||
1183 | } \ | 1257 | } \ |
1184 | if (IS_GEN5(dev_priv->dev)) \ | 1258 | if (IS_GEN5(dev_priv->dev)) \ |
1185 | ilk_dummy_write(dev_priv); \ | 1259 | ilk_dummy_write(dev_priv); \ |
1186 | if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ | 1260 | hsw_unclaimed_reg_clear(dev_priv, reg); \ |
1187 | DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \ | ||
1188 | I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \ | ||
1189 | } \ | ||
1190 | write##y(val, dev_priv->regs + reg); \ | 1261 | write##y(val, dev_priv->regs + reg); \ |
1191 | if (unlikely(__fifo_ret)) { \ | 1262 | if (unlikely(__fifo_ret)) { \ |
1192 | gen6_gt_check_fifodbg(dev_priv); \ | 1263 | gen6_gt_check_fifodbg(dev_priv); \ |
1193 | } \ | 1264 | } \ |
1194 | if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \ | 1265 | hsw_unclaimed_reg_check(dev_priv, reg); \ |
1195 | DRM_ERROR("Unclaimed write to %x\n", reg); \ | ||
1196 | writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT); \ | ||
1197 | } \ | ||
1198 | } | 1266 | } |
1199 | __i915_write(8, b) | 1267 | __i915_write(8, b) |
1200 | __i915_write(16, w) | 1268 | __i915_write(16, w) |