diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2014-05-30 13:36:49 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-05-30 13:36:49 -0400 |
commit | fced6dee29f6fb143fe16ea90331176ff77e6120 (patch) | |
tree | 5b6e57e7a757adc2a6518ce291a4d2914397b917 /drivers/gpu/drm/i915 | |
parent | bfed1074f213051e94648bfad0d0611a16d81366 (diff) | |
parent | be1f7c8d7e2bc8b8c76846aa6f276e8d2ef8975a (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.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 218 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fbdev.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 1 |
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); | |||
2431 | int i915_gem_context_enable(struct drm_i915_private *dev_priv); | 2432 | int i915_gem_context_enable(struct drm_i915_private *dev_priv); |
2432 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); | 2433 | void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); |
2433 | int i915_switch_context(struct intel_ring_buffer *ring, | 2434 | int i915_switch_context(struct intel_ring_buffer *ring, |
2434 | struct drm_file *file, struct i915_hw_context *to); | 2435 | struct i915_hw_context *to); |
2435 | struct i915_hw_context * | 2436 | struct i915_hw_context * |
2436 | i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); | 2437 | i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); |
2437 | void i915_gem_context_free(struct kref *ctx_ref); | 2438 | void i915_gem_context_free(struct kref *ctx_ref); |
2438 | static inline void i915_gem_context_reference(struct i915_hw_context *ctx) | 2439 | static 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 | ||
2444 | static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) | 2444 | static 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 | ||
2450 | static inline bool i915_gem_context_is_default(const struct i915_hw_context *c) | 2449 | static 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 | ||
99 | static int do_switch(struct intel_ring_buffer *ring, | ||
100 | struct i915_hw_context *to); | ||
101 | |||
102 | static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) | 99 | static 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 | ||
344 | err_unpin: | 343 | err_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); |
347 | err_destroy: | 346 | err_destroy: |
348 | i915_gem_context_unreference(ctx); | 347 | i915_gem_context_unreference(ctx); |
@@ -352,32 +351,22 @@ err_destroy: | |||
352 | void i915_gem_context_reset(struct drm_device *dev) | 351 | void 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) | |||
394 | int i915_gem_context_init(struct drm_device *dev) | 383 | int 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 | ||
484 | int i915_gem_context_enable(struct drm_i915_private *dev_priv) | 460 | int 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) | |||
526 | int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) | 499 | int 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 | ||
572 | struct i915_hw_context * | 528 | struct 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 | */ |
769 | int i915_switch_context(struct intel_ring_buffer *ring, | 721 | int 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 | ||
741 | static bool hw_context_enabled(struct drm_device *dev) | ||
742 | { | ||
743 | return to_i915(dev)->hw_context_size; | ||
744 | } | ||
745 | |||
788 | int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | 746 | int 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 | |||
377 | struct bdb_lfp_backlight_data_entry { | 380 | struct 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) | ||
579 | static ssize_t | 580 | static ssize_t |
580 | intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) | 581 | intel_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 | ||
824 | static int hdmi_portclock_limit(struct intel_hdmi *hdmi) | 824 | static 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 | |||
837 | intel_hdmi_mode_valid(struct drm_connector *connector, | 837 | intel_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 | ||
440 | static int init_ring_common(struct intel_ring_buffer *ring) | 440 | static 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 */ | 464 | static 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 | ||
38 | enum intel_ring_hangcheck_action { | 39 | enum intel_ring_hangcheck_action { |
39 | HANGCHECK_IDLE = 0, | 40 | HANGCHECK_IDLE = 0, |