Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+28 -2
+4
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
··· 272 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 279 mutex_unlock(&rcrtc->group->lock); 276 280 277 281 rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR,
+2
drivers/gpu/drm/rcar-du/rcar_du_group.c
··· 162 162 163 163 void rcar_du_group_restart(struct rcar_du_group *rgrp) 164 164 { 165 + rgrp->need_restart = false; 166 + 165 167 __rcar_du_group_start_stop(rgrp, false); 166 168 __rcar_du_group_start_stop(rgrp, true); 167 169 }
+2
drivers/gpu/drm/rcar-du/rcar_du_group.h
··· 32 32 * @dptsr_planes: bitmask of planes driven by dot-clock and timing generator 1 33 33 * @num_planes: number of planes in the group 34 34 * @planes: planes handled by the group 35 + * @need_restart: the group needs to be restarted due to a configuration change 35 36 */ 36 37 struct rcar_du_group { 37 38 struct rcar_du_device *dev; ··· 48 47 49 48 unsigned int num_planes; 50 49 struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES]; 50 + bool need_restart; 51 51 }; 52 52 53 53 u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg);
+20 -2
drivers/gpu/drm/rcar-du/rcar_du_plane.c
··· 275 275 struct drm_plane_state *old_state) 276 276 { 277 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) 280 - rcar_du_plane_setup(rplane); 281 + if (!plane->state->crtc) 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 283 301 static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {