aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2017-06-14 19:18:31 -0400
committerThierry Reding <treding@nvidia.com>2017-06-15 08:20:30 -0400
commit80d3eef16e16912df967a083da237d56dc4493b8 (patch)
tree0e4c841d3ec37e2796bfcfa80b4aa232e77b5828
parent7d2058571aafad239e7f1a3c04a830c6ec6a426f (diff)
drm/tegra: dc: Disable plane if it is invisible
On Tegra20 if plane has width or height equal to 0, it will be infinitely wide or tall. Let's disable the plane if it is invisible on atomic state committing to fix the issue. The Rockchip DRM driver does the same. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Reviewed-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index a7a7cce1afd0..c875f11786b9 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -559,6 +559,23 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
559 return 0; 559 return 0;
560} 560}
561 561
562static void tegra_dc_disable_window(struct tegra_dc *dc, int index)
563{
564 unsigned long flags;
565 u32 value;
566
567 spin_lock_irqsave(&dc->lock, flags);
568
569 value = WINDOW_A_SELECT << index;
570 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
571
572 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
573 value &= ~WIN_ENABLE;
574 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
575
576 spin_unlock_irqrestore(&dc->lock, flags);
577}
578
562static void tegra_plane_atomic_update(struct drm_plane *plane, 579static void tegra_plane_atomic_update(struct drm_plane *plane,
563 struct drm_plane_state *old_state) 580 struct drm_plane_state *old_state)
564{ 581{
@@ -573,6 +590,9 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
573 if (!plane->state->crtc || !plane->state->fb) 590 if (!plane->state->crtc || !plane->state->fb)
574 return; 591 return;
575 592
593 if (!plane->state->visible)
594 return tegra_dc_disable_window(dc, p->index);
595
576 memset(&window, 0, sizeof(window)); 596 memset(&window, 0, sizeof(window));
577 window.src.x = plane->state->src.x1 >> 16; 597 window.src.x = plane->state->src.x1 >> 16;
578 window.src.y = plane->state->src.y1 >> 16; 598 window.src.y = plane->state->src.y1 >> 16;
@@ -612,8 +632,6 @@ static void tegra_plane_atomic_disable(struct drm_plane *plane,
612{ 632{
613 struct tegra_plane *p = to_tegra_plane(plane); 633 struct tegra_plane *p = to_tegra_plane(plane);
614 struct tegra_dc *dc; 634 struct tegra_dc *dc;
615 unsigned long flags;
616 u32 value;
617 635
618 /* rien ne va plus */ 636 /* rien ne va plus */
619 if (!old_state || !old_state->crtc) 637 if (!old_state || !old_state->crtc)
@@ -621,16 +639,7 @@ static void tegra_plane_atomic_disable(struct drm_plane *plane,
621 639
622 dc = to_tegra_dc(old_state->crtc); 640 dc = to_tegra_dc(old_state->crtc);
623 641
624 spin_lock_irqsave(&dc->lock, flags); 642 tegra_dc_disable_window(dc, p->index);
625
626 value = WINDOW_A_SELECT << p->index;
627 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
628
629 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
630 value &= ~WIN_ENABLE;
631 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
632
633 spin_unlock_irqrestore(&dc->lock, flags);
634} 643}
635 644
636static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = { 645static const struct drm_plane_helper_funcs tegra_primary_plane_helper_funcs = {