aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e730789b53b7..f75173c20f47 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -37,6 +37,7 @@
37#include <drm/i915_drm.h> 37#include <drm/i915_drm.h>
38#include "i915_drv.h" 38#include "i915_drv.h"
39#include "i915_trace.h" 39#include "i915_trace.h"
40#include <drm/drm_atomic.h>
40#include <drm/drm_atomic_helper.h> 41#include <drm/drm_atomic_helper.h>
41#include <drm/drm_dp_helper.h> 42#include <drm/drm_dp_helper.h>
42#include <drm/drm_crtc_helper.h> 43#include <drm/drm_crtc_helper.h>
@@ -2416,6 +2417,14 @@ out_unref_obj:
2416 return false; 2417 return false;
2417} 2418}
2418 2419
2420/* Update plane->state->fb to match plane->fb after driver-internal updates */
2421static void
2422update_state_fb(struct drm_plane *plane)
2423{
2424 if (plane->fb != plane->state->fb)
2425 drm_atomic_set_fb_for_plane(plane->state, plane->fb);
2426}
2427
2419static void 2428static void
2420intel_find_plane_obj(struct intel_crtc *intel_crtc, 2429intel_find_plane_obj(struct intel_crtc *intel_crtc,
2421 struct intel_initial_plane_config *plane_config) 2430 struct intel_initial_plane_config *plane_config)
@@ -2429,8 +2438,15 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
2429 if (!intel_crtc->base.primary->fb) 2438 if (!intel_crtc->base.primary->fb)
2430 return; 2439 return;
2431 2440
2432 if (intel_alloc_plane_obj(intel_crtc, plane_config)) 2441 if (intel_alloc_plane_obj(intel_crtc, plane_config)) {
2442 struct drm_plane *primary = intel_crtc->base.primary;
2443
2444 primary->state->crtc = &intel_crtc->base;
2445 primary->crtc = &intel_crtc->base;
2446 update_state_fb(primary);
2447
2433 return; 2448 return;
2449 }
2434 2450
2435 kfree(intel_crtc->base.primary->fb); 2451 kfree(intel_crtc->base.primary->fb);
2436 intel_crtc->base.primary->fb = NULL; 2452 intel_crtc->base.primary->fb = NULL;
@@ -2453,15 +2469,21 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
2453 continue; 2469 continue;
2454 2470
2455 if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) { 2471 if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
2472 struct drm_plane *primary = intel_crtc->base.primary;
2473
2456 if (obj->tiling_mode != I915_TILING_NONE) 2474 if (obj->tiling_mode != I915_TILING_NONE)
2457 dev_priv->preserve_bios_swizzle = true; 2475 dev_priv->preserve_bios_swizzle = true;
2458 2476
2459 drm_framebuffer_reference(c->primary->fb); 2477 drm_framebuffer_reference(c->primary->fb);
2460 intel_crtc->base.primary->fb = c->primary->fb; 2478 primary->fb = c->primary->fb;
2479 primary->state->crtc = &intel_crtc->base;
2480 primary->crtc = &intel_crtc->base;
2461 obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); 2481 obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
2462 break; 2482 break;
2463 } 2483 }
2464 } 2484 }
2485
2486 update_state_fb(intel_crtc->base.primary);
2465} 2487}
2466 2488
2467static void i9xx_update_primary_plane(struct drm_crtc *crtc, 2489static void i9xx_update_primary_plane(struct drm_crtc *crtc,
@@ -6602,6 +6624,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
6602 struct drm_framebuffer *fb; 6624 struct drm_framebuffer *fb;
6603 struct intel_framebuffer *intel_fb; 6625 struct intel_framebuffer *intel_fb;
6604 6626
6627 val = I915_READ(DSPCNTR(plane));
6628 if (!(val & DISPLAY_PLANE_ENABLE))
6629 return;
6630
6605 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 6631 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
6606 if (!intel_fb) { 6632 if (!intel_fb) {
6607 DRM_DEBUG_KMS("failed to alloc fb\n"); 6633 DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -6610,8 +6636,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
6610 6636
6611 fb = &intel_fb->base; 6637 fb = &intel_fb->base;
6612 6638
6613 val = I915_READ(DSPCNTR(plane));
6614
6615 if (INTEL_INFO(dev)->gen >= 4) 6639 if (INTEL_INFO(dev)->gen >= 4)
6616 if (val & DISPPLANE_TILED) 6640 if (val & DISPPLANE_TILED)
6617 plane_config->tiling = I915_TILING_X; 6641 plane_config->tiling = I915_TILING_X;
@@ -7643,6 +7667,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
7643 fb = &intel_fb->base; 7667 fb = &intel_fb->base;
7644 7668
7645 val = I915_READ(PLANE_CTL(pipe, 0)); 7669 val = I915_READ(PLANE_CTL(pipe, 0));
7670 if (!(val & PLANE_CTL_ENABLE))
7671 goto error;
7672
7646 if (val & PLANE_CTL_TILED_MASK) 7673 if (val & PLANE_CTL_TILED_MASK)
7647 plane_config->tiling = I915_TILING_X; 7674 plane_config->tiling = I915_TILING_X;
7648 7675
@@ -7730,6 +7757,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
7730 struct drm_framebuffer *fb; 7757 struct drm_framebuffer *fb;
7731 struct intel_framebuffer *intel_fb; 7758 struct intel_framebuffer *intel_fb;
7732 7759
7760 val = I915_READ(DSPCNTR(pipe));
7761 if (!(val & DISPLAY_PLANE_ENABLE))
7762 return;
7763
7733 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 7764 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
7734 if (!intel_fb) { 7765 if (!intel_fb) {
7735 DRM_DEBUG_KMS("failed to alloc fb\n"); 7766 DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -7738,8 +7769,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
7738 7769
7739 fb = &intel_fb->base; 7770 fb = &intel_fb->base;
7740 7771
7741 val = I915_READ(DSPCNTR(pipe));
7742
7743 if (INTEL_INFO(dev)->gen >= 4) 7772 if (INTEL_INFO(dev)->gen >= 4)
7744 if (val & DISPPLANE_TILED) 7773 if (val & DISPPLANE_TILED)
7745 plane_config->tiling = I915_TILING_X; 7774 plane_config->tiling = I915_TILING_X;
@@ -9716,7 +9745,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe)
9716 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; 9745 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
9717 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 9746 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
9718 9747
9719 WARN_ON(!in_irq()); 9748 WARN_ON(!in_interrupt());
9720 9749
9721 if (crtc == NULL) 9750 if (crtc == NULL)
9722 return; 9751 return;
@@ -9816,6 +9845,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
9816 drm_gem_object_reference(&obj->base); 9845 drm_gem_object_reference(&obj->base);
9817 9846
9818 crtc->primary->fb = fb; 9847 crtc->primary->fb = fb;
9848 update_state_fb(crtc->primary);
9819 9849
9820 work->pending_flip_obj = obj; 9850 work->pending_flip_obj = obj;
9821 9851
@@ -9884,6 +9914,7 @@ cleanup_unpin:
9884cleanup_pending: 9914cleanup_pending:
9885 atomic_dec(&intel_crtc->unpin_work_count); 9915 atomic_dec(&intel_crtc->unpin_work_count);
9886 crtc->primary->fb = old_fb; 9916 crtc->primary->fb = old_fb;
9917 update_state_fb(crtc->primary);
9887 drm_gem_object_unreference(&work->old_fb_obj->base); 9918 drm_gem_object_unreference(&work->old_fb_obj->base);
9888 drm_gem_object_unreference(&obj->base); 9919 drm_gem_object_unreference(&obj->base);
9889 mutex_unlock(&dev->struct_mutex); 9920 mutex_unlock(&dev->struct_mutex);
@@ -13718,6 +13749,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
13718 to_intel_crtc(c)->pipe); 13749 to_intel_crtc(c)->pipe);
13719 drm_framebuffer_unreference(c->primary->fb); 13750 drm_framebuffer_unreference(c->primary->fb);
13720 c->primary->fb = NULL; 13751 c->primary->fb = NULL;
13752 update_state_fb(c->primary);
13721 } 13753 }
13722 } 13754 }
13723 mutex_unlock(&dev->struct_mutex); 13755 mutex_unlock(&dev->struct_mutex);