diff options
author | Dave Airlie <airlied@redhat.com> | 2020-03-12 05:42:41 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-03-12 05:42:56 +0300 |
commit | 9e12da086e5e38f7b4f8d6e02a82447f4165fbee (patch) | |
tree | 96e6029378ccb9ae3f9530d019c8216a3ca4a556 /drivers/gpu/drm/tidss/tidss_crtc.c | |
parent | d3bd37f587b4438d47751d0f1d5aaae3d39bd416 (diff) | |
parent | bc1a4130fc0309cc2f43b9cc616ebbc295e886ff (diff) | |
download | linux-9e12da086e5e38f7b4f8d6e02a82447f4165fbee.tar.xz |
Merge tag 'drm-misc-next-2020-03-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.7:
UAPI Changes:
Cross-subsystem Changes:
Core Changes:
Driver Changes:
- fb-helper: Remove drm_fb_helper_{add,add_all,remove}_one_connector
- fbdev: some cleanups and dead-code removal
- Conversions to simple-encoder
- zero-length array removal
- Panel: panel-dpi support in panel-simple, Novatek NT35510, Elida
KD35T133,
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200309135439.dicfnbo4ikj4tkz7@gilmour
Diffstat (limited to 'drivers/gpu/drm/tidss/tidss_crtc.c')
-rw-r--r-- | drivers/gpu/drm/tidss/tidss_crtc.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index 032c31ee2820..d4ce9bab8c7e 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -17,6 +17,7 @@ #include "tidss_dispc.h" #include "tidss_drv.h" #include "tidss_irq.h" +#include "tidss_plane.h" /* Page flip and frame done IRQs */ @@ -111,6 +112,54 @@ static int tidss_crtc_atomic_check(struct drm_crtc *crtc, return dispc_vp_bus_check(dispc, hw_videoport, state); } +/* + * This needs all affected planes to be present in the atomic + * state. The untouched planes are added to the state in + * tidss_atomic_check(). + */ +static void tidss_crtc_position_planes(struct tidss_device *tidss, + struct drm_crtc *crtc, + struct drm_crtc_state *old_state, + bool newmodeset) +{ + struct drm_atomic_state *ostate = old_state->state; + struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); + struct drm_crtc_state *cstate = crtc->state; + int layer; + + if (!newmodeset && !cstate->zpos_changed && + !to_tidss_crtc_state(cstate)->plane_pos_changed) + return; + + for (layer = 0; layer < tidss->feat->num_planes; layer++) { + struct drm_plane_state *pstate; + struct drm_plane *plane; + bool layer_active = false; + int i; + + for_each_new_plane_in_state(ostate, plane, pstate, i) { + if (pstate->crtc != crtc || !pstate->visible) + continue; + + if (pstate->normalized_zpos == layer) { + layer_active = true; + break; + } + } + + if (layer_active) { + struct tidss_plane *tplane = to_tidss_plane(plane); + + dispc_ovr_set_plane(tidss->dispc, tplane->hw_plane_id, + tcrtc->hw_videoport, + pstate->crtc_x, pstate->crtc_y, + layer); + } + dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer, + layer_active); + } +} + static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { @@ -146,6 +195,9 @@ static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, /* Write vp properties to HW if needed. */ dispc_vp_setup(tidss->dispc, tcrtc->hw_videoport, crtc->state, false); + /* Update plane positions if needed. */ + tidss_crtc_position_planes(tidss, crtc, old_crtc_state, false); + WARN_ON(drm_crtc_vblank_get(crtc) != 0); spin_lock_irqsave(&ddev->event_lock, flags); @@ -183,6 +235,7 @@ static void tidss_crtc_atomic_enable(struct drm_crtc *crtc, return; dispc_vp_setup(tidss->dispc, tcrtc->hw_videoport, crtc->state, true); + tidss_crtc_position_planes(tidss, crtc, old_state, true); /* Turn vertical blanking interrupt reporting on. */ drm_crtc_vblank_on(crtc); @@ -318,6 +371,8 @@ static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc) __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); + state->plane_pos_changed = false; + state->bus_format = current_state->bus_format; state->bus_flags = current_state->bus_flags; |