aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-08-23 20:17:03 -0400
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2016-02-19 19:58:55 -0500
commit2af0394409faec95e80d6061a8a9fe95565be358 (patch)
treed2eae3c1bbacd0244e7f35012156f0080525f28f
parent34a04f2b7baaa980fcb9eff9cbfb28a947c67f74 (diff)
drm: rcar-du: Restart the DU group when a plane source changes
Plane sources are configured by the VSPS bit in the PnDDCR4 register. Although the datasheet states that the bit is updated during vertical blanking, it seems that updates only occur when the DU group is held in reset through the DSYSR.DRES bit. Restart the group if the source changes. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.h2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c22
4 files changed, 28 insertions, 2 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index b87b8ffb898b..e2560aa26ef4 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -272,6 +272,10 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
272 rcar_du_group_restart(rcrtc->group); 272 rcar_du_group_restart(rcrtc->group);
273 } 273 }
274 274
275 /* Restart the group if plane sources have changed. */
276 if (rcrtc->group->need_restart)
277 rcar_du_group_restart(rcrtc->group);
278
275 mutex_unlock(&rcrtc->group->lock); 279 mutex_unlock(&rcrtc->group->lock);
276 280
277 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 281 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 4a44ddd51766..0e2b46dce563 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -162,6 +162,8 @@ void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
162 162
163void rcar_du_group_restart(struct rcar_du_group *rgrp) 163void rcar_du_group_restart(struct rcar_du_group *rgrp)
164{ 164{
165 rgrp->need_restart = false;
166
165 __rcar_du_group_start_stop(rgrp, false); 167 __rcar_du_group_start_stop(rgrp, false);
166 __rcar_du_group_start_stop(rgrp, true); 168 __rcar_du_group_start_stop(rgrp, true);
167} 169}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h
index 4b1952fd4e7d..5e3adc6b31b5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h
@@ -32,6 +32,7 @@ struct rcar_du_device;
32 * @dptsr_planes: bitmask of planes driven by dot-clock and timing generator 1 32 * @dptsr_planes: bitmask of planes driven by dot-clock and timing generator 1
33 * @num_planes: number of planes in the group 33 * @num_planes: number of planes in the group
34 * @planes: planes handled by the group 34 * @planes: planes handled by the group
35 * @need_restart: the group needs to be restarted due to a configuration change
35 */ 36 */
36struct rcar_du_group { 37struct rcar_du_group {
37 struct rcar_du_device *dev; 38 struct rcar_du_device *dev;
@@ -47,6 +48,7 @@ struct rcar_du_group {
47 48
48 unsigned int num_planes; 49 unsigned int num_planes;
49 struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES]; 50 struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
51 bool need_restart;
50}; 52};
51 53
52u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg); 54u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index cc383954e29a..2fa5745fca37 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -275,9 +275,27 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
275 struct drm_plane_state *old_state) 275 struct drm_plane_state *old_state)
276{ 276{
277 struct rcar_du_plane *rplane = to_rcar_plane(plane); 277 struct rcar_du_plane *rplane = to_rcar_plane(plane);
278 struct rcar_du_plane_state *old_rstate;
279 struct rcar_du_plane_state *new_rstate;
278 280
279 if (plane->state->crtc) 281 if (!plane->state->crtc)
280 rcar_du_plane_setup(rplane); 282 return;
283
284 rcar_du_plane_setup(rplane);
285
286 /* Check whether the source has changed from memory to live source or
287 * from live source to memory. The source has been configured by the
288 * VSPS bit in the PnDDCR4 register. Although the datasheet states that
289 * the bit is updated during vertical blanking, it seems that updates
290 * only occur when the DU group is held in reset through the DSYSR.DRES
291 * bit. We thus need to restart the group if the source changes.
292 */
293 old_rstate = to_rcar_plane_state(old_state);
294 new_rstate = to_rcar_plane_state(plane->state);
295
296 if ((old_rstate->source == RCAR_DU_PLANE_MEMORY) !=
297 (new_rstate->source == RCAR_DU_PLANE_MEMORY))
298 rplane->group->need_restart = true;
281} 299}
282 300
283static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = { 301static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {