Rev 4560 | Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | #define __raw_i915_read64(dev_priv__, reg__) readq((dev_priv__)->regs + (reg__)) |
38 | #define __raw_i915_read64(dev_priv__, reg__) readq((dev_priv__)->regs + (reg__)) |
39 | #define __raw_i915_write64(dev_priv__, reg__, val__) writeq(val__, (dev_priv__)->regs + (reg__)) |
39 | #define __raw_i915_write64(dev_priv__, reg__, val__) writeq(val__, (dev_priv__)->regs + (reg__)) |
Line 40... | Line 40... | ||
40 | 40 | ||
Line -... | Line 41... | ||
- | 41 | #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) |
|
- | 42 | ||
- | 43 | static void |
|
- | 44 | assert_device_not_suspended(struct drm_i915_private *dev_priv) |
|
- | 45 | { |
|
- | 46 | WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, |
|
Line 41... | Line 47... | ||
41 | #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__) |
47 | "Device suspended\n"); |
42 | 48 | } |
|
43 | 49 | ||
Line 81... | Line 87... | ||
81 | 87 | ||
82 | /* WaRsForcewakeWaitTC0:snb */ |
88 | /* WaRsForcewakeWaitTC0:snb */ |
83 | __gen6_gt_wait_for_thread_c0(dev_priv); |
89 | __gen6_gt_wait_for_thread_c0(dev_priv); |
Line 84... | Line 90... | ||
84 | } |
90 | } |
85 | 91 | ||
86 | static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) |
92 | static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv) |
87 | { |
93 | { |
88 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); |
94 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff)); |
89 | /* something from same cacheline, but !FORCEWAKE_MT */ |
95 | /* something from same cacheline, but !FORCEWAKE_MT */ |
Line 90... | Line 96... | ||
90 | __raw_posting_read(dev_priv, ECOBUS); |
96 | __raw_posting_read(dev_priv, ECOBUS); |
91 | } |
97 | } |
92 | 98 | ||
93 | static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, |
99 | static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv, |
Line 94... | Line 100... | ||
94 | int fw_engine) |
100 | int fw_engine) |
Line 134... | Line 140... | ||
134 | /* something from same cacheline, but !FORCEWAKE */ |
140 | /* something from same cacheline, but !FORCEWAKE */ |
135 | __raw_posting_read(dev_priv, ECOBUS); |
141 | __raw_posting_read(dev_priv, ECOBUS); |
136 | gen6_gt_check_fifodbg(dev_priv); |
142 | gen6_gt_check_fifodbg(dev_priv); |
137 | } |
143 | } |
Line 138... | Line 144... | ||
138 | 144 | ||
139 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, |
145 | static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv, |
140 | int fw_engine) |
146 | int fw_engine) |
141 | { |
147 | { |
142 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
148 | __raw_i915_write32(dev_priv, FORCEWAKE_MT, |
143 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
149 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
144 | /* something from same cacheline, but !FORCEWAKE_MT */ |
150 | /* something from same cacheline, but !FORCEWAKE_MT */ |
- | 151 | __raw_posting_read(dev_priv, ECOBUS); |
|
- | 152 | ||
145 | __raw_posting_read(dev_priv, ECOBUS); |
153 | if (IS_GEN7(dev_priv->dev)) |
146 | gen6_gt_check_fifodbg(dev_priv); |
154 | gen6_gt_check_fifodbg(dev_priv); |
Line 147... | Line 155... | ||
147 | } |
155 | } |
148 | 156 | ||
Line 175... | Line 183... | ||
175 | 183 | ||
176 | static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) |
184 | static void vlv_force_wake_reset(struct drm_i915_private *dev_priv) |
177 | { |
185 | { |
178 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
186 | __raw_i915_write32(dev_priv, FORCEWAKE_VLV, |
- | 187 | _MASKED_BIT_DISABLE(0xffff)); |
|
- | 188 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
|
179 | _MASKED_BIT_DISABLE(0xffff)); |
189 | _MASKED_BIT_DISABLE(0xffff)); |
180 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
190 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
181 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
191 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
Line 182... | Line 192... | ||
182 | } |
192 | } |
Line 219... | Line 229... | ||
219 | FORCEWAKE_ACK_TIMEOUT_MS)) |
229 | FORCEWAKE_ACK_TIMEOUT_MS)) |
220 | DRM_ERROR("Timed out: waiting for media to ack.\n"); |
230 | DRM_ERROR("Timed out: waiting for media to ack.\n"); |
221 | } |
231 | } |
Line 222... | Line 232... | ||
222 | 232 | ||
- | 233 | /* WaRsForcewakeWaitTC0:vlv */ |
|
223 | /* WaRsForcewakeWaitTC0:vlv */ |
234 | if (!IS_CHERRYVIEW(dev_priv->dev)) |
224 | __gen6_gt_wait_for_thread_c0(dev_priv); |
- | |
225 | 235 | __gen6_gt_wait_for_thread_c0(dev_priv); |
|
Line 226... | Line 236... | ||
226 | } |
236 | } |
227 | 237 | ||
228 | static void __vlv_force_wake_put(struct drm_i915_private *dev_priv, |
238 | static void __vlv_force_wake_put(struct drm_i915_private *dev_priv, |
Line 238... | Line 248... | ||
238 | /* Check for Media Engine */ |
248 | /* Check for Media Engine */ |
239 | if (FORCEWAKE_MEDIA & fw_engine) |
249 | if (FORCEWAKE_MEDIA & fw_engine) |
240 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
250 | __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV, |
241 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
251 | _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL)); |
Line 242... | Line 252... | ||
242 | 252 | ||
- | 253 | /* something from same cacheline, but !FORCEWAKE_VLV */ |
|
- | 254 | __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV); |
|
243 | /* The below doubles as a POSTING_READ */ |
255 | if (!IS_CHERRYVIEW(dev_priv->dev)) |
244 | gen6_gt_check_fifodbg(dev_priv); |
- | |
245 | 256 | gen6_gt_check_fifodbg(dev_priv); |
|
Line 246... | Line 257... | ||
246 | } |
257 | } |
247 | - | ||
248 | void vlv_force_wake_get(struct drm_i915_private *dev_priv, |
258 | |
249 | int fw_engine) |
259 | static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine) |
Line 250... | Line 260... | ||
250 | { |
260 | { |
- | 261 | unsigned long irqflags; |
|
251 | unsigned long irqflags; |
262 | |
252 | 263 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
|
253 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
- | |
254 | if (FORCEWAKE_RENDER & fw_engine) { |
264 | |
255 | if (dev_priv->uncore.fw_rendercount++ == 0) |
- | |
256 | dev_priv->uncore.funcs.force_wake_get(dev_priv, |
265 | if (fw_engine & FORCEWAKE_RENDER && |
257 | FORCEWAKE_RENDER); |
266 | dev_priv->uncore.fw_rendercount++ != 0) |
258 | } |
- | |
259 | if (FORCEWAKE_MEDIA & fw_engine) { |
267 | fw_engine &= ~FORCEWAKE_RENDER; |
260 | if (dev_priv->uncore.fw_mediacount++ == 0) |
268 | if (fw_engine & FORCEWAKE_MEDIA && |
- | 269 | dev_priv->uncore.fw_mediacount++ != 0) |
|
- | 270 | fw_engine &= ~FORCEWAKE_MEDIA; |
|
Line 261... | Line 271... | ||
261 | dev_priv->uncore.funcs.force_wake_get(dev_priv, |
271 | |
262 | FORCEWAKE_MEDIA); |
272 | if (fw_engine) |
Line 263... | Line 273... | ||
263 | } |
273 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine); |
264 | - | ||
265 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
274 | |
266 | } |
275 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
Line 267... | Line 276... | ||
267 | 276 | } |
|
Line 268... | Line 277... | ||
268 | void vlv_force_wake_put(struct drm_i915_private *dev_priv, |
277 | |
269 | int fw_engine) |
278 | static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) |
270 | { |
279 | { |
271 | unsigned long irqflags; |
- | |
272 | 280 | unsigned long irqflags; |
|
273 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
281 | |
Line 274... | Line 282... | ||
274 | 282 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
|
275 | if (FORCEWAKE_RENDER & fw_engine) { |
283 | |
276 | WARN_ON(dev_priv->uncore.fw_rendercount == 0); |
284 | if (fw_engine & FORCEWAKE_RENDER) { |
277 | if (--dev_priv->uncore.fw_rendercount == 0) |
- | |
278 | dev_priv->uncore.funcs.force_wake_put(dev_priv, |
285 | WARN_ON(!dev_priv->uncore.fw_rendercount); |
279 | FORCEWAKE_RENDER); |
286 | if (--dev_priv->uncore.fw_rendercount != 0) |
Line -... | Line 287... | ||
- | 287 | fw_engine &= ~FORCEWAKE_RENDER; |
|
- | 288 | } |
|
- | 289 | ||
280 | } |
290 | if (fw_engine & FORCEWAKE_MEDIA) { |
281 | 291 | WARN_ON(!dev_priv->uncore.fw_mediacount); |
|
Line 282... | Line 292... | ||
282 | if (FORCEWAKE_MEDIA & fw_engine) { |
292 | if (--dev_priv->uncore.fw_mediacount != 0) |
283 | WARN_ON(dev_priv->uncore.fw_mediacount == 0); |
293 | fw_engine &= ~FORCEWAKE_MEDIA; |
284 | if (--dev_priv->uncore.fw_mediacount == 0) |
294 | } |
285 | dev_priv->uncore.funcs.force_wake_put(dev_priv, |
- | |
286 | FORCEWAKE_MEDIA); |
295 | |
Line -... | Line 296... | ||
- | 296 | if (fw_engine) |
|
- | 297 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine); |
|
287 | } |
298 | |
- | 299 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
|
- | 300 | } |
|
288 | 301 | ||
289 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
302 | static void gen6_force_wake_timer(unsigned long arg) |
290 | } |
303 | { |
- | 304 | struct drm_i915_private *dev_priv = (void *)arg; |
|
- | 305 | unsigned long irqflags; |
|
291 | 306 | ||
Line 292... | Line 307... | ||
292 | static void gen6_force_wake_work(struct work_struct *work) |
307 | assert_device_not_suspended(dev_priv); |
293 | { |
308 | |
294 | struct drm_i915_private *dev_priv = |
309 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
- | 310 | WARN_ON(!dev_priv->uncore.forcewake_count); |
|
Line -... | Line 311... | ||
- | 311 | ||
- | 312 | if (--dev_priv->uncore.forcewake_count == 0) |
|
- | 313 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); |
|
- | 314 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
|
- | 315 | ||
- | 316 | intel_runtime_pm_put(dev_priv); |
|
- | 317 | } |
|
- | 318 | ||
295 | container_of(work, typeof(*dev_priv), uncore.force_wake_work.work); |
319 | void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) |
296 | unsigned long irqflags; |
320 | { |
297 | 321 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
298 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
322 | unsigned long irqflags; |
- | 323 | ||
299 | if (--dev_priv->uncore.forcewake_count == 0) |
324 | if (del_timer_sync(&dev_priv->uncore.force_wake_timer)) |
300 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); |
325 | gen6_force_wake_timer((unsigned long)dev_priv); |
- | 326 | ||
- | 327 | /* Hold uncore.lock across reset to prevent any register access |
|
- | 328 | * with forcewake not set correctly |
|
- | 329 | */ |
|
- | 330 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
|
- | 331 | ||
- | 332 | if (IS_VALLEYVIEW(dev)) |
|
- | 333 | vlv_force_wake_reset(dev_priv); |
|
- | 334 | else if (IS_GEN6(dev) || IS_GEN7(dev)) |
|
- | 335 | __gen6_gt_force_wake_reset(dev_priv); |
|
- | 336 | ||
- | 337 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_GEN8(dev)) |
|
- | 338 | __gen7_gt_force_wake_mt_reset(dev_priv); |
|
- | 339 | ||
- | 340 | if (restore) { /* If reset with a user forcewake, try to restore */ |
|
- | 341 | unsigned fw = 0; |
|
- | 342 | ||
- | 343 | if (IS_VALLEYVIEW(dev)) { |
|
- | 344 | if (dev_priv->uncore.fw_rendercount) |
|
- | 345 | fw |= FORCEWAKE_RENDER; |
|
- | 346 | ||
- | 347 | if (dev_priv->uncore.fw_mediacount) |
|
301 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
348 | fw |= FORCEWAKE_MEDIA; |
- | 349 | } else { |
|
- | 350 | if (dev_priv->uncore.forcewake_count) |
|
302 | } |
351 | fw = FORCEWAKE_ALL; |
Line 303... | Line 352... | ||
303 | 352 | } |
|
304 | static void intel_uncore_forcewake_reset(struct drm_device *dev) |
353 | |
305 | { |
354 | if (fw) |
Line 306... | Line 355... | ||
306 | struct drm_i915_private *dev_priv = dev->dev_private; |
355 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw); |
307 | 356 | ||
Line 308... | Line 357... | ||
308 | if (IS_VALLEYVIEW(dev)) { |
357 | if (IS_GEN6(dev) || IS_GEN7(dev)) |
309 | vlv_force_wake_reset(dev_priv); |
358 | dev_priv->uncore.fifo_count = |
310 | } else if (INTEL_INFO(dev)->gen >= 6) { |
359 | __raw_i915_read32(dev_priv, GTFIFOCTL) & |
311 | __gen6_gt_force_wake_reset(dev_priv); |
360 | GT_FIFO_FREE_ENTRIES_MASK; |
312 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
361 | } |
313 | __gen6_gt_force_wake_mt_reset(dev_priv); |
362 | |
Line 335... | Line 384... | ||
335 | /* clear out old GT FIFO errors */ |
384 | /* clear out old GT FIFO errors */ |
336 | if (IS_GEN6(dev) || IS_GEN7(dev)) |
385 | if (IS_GEN6(dev) || IS_GEN7(dev)) |
337 | __raw_i915_write32(dev_priv, GTFIFODBG, |
386 | __raw_i915_write32(dev_priv, GTFIFODBG, |
338 | __raw_i915_read32(dev_priv, GTFIFODBG)); |
387 | __raw_i915_read32(dev_priv, GTFIFODBG)); |
Line 339... | Line 388... | ||
339 | 388 | ||
340 | intel_uncore_forcewake_reset(dev); |
389 | intel_uncore_forcewake_reset(dev, restore_forcewake); |
Line 341... | Line 390... | ||
341 | } |
390 | } |
342 | 391 | ||
343 | void intel_uncore_sanitize(struct drm_device *dev) |
- | |
344 | { |
- | |
345 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
346 | u32 reg_val; |
392 | void intel_uncore_sanitize(struct drm_device *dev) |
347 | 393 | { |
|
348 | /* BIOS often leaves RC6 enabled, but disable it for hw init */ |
- | |
349 | intel_disable_gt_powersave(dev); |
- | |
350 | - | ||
351 | /* Turn off power gate, require especially for the BIOS less system */ |
- | |
352 | if (IS_VALLEYVIEW(dev)) { |
- | |
353 | - | ||
354 | mutex_lock(&dev_priv->rps.hw_lock); |
- | |
355 | reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS); |
- | |
356 | - | ||
357 | if (reg_val & (RENDER_PWRGT | MEDIA_PWRGT | DISP2D_PWRGT)) |
- | |
358 | vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0); |
- | |
359 | - | ||
360 | mutex_unlock(&dev_priv->rps.hw_lock); |
- | |
361 | 394 | /* BIOS often leaves RC6 enabled, but disable it for hw init */ |
|
Line 362... | Line 395... | ||
362 | } |
395 | intel_disable_gt_powersave(dev); |
363 | } |
396 | } |
364 | 397 | ||
Line 391... | Line 424... | ||
391 | * see gen6_gt_force_wake_get() |
424 | * see gen6_gt_force_wake_get() |
392 | */ |
425 | */ |
393 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) |
426 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine) |
394 | { |
427 | { |
395 | unsigned long irqflags; |
428 | unsigned long irqflags; |
- | 429 | bool delayed = false; |
|
Line 396... | Line 430... | ||
396 | 430 | ||
397 | if (!dev_priv->uncore.funcs.force_wake_put) |
431 | if (!dev_priv->uncore.funcs.force_wake_put) |
Line 398... | Line 432... | ||
398 | return; |
432 | return; |
399 | 433 | ||
400 | /* Redirect to VLV specific routine */ |
434 | /* Redirect to VLV specific routine */ |
- | 435 | if (IS_VALLEYVIEW(dev_priv->dev)) { |
|
- | 436 | vlv_force_wake_put(dev_priv, fw_engine); |
|
Line 401... | Line 437... | ||
401 | if (IS_VALLEYVIEW(dev_priv->dev)) |
437 | goto out; |
- | 438 | } |
|
- | 439 | ||
402 | return vlv_force_wake_put(dev_priv, fw_engine); |
440 | |
403 | 441 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
|
404 | 442 | WARN_ON(!dev_priv->uncore.forcewake_count); |
|
405 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
443 | |
406 | if (--dev_priv->uncore.forcewake_count == 0) { |
444 | if (--dev_priv->uncore.forcewake_count == 0) { |
407 | dev_priv->uncore.forcewake_count++; |
445 | dev_priv->uncore.forcewake_count++; |
408 | mod_delayed_work(dev_priv->wq, |
446 | delayed = true; |
Line -... | Line 447... | ||
- | 447 | // mod_timer_pinned(&dev_priv->uncore.force_wake_timer, |
|
- | 448 | // GetTimerTicks() + 1); |
|
409 | &dev_priv->uncore.force_wake_work, |
449 | } |
410 | 1); |
450 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
Line -... | Line 451... | ||
- | 451 | ||
- | 452 | out: |
|
- | 453 | if (!delayed) |
|
- | 454 | intel_runtime_pm_put(dev_priv); |
|
- | 455 | } |
|
- | 456 | ||
- | 457 | void assert_force_wake_inactive(struct drm_i915_private *dev_priv) |
|
- | 458 | { |
|
411 | } |
459 | if (!dev_priv->uncore.funcs.force_wake_get) |
412 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
460 | return; |
413 | 461 | ||
Line -... | Line 462... | ||
- | 462 | WARN_ON(dev_priv->uncore.forcewake_count > 0); |
|
- | 463 | } |
|
- | 464 | ||
- | 465 | /* We give fast paths for the really cool registers */ |
|
- | 466 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ |
|
- | 467 | ((reg) < 0x40000 && (reg) != FORCEWAKE) |
|
- | 468 | ||
- | 469 | #define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end)) |
|
- | 470 | ||
- | 471 | #define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \ |
|
- | 472 | (REG_RANGE((reg), 0x2000, 0x4000) || \ |
|
- | 473 | REG_RANGE((reg), 0x5000, 0x8000) || \ |
|
- | 474 | REG_RANGE((reg), 0xB000, 0x12000) || \ |
|
- | 475 | REG_RANGE((reg), 0x2E000, 0x30000)) |
|
- | 476 | ||
- | 477 | #define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg) \ |
|
- | 478 | (REG_RANGE((reg), 0x12000, 0x14000) || \ |
|
- | 479 | REG_RANGE((reg), 0x22000, 0x24000) || \ |
|
- | 480 | REG_RANGE((reg), 0x30000, 0x40000)) |
|
- | 481 | ||
- | 482 | #define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \ |
|
- | 483 | (REG_RANGE((reg), 0x2000, 0x4000) || \ |
|
- | 484 | REG_RANGE((reg), 0x5000, 0x8000) || \ |
|
- | 485 | REG_RANGE((reg), 0x8300, 0x8500) || \ |
|
- | 486 | REG_RANGE((reg), 0xB000, 0xC000) || \ |
|
- | 487 | REG_RANGE((reg), 0xE000, 0xE800)) |
|
- | 488 | ||
- | 489 | #define FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg) \ |
|
- | 490 | (REG_RANGE((reg), 0x8800, 0x8900) || \ |
|
- | 491 | REG_RANGE((reg), 0xD000, 0xD800) || \ |
|
- | 492 | REG_RANGE((reg), 0x12000, 0x14000) || \ |
|
- | 493 | REG_RANGE((reg), 0x1A000, 0x1C000) || \ |
|
- | 494 | REG_RANGE((reg), 0x1E800, 0x1EA00) || \ |
|
- | 495 | REG_RANGE((reg), 0x30000, 0x40000)) |
|
- | 496 | ||
- | 497 | #define FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg) \ |
|
- | 498 | (REG_RANGE((reg), 0x4000, 0x5000) || \ |
|
- | 499 | REG_RANGE((reg), 0x8000, 0x8300) || \ |
|
414 | intel_runtime_pm_put(dev_priv); |
500 | REG_RANGE((reg), 0x8500, 0x8600) || \ |
415 | } |
501 | REG_RANGE((reg), 0x9000, 0xB000) || \ |
416 | 502 | REG_RANGE((reg), 0xC000, 0xC800) || \ |
|
417 | /* We give fast paths for the really cool registers */ |
503 | REG_RANGE((reg), 0xF000, 0x10000) || \ |
418 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ |
504 | REG_RANGE((reg), 0x14000, 0x14400) || \ |
419 | ((reg) < 0x40000 && (reg) != FORCEWAKE) |
505 | REG_RANGE((reg), 0x22000, 0x24000)) |
420 | 506 | ||
421 | static void |
507 | static void |
Line 422... | Line 508... | ||
422 | ilk_dummy_write(struct drm_i915_private *dev_priv) |
508 | ilk_dummy_write(struct drm_i915_private *dev_priv) |
423 | { |
509 | { |
- | 510 | /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up |
|
424 | /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up |
511 | * the chip from rc6 before touching it for real. MI_MODE is masked, |
- | 512 | * hence harmless to write 0 into. */ |
|
- | 513 | __raw_i915_write32(dev_priv, MI_MODE, 0); |
|
- | 514 | } |
|
- | 515 | ||
- | 516 | static void |
|
- | 517 | hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, u32 reg, bool read, |
|
425 | * the chip from rc6 before touching it for real. MI_MODE is masked, |
518 | bool before) |
426 | * hence harmless to write 0 into. */ |
519 | { |
427 | __raw_i915_write32(dev_priv, MI_MODE, 0); |
520 | const char *op = read ? "reading" : "writing to"; |
428 | } |
521 | const char *when = before ? "before" : "after"; |
429 | 522 | ||
430 | static void |
523 | if (!i915.mmio_debug) |
Line 431... | Line 524... | ||
431 | hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) |
524 | return; |
432 | { |
525 | |
433 | if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { |
526 | if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { |
- | 527 | WARN(1, "Unclaimed register detected %s %s register 0x%x\n", |
|
- | 528 | when, op, reg); |
|
- | 529 | __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); |
|
434 | DRM_ERROR("Unknown unclaimed register before writing to %x\n", |
530 | } |
435 | reg); |
531 | } |
436 | __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); |
532 | |
437 | } |
533 | static void |
438 | } |
534 | hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) |
Line 439... | Line -... | ||
439 | - | ||
440 | static void |
- | |
441 | hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) |
- | |
442 | { |
- | |
443 | if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { |
- | |
444 | DRM_ERROR("Unclaimed write to %x\n", reg); |
- | |
445 | __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); |
- | |
446 | } |
535 | { |
447 | } |
536 | if (i915.mmio_debug) |
448 | 537 | return; |
|
- | 538 | ||
449 | static void |
539 | if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { |
Line 450... | Line 540... | ||
450 | assert_device_not_suspended(struct drm_i915_private *dev_priv) |
540 | DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); |
451 | { |
541 | __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); |
452 | WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, |
542 | } |
Line 482... | Line 572... | ||
482 | 572 | ||
483 | #define __gen6_read(x) \ |
573 | #define __gen6_read(x) \ |
484 | static u##x \ |
574 | static u##x \ |
485 | gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
575 | gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
486 | REG_READ_HEADER(x); \ |
576 | REG_READ_HEADER(x); \ |
487 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
577 | hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ |
- | 578 | if (dev_priv->uncore.forcewake_count == 0 && \ |
|
488 | if (dev_priv->uncore.forcewake_count == 0) \ |
579 | NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
489 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
580 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
490 | FORCEWAKE_ALL); \ |
581 | FORCEWAKE_ALL); \ |
491 | val = __raw_i915_read##x(dev_priv, reg); \ |
- | |
492 | if (dev_priv->uncore.forcewake_count == 0) \ |
582 | val = __raw_i915_read##x(dev_priv, reg); \ |
493 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ |
583 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ |
494 | FORCEWAKE_ALL); \ |
584 | FORCEWAKE_ALL); \ |
495 | } else { \ |
585 | } else { \ |
496 | val = __raw_i915_read##x(dev_priv, reg); \ |
586 | val = __raw_i915_read##x(dev_priv, reg); \ |
- | 587 | } \ |
|
497 | } \ |
588 | hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \ |
498 | REG_READ_FOOTER; \ |
589 | REG_READ_FOOTER; \ |
Line 499... | Line 590... | ||
499 | } |
590 | } |
500 | 591 | ||
501 | #define __vlv_read(x) \ |
592 | #define __vlv_read(x) \ |
502 | static u##x \ |
593 | static u##x \ |
503 | vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
- | |
504 | unsigned fwengine = 0; \ |
594 | vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
505 | unsigned *fwcount; \ |
595 | unsigned fwengine = 0; \ |
- | 596 | REG_READ_HEADER(x); \ |
|
506 | REG_READ_HEADER(x); \ |
597 | if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \ |
507 | if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \ |
- | |
508 | fwengine = FORCEWAKE_RENDER; \ |
- | |
509 | fwcount = &dev_priv->uncore.fw_rendercount; \ |
598 | if (dev_priv->uncore.fw_rendercount == 0) \ |
- | 599 | fwengine = FORCEWAKE_RENDER; \ |
|
510 | } \ |
600 | } else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \ |
511 | else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \ |
- | |
512 | fwengine = FORCEWAKE_MEDIA; \ |
601 | if (dev_priv->uncore.fw_mediacount == 0) \ |
513 | fwcount = &dev_priv->uncore.fw_mediacount; \ |
602 | fwengine = FORCEWAKE_MEDIA; \ |
514 | } \ |
- | |
515 | if (fwengine != 0) { \ |
603 | } \ |
516 | if ((*fwcount)++ == 0) \ |
- | |
517 | (dev_priv)->uncore.funcs.force_wake_get(dev_priv, \ |
- | |
518 | fwengine); \ |
- | |
519 | val = __raw_i915_read##x(dev_priv, reg); \ |
- | |
520 | if (--(*fwcount) == 0) \ |
- | |
521 | (dev_priv)->uncore.funcs.force_wake_put(dev_priv, \ |
- | |
522 | fwengine); \ |
604 | if (fwengine) \ |
523 | } else { \ |
605 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \ |
- | 606 | val = __raw_i915_read##x(dev_priv, reg); \ |
|
524 | val = __raw_i915_read##x(dev_priv, reg); \ |
607 | if (fwengine) \ |
525 | } \ |
608 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \ |
Line -... | Line 609... | ||
- | 609 | REG_READ_FOOTER; \ |
|
- | 610 | } |
|
- | 611 | ||
- | 612 | #define __chv_read(x) \ |
|
- | 613 | static u##x \ |
|
- | 614 | chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ |
|
- | 615 | unsigned fwengine = 0; \ |
|
- | 616 | REG_READ_HEADER(x); \ |
|
- | 617 | if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \ |
|
- | 618 | if (dev_priv->uncore.fw_rendercount == 0) \ |
|
- | 619 | fwengine = FORCEWAKE_RENDER; \ |
|
- | 620 | } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \ |
|
- | 621 | if (dev_priv->uncore.fw_mediacount == 0) \ |
|
- | 622 | fwengine = FORCEWAKE_MEDIA; \ |
|
- | 623 | } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \ |
|
- | 624 | if (dev_priv->uncore.fw_rendercount == 0) \ |
|
- | 625 | fwengine |= FORCEWAKE_RENDER; \ |
|
- | 626 | if (dev_priv->uncore.fw_mediacount == 0) \ |
|
- | 627 | fwengine |= FORCEWAKE_MEDIA; \ |
|
- | 628 | } \ |
|
- | 629 | if (fwengine) \ |
|
- | 630 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \ |
|
- | 631 | val = __raw_i915_read##x(dev_priv, reg); \ |
|
- | 632 | if (fwengine) \ |
|
Line -... | Line 633... | ||
- | 633 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \ |
|
- | 634 | REG_READ_FOOTER; \ |
|
- | 635 | } |
|
- | 636 | ||
526 | REG_READ_FOOTER; \ |
637 | __chv_read(8) |
527 | } |
638 | __chv_read(16) |
528 | 639 | __chv_read(32) |
|
529 | 640 | __chv_read(64) |
|
530 | __vlv_read(8) |
641 | __vlv_read(8) |
Line 542... | Line 653... | ||
542 | __gen4_read(8) |
653 | __gen4_read(8) |
543 | __gen4_read(16) |
654 | __gen4_read(16) |
544 | __gen4_read(32) |
655 | __gen4_read(32) |
545 | __gen4_read(64) |
656 | __gen4_read(64) |
Line -... | Line 657... | ||
- | 657 | ||
546 | 658 | #undef __chv_read |
|
547 | #undef __vlv_read |
659 | #undef __vlv_read |
548 | #undef __gen6_read |
660 | #undef __gen6_read |
549 | #undef __gen5_read |
661 | #undef __gen5_read |
550 | #undef __gen4_read |
662 | #undef __gen4_read |
551 | #undef REG_READ_FOOTER |
663 | #undef REG_READ_FOOTER |
Line 552... | Line 664... | ||
552 | #undef REG_READ_HEADER |
664 | #undef REG_READ_HEADER |
553 | 665 | ||
554 | #define REG_WRITE_HEADER \ |
666 | #define REG_WRITE_HEADER \ |
- | 667 | unsigned long irqflags; \ |
|
555 | unsigned long irqflags; \ |
668 | trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ |
Line 556... | Line 669... | ||
556 | trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ |
669 | assert_device_not_suspended(dev_priv); \ |
557 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) |
670 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) |
Line 582... | Line 695... | ||
582 | u32 __fifo_ret = 0; \ |
695 | u32 __fifo_ret = 0; \ |
583 | REG_WRITE_HEADER; \ |
696 | REG_WRITE_HEADER; \ |
584 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
697 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
585 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
698 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
586 | } \ |
699 | } \ |
587 | assert_device_not_suspended(dev_priv); \ |
- | |
588 | __raw_i915_write##x(dev_priv, reg, val); \ |
700 | __raw_i915_write##x(dev_priv, reg, val); \ |
589 | if (unlikely(__fifo_ret)) { \ |
701 | if (unlikely(__fifo_ret)) { \ |
590 | gen6_gt_check_fifodbg(dev_priv); \ |
702 | gen6_gt_check_fifodbg(dev_priv); \ |
591 | } \ |
703 | } \ |
592 | REG_WRITE_FOOTER; \ |
704 | REG_WRITE_FOOTER; \ |
Line 598... | Line 710... | ||
598 | u32 __fifo_ret = 0; \ |
710 | u32 __fifo_ret = 0; \ |
599 | REG_WRITE_HEADER; \ |
711 | REG_WRITE_HEADER; \ |
600 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
712 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
601 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
713 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
602 | } \ |
714 | } \ |
603 | assert_device_not_suspended(dev_priv); \ |
- | |
604 | hsw_unclaimed_reg_clear(dev_priv, reg); \ |
715 | hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ |
605 | __raw_i915_write##x(dev_priv, reg, val); \ |
716 | __raw_i915_write##x(dev_priv, reg, val); \ |
606 | if (unlikely(__fifo_ret)) { \ |
717 | if (unlikely(__fifo_ret)) { \ |
607 | gen6_gt_check_fifodbg(dev_priv); \ |
718 | gen6_gt_check_fifodbg(dev_priv); \ |
608 | } \ |
719 | } \ |
- | 720 | hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ |
|
609 | hsw_unclaimed_reg_check(dev_priv, reg); \ |
721 | hsw_unclaimed_reg_detect(dev_priv); \ |
610 | REG_WRITE_FOOTER; \ |
722 | REG_WRITE_FOOTER; \ |
611 | } |
723 | } |
Line 612... | Line 724... | ||
612 | 724 | ||
613 | static const u32 gen8_shadowed_regs[] = { |
725 | static const u32 gen8_shadowed_regs[] = { |
Line 632... | Line 744... | ||
632 | } |
744 | } |
Line 633... | Line 745... | ||
633 | 745 | ||
634 | #define __gen8_write(x) \ |
746 | #define __gen8_write(x) \ |
635 | static void \ |
747 | static void \ |
636 | gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ |
- | |
637 | bool __needs_put = reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg); \ |
748 | gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ |
- | 749 | REG_WRITE_HEADER; \ |
|
- | 750 | hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ |
|
638 | REG_WRITE_HEADER; \ |
751 | if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \ |
639 | if (__needs_put) { \ |
752 | if (dev_priv->uncore.forcewake_count == 0) \ |
640 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
753 | dev_priv->uncore.funcs.force_wake_get(dev_priv, \ |
641 | FORCEWAKE_ALL); \ |
- | |
642 | } \ |
754 | FORCEWAKE_ALL); \ |
643 | __raw_i915_write##x(dev_priv, reg, val); \ |
755 | __raw_i915_write##x(dev_priv, reg, val); \ |
644 | if (__needs_put) { \ |
756 | if (dev_priv->uncore.forcewake_count == 0) \ |
645 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ |
757 | dev_priv->uncore.funcs.force_wake_put(dev_priv, \ |
- | 758 | FORCEWAKE_ALL); \ |
|
- | 759 | } else { \ |
|
646 | FORCEWAKE_ALL); \ |
760 | __raw_i915_write##x(dev_priv, reg, val); \ |
- | 761 | } \ |
|
- | 762 | hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ |
|
647 | } \ |
763 | hsw_unclaimed_reg_detect(dev_priv); \ |
648 | REG_WRITE_FOOTER; \ |
764 | REG_WRITE_FOOTER; \ |
Line -... | Line 765... | ||
- | 765 | } |
|
- | 766 | ||
- | 767 | #define __chv_write(x) \ |
|
- | 768 | static void \ |
|
- | 769 | chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ |
|
- | 770 | unsigned fwengine = 0; \ |
|
- | 771 | bool shadowed = is_gen8_shadowed(dev_priv, reg); \ |
|
- | 772 | REG_WRITE_HEADER; \ |
|
- | 773 | if (!shadowed) { \ |
|
- | 774 | if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \ |
|
- | 775 | if (dev_priv->uncore.fw_rendercount == 0) \ |
|
- | 776 | fwengine = FORCEWAKE_RENDER; \ |
|
- | 777 | } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \ |
|
- | 778 | if (dev_priv->uncore.fw_mediacount == 0) \ |
|
- | 779 | fwengine = FORCEWAKE_MEDIA; \ |
|
- | 780 | } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \ |
|
- | 781 | if (dev_priv->uncore.fw_rendercount == 0) \ |
|
- | 782 | fwengine |= FORCEWAKE_RENDER; \ |
|
- | 783 | if (dev_priv->uncore.fw_mediacount == 0) \ |
|
- | 784 | fwengine |= FORCEWAKE_MEDIA; \ |
|
- | 785 | } \ |
|
- | 786 | } \ |
|
- | 787 | if (fwengine) \ |
|
- | 788 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \ |
|
- | 789 | __raw_i915_write##x(dev_priv, reg, val); \ |
|
- | 790 | if (fwengine) \ |
|
- | 791 | dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \ |
|
- | 792 | REG_WRITE_FOOTER; \ |
|
- | 793 | } |
|
- | 794 | ||
- | 795 | __chv_write(8) |
|
- | 796 | __chv_write(16) |
|
649 | } |
797 | __chv_write(32) |
650 | 798 | __chv_write(64) |
|
651 | __gen8_write(8) |
799 | __gen8_write(8) |
652 | __gen8_write(16) |
800 | __gen8_write(16) |
653 | __gen8_write(32) |
801 | __gen8_write(32) |
Line 667... | Line 815... | ||
667 | __gen4_write(8) |
815 | __gen4_write(8) |
668 | __gen4_write(16) |
816 | __gen4_write(16) |
669 | __gen4_write(32) |
817 | __gen4_write(32) |
670 | __gen4_write(64) |
818 | __gen4_write(64) |
Line -... | Line 819... | ||
- | 819 | ||
671 | 820 | #undef __chv_write |
|
672 | #undef __gen8_write |
821 | #undef __gen8_write |
673 | #undef __hsw_write |
822 | #undef __hsw_write |
674 | #undef __gen6_write |
823 | #undef __gen6_write |
675 | #undef __gen5_write |
824 | #undef __gen5_write |
Line 679... | Line 828... | ||
679 | 828 | ||
680 | void intel_uncore_init(struct drm_device *dev) |
829 | void intel_uncore_init(struct drm_device *dev) |
681 | { |
830 | { |
Line 682... | Line 831... | ||
682 | struct drm_i915_private *dev_priv = dev->dev_private; |
831 | struct drm_i915_private *dev_priv = dev->dev_private; |
683 | 832 | ||
- | 833 | setup_timer(&dev_priv->uncore.force_wake_timer, |
|
- | 834 | gen6_force_wake_timer, (unsigned long)dev_priv); |
|
Line 684... | Line 835... | ||
684 | INIT_DELAYED_WORK(&dev_priv->uncore.force_wake_work, |
835 | |
685 | gen6_force_wake_work); |
836 | intel_uncore_early_sanitize(dev, false); |
686 | 837 | ||
687 | if (IS_VALLEYVIEW(dev)) { |
838 | if (IS_VALLEYVIEW(dev)) { |
688 | dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; |
839 | dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get; |
689 | dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put; |
840 | dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put; |
690 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { |
841 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { |
691 | dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; |
842 | dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get; |
Line 692... | Line 843... | ||
692 | dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; |
843 | dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put; |
Line 701... | Line 852... | ||
701 | * ECOBUS read will return zero. Which will be |
852 | * ECOBUS read will return zero. Which will be |
702 | * (correctly) interpreted by the test below as MT |
853 | * (correctly) interpreted by the test below as MT |
703 | * forcewake being disabled. |
854 | * forcewake being disabled. |
704 | */ |
855 | */ |
705 | mutex_lock(&dev->struct_mutex); |
856 | mutex_lock(&dev->struct_mutex); |
706 | __gen6_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL); |
857 | __gen7_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL); |
707 | ecobus = __raw_i915_read32(dev_priv, ECOBUS); |
858 | ecobus = __raw_i915_read32(dev_priv, ECOBUS); |
708 | __gen6_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL); |
859 | __gen7_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL); |
709 | mutex_unlock(&dev->struct_mutex); |
860 | mutex_unlock(&dev->struct_mutex); |
Line 710... | Line 861... | ||
710 | 861 | ||
711 | if (ecobus & FORCEWAKE_MT_ENABLE) { |
862 | if (ecobus & FORCEWAKE_MT_ENABLE) { |
712 | dev_priv->uncore.funcs.force_wake_get = |
863 | dev_priv->uncore.funcs.force_wake_get = |
713 | __gen6_gt_force_wake_mt_get; |
864 | __gen7_gt_force_wake_mt_get; |
714 | dev_priv->uncore.funcs.force_wake_put = |
865 | dev_priv->uncore.funcs.force_wake_put = |
715 | __gen6_gt_force_wake_mt_put; |
866 | __gen7_gt_force_wake_mt_put; |
716 | } else { |
867 | } else { |
717 | DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); |
868 | DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); |
718 | DRM_INFO("when using vblank-synced partial screen updates.\n"); |
869 | DRM_INFO("when using vblank-synced partial screen updates.\n"); |
719 | dev_priv->uncore.funcs.force_wake_get = |
870 | dev_priv->uncore.funcs.force_wake_get = |
Line 728... | Line 879... | ||
728 | __gen6_gt_force_wake_put; |
879 | __gen6_gt_force_wake_put; |
729 | } |
880 | } |
Line 730... | Line 881... | ||
730 | 881 | ||
731 | switch (INTEL_INFO(dev)->gen) { |
882 | switch (INTEL_INFO(dev)->gen) { |
- | 883 | default: |
|
- | 884 | if (IS_CHERRYVIEW(dev)) { |
|
- | 885 | dev_priv->uncore.funcs.mmio_writeb = chv_write8; |
|
- | 886 | dev_priv->uncore.funcs.mmio_writew = chv_write16; |
|
- | 887 | dev_priv->uncore.funcs.mmio_writel = chv_write32; |
|
- | 888 | dev_priv->uncore.funcs.mmio_writeq = chv_write64; |
|
- | 889 | dev_priv->uncore.funcs.mmio_readb = chv_read8; |
|
- | 890 | dev_priv->uncore.funcs.mmio_readw = chv_read16; |
|
- | 891 | dev_priv->uncore.funcs.mmio_readl = chv_read32; |
|
- | 892 | dev_priv->uncore.funcs.mmio_readq = chv_read64; |
|
- | 893 | ||
732 | default: |
894 | } else { |
733 | dev_priv->uncore.funcs.mmio_writeb = gen8_write8; |
895 | dev_priv->uncore.funcs.mmio_writeb = gen8_write8; |
734 | dev_priv->uncore.funcs.mmio_writew = gen8_write16; |
896 | dev_priv->uncore.funcs.mmio_writew = gen8_write16; |
735 | dev_priv->uncore.funcs.mmio_writel = gen8_write32; |
897 | dev_priv->uncore.funcs.mmio_writel = gen8_write32; |
736 | dev_priv->uncore.funcs.mmio_writeq = gen8_write64; |
898 | dev_priv->uncore.funcs.mmio_writeq = gen8_write64; |
737 | dev_priv->uncore.funcs.mmio_readb = gen6_read8; |
899 | dev_priv->uncore.funcs.mmio_readb = gen6_read8; |
738 | dev_priv->uncore.funcs.mmio_readw = gen6_read16; |
900 | dev_priv->uncore.funcs.mmio_readw = gen6_read16; |
739 | dev_priv->uncore.funcs.mmio_readl = gen6_read32; |
901 | dev_priv->uncore.funcs.mmio_readl = gen6_read32; |
- | 902 | dev_priv->uncore.funcs.mmio_readq = gen6_read64; |
|
740 | dev_priv->uncore.funcs.mmio_readq = gen6_read64; |
903 | } |
741 | break; |
904 | break; |
742 | case 7: |
905 | case 7: |
743 | case 6: |
906 | case 6: |
744 | if (IS_HASWELL(dev)) { |
907 | if (IS_HASWELL(dev)) { |
Line 790... | Line 953... | ||
790 | } |
953 | } |
791 | } |
954 | } |
Line 792... | Line 955... | ||
792 | 955 | ||
793 | void intel_uncore_fini(struct drm_device *dev) |
956 | void intel_uncore_fini(struct drm_device *dev) |
794 | { |
- | |
795 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
796 | - | ||
797 | // flush_delayed_work(&dev_priv->uncore.force_wake_work); |
- | |
798 | 957 | { |
|
799 | /* Paranoia: make sure we have disabled everything before we exit. */ |
958 | /* Paranoia: make sure we have disabled everything before we exit. */ |
- | 959 | intel_uncore_sanitize(dev); |
|
800 | intel_uncore_sanitize(dev); |
960 | intel_uncore_forcewake_reset(dev, false); |
Line -... | Line 961... | ||
- | 961 | } |
|
- | 962 | ||
801 | } |
963 | #define GEN_RANGE(l, h) GENMASK(h, l) |
802 | 964 | ||
803 | static const struct register_whitelist { |
965 | static const struct register_whitelist { |
804 | uint64_t offset; |
966 | uint64_t offset; |
- | 967 | uint32_t size; |
|
805 | uint32_t size; |
968 | /* supported gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ |
806 | uint32_t gen_bitmask; /* support gens, 0x10 for 4, 0x30 for 4 and 5, etc. */ |
969 | uint32_t gen_bitmask; |
807 | } whitelist[] = { |
970 | } whitelist[] = { |
Line 808... | Line 971... | ||
808 | { RING_TIMESTAMP(RENDER_RING_BASE), 8, 0x1F0 }, |
971 | { RING_TIMESTAMP(RENDER_RING_BASE), 8, GEN_RANGE(4, 8) }, |
809 | }; |
972 | }; |
810 | 973 | ||
811 | int i915_reg_read_ioctl(struct drm_device *dev, |
974 | int i915_reg_read_ioctl(struct drm_device *dev, |
812 | void *data, struct drm_file *file) |
975 | void *data, struct drm_file *file) |
813 | { |
976 | { |
814 | struct drm_i915_private *dev_priv = dev->dev_private; |
977 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 815... | Line 978... | ||
815 | struct drm_i915_reg_read *reg = data; |
978 | struct drm_i915_reg_read *reg = data; |
816 | struct register_whitelist const *entry = whitelist; |
979 | struct register_whitelist const *entry = whitelist; |
817 | int i; |
980 | int i, ret = 0; |
818 | 981 | ||
Line 838... | Line 1001... | ||
838 | case 1: |
1001 | case 1: |
839 | reg->val = I915_READ8(reg->offset); |
1002 | reg->val = I915_READ8(reg->offset); |
840 | break; |
1003 | break; |
841 | default: |
1004 | default: |
842 | WARN_ON(1); |
1005 | WARN_ON(1); |
843 | return -EINVAL; |
1006 | ret = -EINVAL; |
- | 1007 | goto out; |
|
844 | } |
1008 | } |
Line -... | Line 1009... | ||
- | 1009 | ||
845 | 1010 | out: |
|
846 | return 0; |
1011 | return ret; |
Line 847... | Line 1012... | ||
847 | } |
1012 | } |
848 | 1013 | ||
849 | int i915_get_reset_stats_ioctl(struct drm_device *dev, |
1014 | int i915_get_reset_stats_ioctl(struct drm_device *dev, |
850 | void *data, struct drm_file *file) |
1015 | void *data, struct drm_file *file) |
851 | { |
1016 | { |
852 | struct drm_i915_private *dev_priv = dev->dev_private; |
1017 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 1018 | struct drm_i915_reset_stats *args = data; |
|
853 | struct drm_i915_reset_stats *args = data; |
1019 | struct i915_ctx_hang_stats *hs; |
Line 854... | Line 1020... | ||
854 | struct i915_ctx_hang_stats *hs; |
1020 | struct intel_context *ctx; |
855 | int ret; |
1021 | int ret; |
Line 856... | Line -... | ||
856 | - | ||
857 | if (args->flags || args->pad) |
- | |
858 | return -EINVAL; |
- | |
859 | 1022 | ||
860 | if (args->ctx_id == DEFAULT_CONTEXT_ID) |
1023 | if (args->flags || args->pad) |
861 | return -EPERM; |
1024 | return -EINVAL; |
Line 862... | Line 1025... | ||
862 | 1025 | ||
863 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
1026 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
864 | if (ret) |
1027 | if (ret) |
865 | return ret; |
1028 | return ret; |
866 | 1029 | ||
- | 1030 | ctx = i915_gem_context_get(file->driver_priv, args->ctx_id); |
|
Line 867... | Line 1031... | ||
867 | hs = i915_gem_context_get_hang_stats(dev, file, args->ctx_id); |
1031 | if (IS_ERR(ctx)) { |
Line 868... | Line 1032... | ||
868 | if (IS_ERR(hs)) { |
1032 | mutex_unlock(&dev->struct_mutex); |
869 | mutex_unlock(&dev->struct_mutex); |
1033 | return PTR_ERR(ctx); |
Line 889... | Line 1053... | ||
889 | 1053 | ||
890 | static int i965_do_reset(struct drm_device *dev) |
1054 | static int i965_do_reset(struct drm_device *dev) |
891 | { |
1055 | { |
Line -... | Line 1056... | ||
- | 1056 | int ret; |
|
- | 1057 | ||
- | 1058 | /* FIXME: i965g/gm need a display save/restore for gpu reset. */ |
|
892 | int ret; |
1059 | return -ENODEV; |
893 | 1060 | ||
894 | /* |
1061 | /* |
895 | * Set the domains we want to reset (GRDOM/bits 2 and 3) as |
1062 | * Set the domains we want to reset (GRDOM/bits 2 and 3) as |
896 | * well as the reset bit (GR/bit 0). Setting the GR bit |
1063 | * well as the reset bit (GR/bit 0). Setting the GR bit |
Line 900... | Line 1067... | ||
900 | GRDOM_RENDER | GRDOM_RESET_ENABLE); |
1067 | GRDOM_RENDER | GRDOM_RESET_ENABLE); |
901 | ret = wait_for(i965_reset_complete(dev), 500); |
1068 | ret = wait_for(i965_reset_complete(dev), 500); |
902 | if (ret) |
1069 | if (ret) |
903 | return ret; |
1070 | return ret; |
Line 904... | Line -... | ||
904 | - | ||
905 | /* We can't reset render&media without also resetting display ... */ |
1071 | |
906 | pci_write_config_byte(dev->pdev, I965_GDRST, |
1072 | pci_write_config_byte(dev->pdev, I965_GDRST, |
Line 907... | Line 1073... | ||
907 | GRDOM_MEDIA | GRDOM_RESET_ENABLE); |
1073 | GRDOM_MEDIA | GRDOM_RESET_ENABLE); |
908 | 1074 | ||
Line 913... | Line 1079... | ||
913 | pci_write_config_byte(dev->pdev, I965_GDRST, 0); |
1079 | pci_write_config_byte(dev->pdev, I965_GDRST, 0); |
Line 914... | Line 1080... | ||
914 | 1080 | ||
915 | return 0; |
1081 | return 0; |
Line -... | Line 1082... | ||
- | 1082 | } |
|
- | 1083 | ||
- | 1084 | static int g4x_do_reset(struct drm_device *dev) |
|
- | 1085 | { |
|
- | 1086 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1087 | int ret; |
|
- | 1088 | ||
- | 1089 | pci_write_config_byte(dev->pdev, I965_GDRST, |
|
- | 1090 | GRDOM_RENDER | GRDOM_RESET_ENABLE); |
|
- | 1091 | ret = wait_for(i965_reset_complete(dev), 500); |
|
- | 1092 | if (ret) |
|
- | 1093 | return ret; |
|
- | 1094 | ||
- | 1095 | /* WaVcpClkGateDisableForMediaReset:ctg,elk */ |
|
- | 1096 | I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE); |
|
- | 1097 | POSTING_READ(VDECCLK_GATE_D); |
|
- | 1098 | ||
- | 1099 | pci_write_config_byte(dev->pdev, I965_GDRST, |
|
- | 1100 | GRDOM_MEDIA | GRDOM_RESET_ENABLE); |
|
- | 1101 | ret = wait_for(i965_reset_complete(dev), 500); |
|
- | 1102 | if (ret) |
|
- | 1103 | return ret; |
|
- | 1104 | ||
- | 1105 | /* WaVcpClkGateDisableForMediaReset:ctg,elk */ |
|
- | 1106 | I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE); |
|
- | 1107 | POSTING_READ(VDECCLK_GATE_D); |
|
- | 1108 | ||
- | 1109 | pci_write_config_byte(dev->pdev, I965_GDRST, 0); |
|
- | 1110 | ||
- | 1111 | return 0; |
|
916 | } |
1112 | } |
917 | 1113 | ||
918 | static int ironlake_do_reset(struct drm_device *dev) |
1114 | static int ironlake_do_reset(struct drm_device *dev) |
919 | { |
- | |
920 | struct drm_i915_private *dev_priv = dev->dev_private; |
1115 | { |
Line 921... | Line -... | ||
921 | u32 gdrst; |
- | |
922 | int ret; |
- | |
923 | 1116 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
924 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); |
1117 | int ret; |
925 | gdrst &= ~GRDOM_MASK; |
1118 | |
- | 1119 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
|
926 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
1120 | ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE); |
927 | gdrst | GRDOM_RENDER | GRDOM_RESET_ENABLE); |
1121 | ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & |
Line 928... | Line -... | ||
928 | ret = wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); |
- | |
929 | if (ret) |
- | |
930 | return ret; |
- | |
931 | 1122 | ILK_GRDOM_RESET_ENABLE) == 0, 500); |
|
932 | /* We can't reset render&media without also resetting display ... */ |
1123 | if (ret) |
933 | gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); |
1124 | return ret; |
- | 1125 | ||
- | 1126 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
|
- | 1127 | ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE); |
|
- | 1128 | ret = wait_for((I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & |
|
- | 1129 | ILK_GRDOM_RESET_ENABLE) == 0, 500); |
|
- | 1130 | if (ret) |
|
- | 1131 | return ret; |
|
934 | gdrst &= ~GRDOM_MASK; |
1132 | |
Line 935... | Line 1133... | ||
935 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, |
1133 | I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, 0); |
936 | gdrst | GRDOM_MEDIA | GRDOM_RESET_ENABLE); |
1134 | |
937 | return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); |
1135 | return 0; |
938 | } |
1136 | } |
939 | - | ||
940 | static int gen6_do_reset(struct drm_device *dev) |
- | |
941 | { |
- | |
942 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
943 | int ret; |
- | |
944 | unsigned long irqflags; |
- | |
Line 945... | Line 1137... | ||
945 | 1137 | ||
Line 946... | Line 1138... | ||
946 | /* Hold uncore.lock across reset to prevent any register access |
1138 | static int gen6_do_reset(struct drm_device *dev) |
947 | * with forcewake not set correctly |
1139 | { |
Line 957... | Line 1149... | ||
957 | __raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL); |
1149 | __raw_i915_write32(dev_priv, GEN6_GDRST, GEN6_GRDOM_FULL); |
Line 958... | Line 1150... | ||
958 | 1150 | ||
959 | /* Spin waiting for the device to ack the reset request */ |
1151 | /* Spin waiting for the device to ack the reset request */ |
Line 960... | Line 1152... | ||
960 | ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); |
1152 | ret = wait_for((__raw_i915_read32(dev_priv, GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); |
961 | - | ||
962 | intel_uncore_forcewake_reset(dev); |
- | |
963 | - | ||
964 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ |
- | |
965 | if (dev_priv->uncore.forcewake_count) |
- | |
966 | dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL); |
- | |
967 | else |
- | |
968 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); |
- | |
969 | - | ||
Line 970... | Line -... | ||
970 | /* Restore fifo count */ |
- | |
971 | dev_priv->uncore.fifo_count = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK; |
1153 | |
972 | 1154 | intel_uncore_forcewake_reset(dev, true); |
|
Line 973... | Line 1155... | ||
973 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
1155 | |
974 | return ret; |
1156 | return ret; |
975 | } |
1157 | } |
976 | 1158 | ||
977 | int intel_gpu_reset(struct drm_device *dev) |
1159 | int intel_gpu_reset(struct drm_device *dev) |
978 | { |
1160 | { |
- | 1161 | if (INTEL_INFO(dev)->gen >= 6) |
|
979 | switch (INTEL_INFO(dev)->gen) { |
1162 | return gen6_do_reset(dev); |
- | 1163 | else if (IS_GEN5(dev)) |
|
980 | case 8: |
1164 | return ironlake_do_reset(dev); |
- | 1165 | else if (IS_G4X(dev)) |
|
981 | case 7: |
1166 | return g4x_do_reset(dev); |
982 | case 6: return gen6_do_reset(dev); |
- | |
983 | case 5: return ironlake_do_reset(dev); |
1167 | else if (IS_GEN4(dev)) |
Line 984... | Line 1168... | ||
984 | case 4: return i965_do_reset(dev); |
1168 | return i965_do_reset(dev); |
985 | default: return -ENODEV; |
1169 | else |
986 | } |
1170 | return -ENODEV; |