aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2014-05-30 13:36:49 -0400
committerKukjin Kim <kgene.kim@samsung.com>2014-05-30 13:36:49 -0400
commitfced6dee29f6fb143fe16ea90331176ff77e6120 (patch)
tree5b6e57e7a757adc2a6518ce291a4d2914397b917 /drivers/gpu/drm/i915
parentbfed1074f213051e94648bfad0d0611a16d81366 (diff)
parentbe1f7c8d7e2bc8b8c76846aa6f276e8d2ef8975a (diff)
Merge branch 'v3.16-next/cleanup-samsung' into v3.16-next/platform-exynos
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h9
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c218
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c18
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c10
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c23
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c18
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c10
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c9
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c5
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c10
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c54
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h1
18 files changed, 222 insertions, 176 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0905cd915589..ec82f6bff122 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1308,6 +1308,7 @@ struct intel_vbt_data {
1308 1308
1309 struct { 1309 struct {
1310 u16 pwm_freq_hz; 1310 u16 pwm_freq_hz;
1311 bool present;
1311 bool active_low_pwm; 1312 bool active_low_pwm;
1312 } backlight; 1313 } backlight;
1313 1314
@@ -2431,20 +2432,18 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
2431int i915_gem_context_enable(struct drm_i915_private *dev_priv); 2432int i915_gem_context_enable(struct drm_i915_private *dev_priv);
2432void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); 2433void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
2433int i915_switch_context(struct intel_ring_buffer *ring, 2434int i915_switch_context(struct intel_ring_buffer *ring,
2434 struct drm_file *file, struct i915_hw_context *to); 2435 struct i915_hw_context *to);
2435struct i915_hw_context * 2436struct i915_hw_context *
2436i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); 2437i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
2437void i915_gem_context_free(struct kref *ctx_ref); 2438void i915_gem_context_free(struct kref *ctx_ref);
2438static inline void i915_gem_context_reference(struct i915_hw_context *ctx) 2439static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
2439{ 2440{
2440 if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev)) 2441 kref_get(&ctx->ref);
2441 kref_get(&ctx->ref);
2442} 2442}
2443 2443
2444static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) 2444static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
2445{ 2445{
2446 if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev)) 2446 kref_put(&ctx->ref, i915_gem_context_free);
2447 kref_put(&ctx->ref, i915_gem_context_free);
2448} 2447}
2449 2448
2450static inline bool i915_gem_context_is_default(const struct i915_hw_context *c) 2449static inline bool i915_gem_context_is_default(const struct i915_hw_context *c)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6370a761d137..2871ce75f438 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev)
2790 2790
2791 /* Flush everything onto the inactive list. */ 2791 /* Flush everything onto the inactive list. */
2792 for_each_ring(ring, dev_priv, i) { 2792 for_each_ring(ring, dev_priv, i) {
2793 ret = i915_switch_context(ring, NULL, ring->default_context); 2793 ret = i915_switch_context(ring, ring->default_context);
2794 if (ret) 2794 if (ret)
2795 return ret; 2795 return ret;
2796 2796
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6043062ffce7..d72db15afa02 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -96,9 +96,6 @@
96#define GEN6_CONTEXT_ALIGN (64<<10) 96#define GEN6_CONTEXT_ALIGN (64<<10)
97#define GEN7_CONTEXT_ALIGN 4096 97#define GEN7_CONTEXT_ALIGN 4096
98 98
99static int do_switch(struct intel_ring_buffer *ring,
100 struct i915_hw_context *to);
101
102static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) 99static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
103{ 100{
104 struct drm_device *dev = ppgtt->base.dev; 101 struct drm_device *dev = ppgtt->base.dev;
@@ -185,13 +182,15 @@ void i915_gem_context_free(struct kref *ctx_ref)
185 typeof(*ctx), ref); 182 typeof(*ctx), ref);
186 struct i915_hw_ppgtt *ppgtt = NULL; 183 struct i915_hw_ppgtt *ppgtt = NULL;
187 184
188 /* We refcount even the aliasing PPGTT to keep the code symmetric */ 185 if (ctx->obj) {
189 if (USES_PPGTT(ctx->obj->base.dev)) 186 /* We refcount even the aliasing PPGTT to keep the code symmetric */
190 ppgtt = ctx_to_ppgtt(ctx); 187 if (USES_PPGTT(ctx->obj->base.dev))
188 ppgtt = ctx_to_ppgtt(ctx);
191 189
192 /* XXX: Free up the object before tearing down the address space, in 190 /* XXX: Free up the object before tearing down the address space, in
193 * case we're bound in the PPGTT */ 191 * case we're bound in the PPGTT */
194 drm_gem_object_unreference(&ctx->obj->base); 192 drm_gem_object_unreference(&ctx->obj->base);
193 }
195 194
196 if (ppgtt) 195 if (ppgtt)
197 kref_put(&ppgtt->ref, ppgtt_release); 196 kref_put(&ppgtt->ref, ppgtt_release);
@@ -232,32 +231,32 @@ __create_hw_context(struct drm_device *dev,
232 return ERR_PTR(-ENOMEM); 231 return ERR_PTR(-ENOMEM);
233 232
234 kref_init(&ctx->ref); 233 kref_init(&ctx->ref);
235 ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); 234 list_add_tail(&ctx->link, &dev_priv->context_list);
236 INIT_LIST_HEAD(&ctx->link);
237 if (ctx->obj == NULL) {
238 kfree(ctx);
239 DRM_DEBUG_DRIVER("Context object allocated failed\n");
240 return ERR_PTR(-ENOMEM);
241 }
242 235
243 if (INTEL_INFO(dev)->gen >= 7) { 236 if (dev_priv->hw_context_size) {
244 ret = i915_gem_object_set_cache_level(ctx->obj, 237 ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
245 I915_CACHE_L3_LLC); 238 if (ctx->obj == NULL) {
246 /* Failure shouldn't ever happen this early */ 239 ret = -ENOMEM;
247 if (WARN_ON(ret))
248 goto err_out; 240 goto err_out;
249 } 241 }
250 242
251 list_add_tail(&ctx->link, &dev_priv->context_list); 243 if (INTEL_INFO(dev)->gen >= 7) {
244 ret = i915_gem_object_set_cache_level(ctx->obj,
245 I915_CACHE_L3_LLC);
246 /* Failure shouldn't ever happen this early */
247 if (WARN_ON(ret))
248 goto err_out;
249 }
250 }
252 251
253 /* Default context will never have a file_priv */ 252 /* Default context will never have a file_priv */
254 if (file_priv == NULL) 253 if (file_priv != NULL) {
255 return ctx; 254 ret = idr_alloc(&file_priv->context_idr, ctx,
256 255 DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
257 ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0, 256 if (ret < 0)
258 GFP_KERNEL); 257 goto err_out;
259 if (ret < 0) 258 } else
260 goto err_out; 259 ret = DEFAULT_CONTEXT_ID;
261 260
262 ctx->file_priv = file_priv; 261 ctx->file_priv = file_priv;
263 ctx->id = ret; 262 ctx->id = ret;
@@ -294,7 +293,7 @@ i915_gem_create_context(struct drm_device *dev,
294 if (IS_ERR(ctx)) 293 if (IS_ERR(ctx))
295 return ctx; 294 return ctx;
296 295
297 if (is_global_default_ctx) { 296 if (is_global_default_ctx && ctx->obj) {
298 /* We may need to do things with the shrinker which 297 /* We may need to do things with the shrinker which
299 * require us to immediately switch back to the default 298 * require us to immediately switch back to the default
300 * context. This can cause a problem as pinning the 299 * context. This can cause a problem as pinning the
@@ -342,7 +341,7 @@ i915_gem_create_context(struct drm_device *dev,
342 return ctx; 341 return ctx;
343 342
344err_unpin: 343err_unpin:
345 if (is_global_default_ctx) 344 if (is_global_default_ctx && ctx->obj)
346 i915_gem_object_ggtt_unpin(ctx->obj); 345 i915_gem_object_ggtt_unpin(ctx->obj);
347err_destroy: 346err_destroy:
348 i915_gem_context_unreference(ctx); 347 i915_gem_context_unreference(ctx);
@@ -352,32 +351,22 @@ err_destroy:
352void i915_gem_context_reset(struct drm_device *dev) 351void i915_gem_context_reset(struct drm_device *dev)
353{ 352{
354 struct drm_i915_private *dev_priv = dev->dev_private; 353 struct drm_i915_private *dev_priv = dev->dev_private;
355 struct intel_ring_buffer *ring;
356 int i; 354 int i;
357 355
358 if (!HAS_HW_CONTEXTS(dev))
359 return;
360
361 /* Prevent the hardware from restoring the last context (which hung) on 356 /* Prevent the hardware from restoring the last context (which hung) on
362 * the next switch */ 357 * the next switch */
363 for (i = 0; i < I915_NUM_RINGS; i++) { 358 for (i = 0; i < I915_NUM_RINGS; i++) {
364 struct i915_hw_context *dctx; 359 struct intel_ring_buffer *ring = &dev_priv->ring[i];
365 if (!(INTEL_INFO(dev)->ring_mask & (1<<i))) 360 struct i915_hw_context *dctx = ring->default_context;
366 continue;
367 361
368 /* Do a fake switch to the default context */ 362 /* Do a fake switch to the default context */
369 ring = &dev_priv->ring[i]; 363 if (ring->last_context == dctx)
370 dctx = ring->default_context;
371 if (WARN_ON(!dctx))
372 continue; 364 continue;
373 365
374 if (!ring->last_context) 366 if (!ring->last_context)
375 continue; 367 continue;
376 368
377 if (ring->last_context == dctx) 369 if (dctx->obj && i == RCS) {
378 continue;
379
380 if (i == RCS) {
381 WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj, 370 WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
382 get_context_alignment(dev), 0)); 371 get_context_alignment(dev), 0));
383 /* Fake a finish/inactive */ 372 /* Fake a finish/inactive */
@@ -394,44 +383,35 @@ void i915_gem_context_reset(struct drm_device *dev)
394int i915_gem_context_init(struct drm_device *dev) 383int i915_gem_context_init(struct drm_device *dev)
395{ 384{
396 struct drm_i915_private *dev_priv = dev->dev_private; 385 struct drm_i915_private *dev_priv = dev->dev_private;
397 struct intel_ring_buffer *ring; 386 struct i915_hw_context *ctx;
398 int i; 387 int i;
399 388
400 if (!HAS_HW_CONTEXTS(dev))
401 return 0;
402
403 /* Init should only be called once per module load. Eventually the 389 /* Init should only be called once per module load. Eventually the
404 * restriction on the context_disabled check can be loosened. */ 390 * restriction on the context_disabled check can be loosened. */
405 if (WARN_ON(dev_priv->ring[RCS].default_context)) 391 if (WARN_ON(dev_priv->ring[RCS].default_context))
406 return 0; 392 return 0;
407 393
408 dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); 394 if (HAS_HW_CONTEXTS(dev)) {
409 395 dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
410 if (dev_priv->hw_context_size > (1<<20)) { 396 if (dev_priv->hw_context_size > (1<<20)) {
411 DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n"); 397 DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
412 return -E2BIG; 398 dev_priv->hw_context_size);
399 dev_priv->hw_context_size = 0;
400 }
413 } 401 }
414 402
415 dev_priv->ring[RCS].default_context = 403 ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
416 i915_gem_create_context(dev, NULL, USES_PPGTT(dev)); 404 if (IS_ERR(ctx)) {
417 405 DRM_ERROR("Failed to create default global context (error %ld)\n",
418 if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) { 406 PTR_ERR(ctx));
419 DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n", 407 return PTR_ERR(ctx);
420 PTR_ERR(dev_priv->ring[RCS].default_context));
421 return PTR_ERR(dev_priv->ring[RCS].default_context);
422 } 408 }
423 409
424 for (i = RCS + 1; i < I915_NUM_RINGS; i++) { 410 /* NB: RCS will hold a ref for all rings */
425 if (!(INTEL_INFO(dev)->ring_mask & (1<<i))) 411 for (i = 0; i < I915_NUM_RINGS; i++)
426 continue; 412 dev_priv->ring[i].default_context = ctx;
427
428 ring = &dev_priv->ring[i];
429 413
430 /* NB: RCS will hold a ref for all rings */ 414 DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake");
431 ring->default_context = dev_priv->ring[RCS].default_context;
432 }
433
434 DRM_DEBUG_DRIVER("HW context support initialized\n");
435 return 0; 415 return 0;
436} 416}
437 417
@@ -441,33 +421,30 @@ void i915_gem_context_fini(struct drm_device *dev)
441 struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context; 421 struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
442 int i; 422 int i;
443 423
444 if (!HAS_HW_CONTEXTS(dev)) 424 if (dctx->obj) {
445 return; 425 /* The only known way to stop the gpu from accessing the hw context is
446 426 * to reset it. Do this as the very last operation to avoid confusing
447 /* The only known way to stop the gpu from accessing the hw context is 427 * other code, leading to spurious errors. */
448 * to reset it. Do this as the very last operation to avoid confusing 428 intel_gpu_reset(dev);
449 * other code, leading to spurious errors. */ 429
450 intel_gpu_reset(dev); 430 /* When default context is created and switched to, base object refcount
451 431 * will be 2 (+1 from object creation and +1 from do_switch()).
452 /* When default context is created and switched to, base object refcount 432 * i915_gem_context_fini() will be called after gpu_idle() has switched
453 * will be 2 (+1 from object creation and +1 from do_switch()). 433 * to default context. So we need to unreference the base object once
454 * i915_gem_context_fini() will be called after gpu_idle() has switched 434 * to offset the do_switch part, so that i915_gem_context_unreference()
455 * to default context. So we need to unreference the base object once 435 * can then free the base object correctly. */
456 * to offset the do_switch part, so that i915_gem_context_unreference() 436 WARN_ON(!dev_priv->ring[RCS].last_context);
457 * can then free the base object correctly. */ 437 if (dev_priv->ring[RCS].last_context == dctx) {
458 WARN_ON(!dev_priv->ring[RCS].last_context); 438 /* Fake switch to NULL context */
459 if (dev_priv->ring[RCS].last_context == dctx) { 439 WARN_ON(dctx->obj->active);
460 /* Fake switch to NULL context */ 440 i915_gem_object_ggtt_unpin(dctx->obj);
461 WARN_ON(dctx->obj->active); 441 i915_gem_context_unreference(dctx);
462 i915_gem_object_ggtt_unpin(dctx->obj); 442 dev_priv->ring[RCS].last_context = NULL;
463 i915_gem_context_unreference(dctx); 443 }
464 dev_priv->ring[RCS].last_context = NULL;
465 } 444 }
466 445
467 for (i = 0; i < I915_NUM_RINGS; i++) { 446 for (i = 0; i < I915_NUM_RINGS; i++) {
468 struct intel_ring_buffer *ring = &dev_priv->ring[i]; 447 struct intel_ring_buffer *ring = &dev_priv->ring[i];
469 if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
470 continue;
471 448
472 if (ring->last_context) 449 if (ring->last_context)
473 i915_gem_context_unreference(ring->last_context); 450 i915_gem_context_unreference(ring->last_context);
@@ -478,7 +455,6 @@ void i915_gem_context_fini(struct drm_device *dev)
478 455
479 i915_gem_object_ggtt_unpin(dctx->obj); 456 i915_gem_object_ggtt_unpin(dctx->obj);
480 i915_gem_context_unreference(dctx); 457 i915_gem_context_unreference(dctx);
481 dev_priv->mm.aliasing_ppgtt = NULL;
482} 458}
483 459
484int i915_gem_context_enable(struct drm_i915_private *dev_priv) 460int i915_gem_context_enable(struct drm_i915_private *dev_priv)
@@ -486,9 +462,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
486 struct intel_ring_buffer *ring; 462 struct intel_ring_buffer *ring;
487 int ret, i; 463 int ret, i;
488 464
489 if (!HAS_HW_CONTEXTS(dev_priv->dev))
490 return 0;
491
492 /* This is the only place the aliasing PPGTT gets enabled, which means 465 /* This is the only place the aliasing PPGTT gets enabled, which means
493 * it has to happen before we bail on reset */ 466 * it has to happen before we bail on reset */
494 if (dev_priv->mm.aliasing_ppgtt) { 467 if (dev_priv->mm.aliasing_ppgtt) {
@@ -503,7 +476,7 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
503 BUG_ON(!dev_priv->ring[RCS].default_context); 476 BUG_ON(!dev_priv->ring[RCS].default_context);
504 477
505 for_each_ring(ring, dev_priv, i) { 478 for_each_ring(ring, dev_priv, i) {
506 ret = do_switch(ring, ring->default_context); 479 ret = i915_switch_context(ring, ring->default_context);
507 if (ret) 480 if (ret)
508 return ret; 481 return ret;
509 } 482 }
@@ -526,19 +499,6 @@ static int context_idr_cleanup(int id, void *p, void *data)
526int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) 499int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
527{ 500{
528 struct drm_i915_file_private *file_priv = file->driver_priv; 501 struct drm_i915_file_private *file_priv = file->driver_priv;
529 struct drm_i915_private *dev_priv = dev->dev_private;
530
531 if (!HAS_HW_CONTEXTS(dev)) {
532 /* Cheat for hang stats */
533 file_priv->private_default_ctx =
534 kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL);
535
536 if (file_priv->private_default_ctx == NULL)
537 return -ENOMEM;
538
539 file_priv->private_default_ctx->vm = &dev_priv->gtt.base;
540 return 0;
541 }
542 502
543 idr_init(&file_priv->context_idr); 503 idr_init(&file_priv->context_idr);
544 504
@@ -559,14 +519,10 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
559{ 519{
560 struct drm_i915_file_private *file_priv = file->driver_priv; 520 struct drm_i915_file_private *file_priv = file->driver_priv;
561 521
562 if (!HAS_HW_CONTEXTS(dev)) {
563 kfree(file_priv->private_default_ctx);
564 return;
565 }
566
567 idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); 522 idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
568 i915_gem_context_unreference(file_priv->private_default_ctx);
569 idr_destroy(&file_priv->context_idr); 523 idr_destroy(&file_priv->context_idr);
524
525 i915_gem_context_unreference(file_priv->private_default_ctx);
570} 526}
571 527
572struct i915_hw_context * 528struct i915_hw_context *
@@ -574,9 +530,6 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id)
574{ 530{
575 struct i915_hw_context *ctx; 531 struct i915_hw_context *ctx;
576 532
577 if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev))
578 return file_priv->private_default_ctx;
579
580 ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id); 533 ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
581 if (!ctx) 534 if (!ctx)
582 return ERR_PTR(-ENOENT); 535 return ERR_PTR(-ENOENT);
@@ -758,7 +711,6 @@ unpin_out:
758/** 711/**
759 * i915_switch_context() - perform a GPU context switch. 712 * i915_switch_context() - perform a GPU context switch.
760 * @ring: ring for which we'll execute the context switch 713 * @ring: ring for which we'll execute the context switch
761 * @file_priv: file_priv associated with the context, may be NULL
762 * @to: the context to switch to 714 * @to: the context to switch to
763 * 715 *
764 * The context life cycle is simple. The context refcount is incremented and 716 * The context life cycle is simple. The context refcount is incremented and
@@ -767,24 +719,30 @@ unpin_out:
767 * object while letting the normal object tracking destroy the backing BO. 719 * object while letting the normal object tracking destroy the backing BO.
768 */ 720 */
769int i915_switch_context(struct intel_ring_buffer *ring, 721int i915_switch_context(struct intel_ring_buffer *ring,
770 struct drm_file *file,
771 struct i915_hw_context *to) 722 struct i915_hw_context *to)
772{ 723{
773 struct drm_i915_private *dev_priv = ring->dev->dev_private; 724 struct drm_i915_private *dev_priv = ring->dev->dev_private;
774 725
775 WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); 726 WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
776 727
777 BUG_ON(file && to == NULL); 728 if (to->obj == NULL) { /* We have the fake context */
778 729 if (to != ring->last_context) {
779 /* We have the fake context */ 730 i915_gem_context_reference(to);
780 if (!HAS_HW_CONTEXTS(ring->dev)) { 731 if (ring->last_context)
781 ring->last_context = to; 732 i915_gem_context_unreference(ring->last_context);
733 ring->last_context = to;
734 }
782 return 0; 735 return 0;
783 } 736 }
784 737
785 return do_switch(ring, to); 738 return do_switch(ring, to);
786} 739}
787 740
741static bool hw_context_enabled(struct drm_device *dev)
742{
743 return to_i915(dev)->hw_context_size;
744}
745
788int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, 746int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
789 struct drm_file *file) 747 struct drm_file *file)
790{ 748{
@@ -793,7 +751,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
793 struct i915_hw_context *ctx; 751 struct i915_hw_context *ctx;
794 int ret; 752 int ret;
795 753
796 if (!HAS_HW_CONTEXTS(dev)) 754 if (!hw_context_enabled(dev))
797 return -ENODEV; 755 return -ENODEV;
798 756
799 ret = i915_mutex_lock_interruptible(dev); 757 ret = i915_mutex_lock_interruptible(dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7447160155a3..2c9d9cbaf653 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1221,7 +1221,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1221 if (ret) 1221 if (ret)
1222 goto err; 1222 goto err;
1223 1223
1224 ret = i915_switch_context(ring, file, ctx); 1224 ret = i915_switch_context(ring, ctx);
1225 if (ret) 1225 if (ret)
1226 goto err; 1226 goto err;
1227 1227
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ab5e93c30aa2..62a5c3627b90 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -50,7 +50,7 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full)
50 50
51 /* Full ppgtt disabled by default for now due to issues. */ 51 /* Full ppgtt disabled by default for now due to issues. */
52 if (full) 52 if (full)
53 return false; /* HAS_PPGTT(dev) */ 53 return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2);
54 else 54 else
55 return HAS_ALIASING_PPGTT(dev); 55 return HAS_ALIASING_PPGTT(dev);
56} 56}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7753249b3a95..f98ba4e6e70b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1362,10 +1362,20 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
1362 spin_lock(&dev_priv->irq_lock); 1362 spin_lock(&dev_priv->irq_lock);
1363 for (i = 1; i < HPD_NUM_PINS; i++) { 1363 for (i = 1; i < HPD_NUM_PINS; i++) {
1364 1364
1365 WARN_ONCE(hpd[i] & hotplug_trigger && 1365 if (hpd[i] & hotplug_trigger &&
1366 dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, 1366 dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) {
1367 "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", 1367 /*
1368 hotplug_trigger, i, hpd[i]); 1368 * On GMCH platforms the interrupt mask bits only
1369 * prevent irq generation, not the setting of the
1370 * hotplug bits itself. So only WARN about unexpected
1371 * interrupts on saner platforms.
1372 */
1373 WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev),
1374 "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n",
1375 hotplug_trigger, i, hpd[i]);
1376
1377 continue;
1378 }
1369 1379
1370 if (!(hpd[i] & hotplug_trigger) || 1380 if (!(hpd[i] & hotplug_trigger) ||
1371 dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) 1381 dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9f5b18d9d885..c77af69c2d8f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -827,6 +827,7 @@ enum punit_power_well {
827# define MI_FLUSH_ENABLE (1 << 12) 827# define MI_FLUSH_ENABLE (1 << 12)
828# define ASYNC_FLIP_PERF_DISABLE (1 << 14) 828# define ASYNC_FLIP_PERF_DISABLE (1 << 14)
829# define MODE_IDLE (1 << 9) 829# define MODE_IDLE (1 << 9)
830# define STOP_RING (1 << 8)
830 831
831#define GEN6_GT_MODE 0x20d0 832#define GEN6_GT_MODE 0x20d0
832#define GEN7_GT_MODE 0x7008 833#define GEN7_GT_MODE 0x7008
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4867f4cc0938..fa486c5fbb02 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -287,6 +287,9 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
287 const struct bdb_lfp_backlight_data *backlight_data; 287 const struct bdb_lfp_backlight_data *backlight_data;
288 const struct bdb_lfp_backlight_data_entry *entry; 288 const struct bdb_lfp_backlight_data_entry *entry;
289 289
290 /* Err to enabling backlight if no backlight block. */
291 dev_priv->vbt.backlight.present = true;
292
290 backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); 293 backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
291 if (!backlight_data) 294 if (!backlight_data)
292 return; 295 return;
@@ -299,6 +302,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
299 302
300 entry = &backlight_data->data[panel_type]; 303 entry = &backlight_data->data[panel_type];
301 304
305 dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
306 if (!dev_priv->vbt.backlight.present) {
307 DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
308 entry->type);
309 return;
310 }
311
302 dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; 312 dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
303 dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm; 313 dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
304 DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, " 314 DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 83b7629e4367..f27f7b282465 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -374,6 +374,9 @@ struct bdb_lvds_lfp_data {
374 struct bdb_lvds_lfp_data_entry data[16]; 374 struct bdb_lvds_lfp_data_entry data[16];
375} __packed; 375} __packed;
376 376
377#define BDB_BACKLIGHT_TYPE_NONE 0
378#define BDB_BACKLIGHT_TYPE_PWM 2
379
377struct bdb_lfp_backlight_data_entry { 380struct bdb_lfp_backlight_data_entry {
378 u8 type:2; 381 u8 type:2;
379 u8 active_low_pwm:1; 382 u8 active_low_pwm:1;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dae976f51d83..69bcc42a0e44 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9654,11 +9654,22 @@ intel_pipe_config_compare(struct drm_device *dev,
9654 PIPE_CONF_CHECK_I(pipe_src_w); 9654 PIPE_CONF_CHECK_I(pipe_src_w);
9655 PIPE_CONF_CHECK_I(pipe_src_h); 9655 PIPE_CONF_CHECK_I(pipe_src_h);
9656 9656
9657 PIPE_CONF_CHECK_I(gmch_pfit.control); 9657 /*
9658 /* pfit ratios are autocomputed by the hw on gen4+ */ 9658 * FIXME: BIOS likes to set up a cloned config with lvds+external
9659 if (INTEL_INFO(dev)->gen < 4) 9659 * screen. Since we don't yet re-compute the pipe config when moving
9660 PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); 9660 * just the lvds port away to another pipe the sw tracking won't match.
9661 PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); 9661 *
9662 * Proper atomic modesets with recomputed global state will fix this.
9663 * Until then just don't check gmch state for inherited modes.
9664 */
9665 if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
9666 PIPE_CONF_CHECK_I(gmch_pfit.control);
9667 /* pfit ratios are autocomputed by the hw on gen4+ */
9668 if (INTEL_INFO(dev)->gen < 4)
9669 PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
9670 PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
9671 }
9672
9662 PIPE_CONF_CHECK_I(pch_pfit.enabled); 9673 PIPE_CONF_CHECK_I(pch_pfit.enabled);
9663 if (current_config->pch_pfit.enabled) { 9674 if (current_config->pch_pfit.enabled) {
9664 PIPE_CONF_CHECK_I(pch_pfit.pos); 9675 PIPE_CONF_CHECK_I(pch_pfit.pos);
@@ -11616,6 +11627,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
11616 base.head) { 11627 base.head) {
11617 memset(&crtc->config, 0, sizeof(crtc->config)); 11628 memset(&crtc->config, 0, sizeof(crtc->config));
11618 11629
11630 crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
11631
11619 crtc->active = dev_priv->display.get_pipe_config(crtc, 11632 crtc->active = dev_priv->display.get_pipe_config(crtc,
11620 &crtc->config); 11633 &crtc->config);
11621 11634
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a0dad1a2f819..dfa85289f28f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -575,7 +575,8 @@ out:
575 return ret; 575 return ret;
576} 576}
577 577
578#define HEADER_SIZE 4 578#define BARE_ADDRESS_SIZE 3
579#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
579static ssize_t 580static ssize_t
580intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) 581intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
581{ 582{
@@ -592,7 +593,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
592 switch (msg->request & ~DP_AUX_I2C_MOT) { 593 switch (msg->request & ~DP_AUX_I2C_MOT) {
593 case DP_AUX_NATIVE_WRITE: 594 case DP_AUX_NATIVE_WRITE:
594 case DP_AUX_I2C_WRITE: 595 case DP_AUX_I2C_WRITE:
595 txsize = HEADER_SIZE + msg->size; 596 txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
596 rxsize = 1; 597 rxsize = 1;
597 598
598 if (WARN_ON(txsize > 20)) 599 if (WARN_ON(txsize > 20))
@@ -611,7 +612,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
611 612
612 case DP_AUX_NATIVE_READ: 613 case DP_AUX_NATIVE_READ:
613 case DP_AUX_I2C_READ: 614 case DP_AUX_I2C_READ:
614 txsize = HEADER_SIZE; 615 txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE;
615 rxsize = msg->size + 1; 616 rxsize = msg->size + 1;
616 617
617 if (WARN_ON(rxsize > 20)) 618 if (WARN_ON(rxsize > 20))
@@ -3618,7 +3619,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3618{ 3619{
3619 struct drm_connector *connector = &intel_connector->base; 3620 struct drm_connector *connector = &intel_connector->base;
3620 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 3621 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3621 struct drm_device *dev = intel_dig_port->base.base.dev; 3622 struct intel_encoder *intel_encoder = &intel_dig_port->base;
3623 struct drm_device *dev = intel_encoder->base.dev;
3622 struct drm_i915_private *dev_priv = dev->dev_private; 3624 struct drm_i915_private *dev_priv = dev->dev_private;
3623 struct drm_display_mode *fixed_mode = NULL; 3625 struct drm_display_mode *fixed_mode = NULL;
3624 bool has_dpcd; 3626 bool has_dpcd;
@@ -3628,6 +3630,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3628 if (!is_edp(intel_dp)) 3630 if (!is_edp(intel_dp))
3629 return true; 3631 return true;
3630 3632
3633 /* The VDD bit needs a power domain reference, so if the bit is already
3634 * enabled when we boot, grab this reference. */
3635 if (edp_have_panel_vdd(intel_dp)) {
3636 enum intel_display_power_domain power_domain;
3637 power_domain = intel_display_port_power_domain(intel_encoder);
3638 intel_display_power_get(dev_priv, power_domain);
3639 }
3640
3631 /* Cache DPCD and EDID for edp. */ 3641 /* Cache DPCD and EDID for edp. */
3632 intel_edp_panel_vdd_on(intel_dp); 3642 intel_edp_panel_vdd_on(intel_dp);
3633 has_dpcd = intel_dp_get_dpcd(intel_dp); 3643 has_dpcd = intel_dp_get_dpcd(intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0542de982260..328b1a70264b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -236,7 +236,8 @@ struct intel_crtc_config {
236 * tracked with quirk flags so that fastboot and state checker can act 236 * tracked with quirk flags so that fastboot and state checker can act
237 * accordingly. 237 * accordingly.
238 */ 238 */
239#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ 239#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
240#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
240 unsigned long quirks; 241 unsigned long quirks;
241 242
242 /* User requested mode, only valid as a starting point to 243 /* User requested mode, only valid as a starting point to
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index b4d44e62f0c7..fce4a0d93c0b 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -132,6 +132,16 @@ static int intelfb_create(struct drm_fb_helper *helper,
132 132
133 mutex_lock(&dev->struct_mutex); 133 mutex_lock(&dev->struct_mutex);
134 134
135 if (intel_fb &&
136 (sizes->fb_width > intel_fb->base.width ||
137 sizes->fb_height > intel_fb->base.height)) {
138 DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
139 " releasing it\n",
140 intel_fb->base.width, intel_fb->base.height,
141 sizes->fb_width, sizes->fb_height);
142 drm_framebuffer_unreference(&intel_fb->base);
143 intel_fb = ifbdev->fb = NULL;
144 }
135 if (!intel_fb || WARN_ON(!intel_fb->obj)) { 145 if (!intel_fb || WARN_ON(!intel_fb->obj)) {
136 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); 146 DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
137 ret = intelfb_alloc(helper, sizes); 147 ret = intelfb_alloc(helper, sizes);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index b0413e190625..157267aa3561 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -821,11 +821,11 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
821 } 821 }
822} 822}
823 823
824static int hdmi_portclock_limit(struct intel_hdmi *hdmi) 824static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
825{ 825{
826 struct drm_device *dev = intel_hdmi_to_dev(hdmi); 826 struct drm_device *dev = intel_hdmi_to_dev(hdmi);
827 827
828 if (!hdmi->has_hdmi_sink || IS_G4X(dev)) 828 if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
829 return 165000; 829 return 165000;
830 else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) 830 else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
831 return 300000; 831 return 300000;
@@ -837,7 +837,8 @@ static enum drm_mode_status
837intel_hdmi_mode_valid(struct drm_connector *connector, 837intel_hdmi_mode_valid(struct drm_connector *connector,
838 struct drm_display_mode *mode) 838 struct drm_display_mode *mode)
839{ 839{
840 if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) 840 if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector),
841 true))
841 return MODE_CLOCK_HIGH; 842 return MODE_CLOCK_HIGH;
842 if (mode->clock < 20000) 843 if (mode->clock < 20000)
843 return MODE_CLOCK_LOW; 844 return MODE_CLOCK_LOW;
@@ -879,7 +880,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
879 struct drm_device *dev = encoder->base.dev; 880 struct drm_device *dev = encoder->base.dev;
880 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; 881 struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
881 int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; 882 int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
882 int portclock_limit = hdmi_portclock_limit(intel_hdmi); 883 int portclock_limit = hdmi_portclock_limit(intel_hdmi, false);
883 int desired_bpp; 884 int desired_bpp;
884 885
885 if (intel_hdmi->color_range_auto) { 886 if (intel_hdmi->color_range_auto) {
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index cb058408c70e..0eead16aeda7 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1065,6 +1065,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
1065 unsigned long flags; 1065 unsigned long flags;
1066 int ret; 1066 int ret;
1067 1067
1068 if (!dev_priv->vbt.backlight.present) {
1069 DRM_DEBUG_KMS("native backlight control not available per VBT\n");
1070 return 0;
1071 }
1072
1068 /* set level and max in panel struct */ 1073 /* set level and max in panel struct */
1069 spin_lock_irqsave(&dev_priv->backlight_lock, flags); 1074 spin_lock_irqsave(&dev_priv->backlight_lock, flags);
1070 ret = dev_priv->display.setup_backlight(intel_connector); 1075 ret = dev_priv->display.setup_backlight(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5874716774a7..19e94c3edc19 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1545,6 +1545,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
1545 1545
1546 DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); 1546 DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
1547 1547
1548 if (IS_I915GM(dev) && enabled) {
1549 struct intel_framebuffer *fb;
1550
1551 fb = to_intel_framebuffer(enabled->primary->fb);
1552
1553 /* self-refresh seems busted with untiled */
1554 if (fb->obj->tiling_mode == I915_TILING_NONE)
1555 enabled = NULL;
1556 }
1557
1548 /* 1558 /*
1549 * Overlay gets an aggressive default since video jitter is bad. 1559 * Overlay gets an aggressive default since video jitter is bad.
1550 */ 1560 */
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 6bc68bdcf433..79fb4cc2137c 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -437,32 +437,41 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring)
437 I915_WRITE(HWS_PGA, addr); 437 I915_WRITE(HWS_PGA, addr);
438} 438}
439 439
440static int init_ring_common(struct intel_ring_buffer *ring) 440static bool stop_ring(struct intel_ring_buffer *ring)
441{ 441{
442 struct drm_device *dev = ring->dev; 442 struct drm_i915_private *dev_priv = to_i915(ring->dev);
443 struct drm_i915_private *dev_priv = dev->dev_private;
444 struct drm_i915_gem_object *obj = ring->obj;
445 int ret = 0;
446 u32 head;
447 443
448 gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); 444 if (!IS_GEN2(ring->dev)) {
445 I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING));
446 if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) {
447 DRM_ERROR("%s :timed out trying to stop ring\n", ring->name);
448 return false;
449 }
450 }
449 451
450 /* Stop the ring if it's running. */
451 I915_WRITE_CTL(ring, 0); 452 I915_WRITE_CTL(ring, 0);
452 I915_WRITE_HEAD(ring, 0); 453 I915_WRITE_HEAD(ring, 0);
453 ring->write_tail(ring, 0); 454 ring->write_tail(ring, 0);
454 if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000))
455 DRM_ERROR("%s :timed out trying to stop ring\n", ring->name);
456 455
457 if (I915_NEED_GFX_HWS(dev)) 456 if (!IS_GEN2(ring->dev)) {
458 intel_ring_setup_status_page(ring); 457 (void)I915_READ_CTL(ring);
459 else 458 I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING));
460 ring_setup_phys_status_page(ring); 459 }
461 460
462 head = I915_READ_HEAD(ring) & HEAD_ADDR; 461 return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0;
462}
463 463
464 /* G45 ring initialization fails to reset head to zero */ 464static int init_ring_common(struct intel_ring_buffer *ring)
465 if (head != 0) { 465{
466 struct drm_device *dev = ring->dev;
467 struct drm_i915_private *dev_priv = dev->dev_private;
468 struct drm_i915_gem_object *obj = ring->obj;
469 int ret = 0;
470
471 gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
472
473 if (!stop_ring(ring)) {
474 /* G45 ring initialization often fails to reset head to zero */
466 DRM_DEBUG_KMS("%s head not reset to zero " 475 DRM_DEBUG_KMS("%s head not reset to zero "
467 "ctl %08x head %08x tail %08x start %08x\n", 476 "ctl %08x head %08x tail %08x start %08x\n",
468 ring->name, 477 ring->name,
@@ -471,9 +480,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
471 I915_READ_TAIL(ring), 480 I915_READ_TAIL(ring),
472 I915_READ_START(ring)); 481 I915_READ_START(ring));
473 482
474 I915_WRITE_HEAD(ring, 0); 483 if (!stop_ring(ring)) {
475
476 if (I915_READ_HEAD(ring) & HEAD_ADDR) {
477 DRM_ERROR("failed to set %s head to zero " 484 DRM_ERROR("failed to set %s head to zero "
478 "ctl %08x head %08x tail %08x start %08x\n", 485 "ctl %08x head %08x tail %08x start %08x\n",
479 ring->name, 486 ring->name,
@@ -481,9 +488,16 @@ static int init_ring_common(struct intel_ring_buffer *ring)
481 I915_READ_HEAD(ring), 488 I915_READ_HEAD(ring),
482 I915_READ_TAIL(ring), 489 I915_READ_TAIL(ring),
483 I915_READ_START(ring)); 490 I915_READ_START(ring));
491 ret = -EIO;
492 goto out;
484 } 493 }
485 } 494 }
486 495
496 if (I915_NEED_GFX_HWS(dev))
497 intel_ring_setup_status_page(ring);
498 else
499 ring_setup_phys_status_page(ring);
500
487 /* Initialize the ring. This must happen _after_ we've cleared the ring 501 /* Initialize the ring. This must happen _after_ we've cleared the ring
488 * registers with the above sequence (the readback of the HEAD registers 502 * registers with the above sequence (the readback of the HEAD registers
489 * also enforces ordering), otherwise the hw might lose the new ring 503 * also enforces ordering), otherwise the hw might lose the new ring
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 270a6a973438..2b91c4b4d34b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -34,6 +34,7 @@ struct intel_hw_status_page {
34#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) 34#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
35 35
36#define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) 36#define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
37#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
37 38
38enum intel_ring_hangcheck_action { 39enum intel_ring_hangcheck_action {
39 HANGCHECK_IDLE = 0, 40 HANGCHECK_IDLE = 0,