aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c50
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c42
3 files changed, 62 insertions, 33 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index b492063a6e1f..5685d5af6998 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -319,7 +319,8 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
319 struct rcar_du_plane *plane = &rcrtc->group->planes[i]; 319 struct rcar_du_plane *plane = &rcrtc->group->planes[i];
320 unsigned int j; 320 unsigned int j;
321 321
322 if (plane->plane.state->crtc != &rcrtc->crtc) 322 if (plane->plane.state->crtc != &rcrtc->crtc ||
323 !plane->plane.state->visible)
323 continue; 324 continue;
324 325
325 /* Insert the plane in the sorted planes array. */ 326 /* Insert the plane in the sorted planes array. */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 4f076c364f25..4a3d16cf3ed6 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -332,8 +332,8 @@ static void rcar_du_plane_write(struct rcar_du_group *rgrp,
332static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, 332static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
333 const struct rcar_du_plane_state *state) 333 const struct rcar_du_plane_state *state)
334{ 334{
335 unsigned int src_x = state->state.src_x >> 16; 335 unsigned int src_x = state->state.src.x1 >> 16;
336 unsigned int src_y = state->state.src_y >> 16; 336 unsigned int src_y = state->state.src.y1 >> 16;
337 unsigned int index = state->hwindex; 337 unsigned int index = state->hwindex;
338 unsigned int pitch; 338 unsigned int pitch;
339 bool interlaced; 339 bool interlaced;
@@ -357,7 +357,7 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
357 dma[i] = gem->paddr + fb->offsets[i]; 357 dma[i] = gem->paddr + fb->offsets[i];
358 } 358 }
359 } else { 359 } else {
360 pitch = state->state.src_w >> 16; 360 pitch = drm_rect_width(&state->state.src) >> 16;
361 dma[0] = 0; 361 dma[0] = 0;
362 dma[1] = 0; 362 dma[1] = 0;
363 } 363 }
@@ -521,6 +521,7 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp,
521 const struct rcar_du_plane_state *state) 521 const struct rcar_du_plane_state *state)
522{ 522{
523 struct rcar_du_device *rcdu = rgrp->dev; 523 struct rcar_du_device *rcdu = rgrp->dev;
524 const struct drm_rect *dst = &state->state.dst;
524 525
525 if (rcdu->info->gen < 3) 526 if (rcdu->info->gen < 3)
526 rcar_du_plane_setup_format_gen2(rgrp, index, state); 527 rcar_du_plane_setup_format_gen2(rgrp, index, state);
@@ -528,10 +529,10 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp,
528 rcar_du_plane_setup_format_gen3(rgrp, index, state); 529 rcar_du_plane_setup_format_gen3(rgrp, index, state);
529 530
530 /* Destination position and size */ 531 /* Destination position and size */
531 rcar_du_plane_write(rgrp, index, PnDSXR, state->state.crtc_w); 532 rcar_du_plane_write(rgrp, index, PnDSXR, drm_rect_width(dst));
532 rcar_du_plane_write(rgrp, index, PnDSYR, state->state.crtc_h); 533 rcar_du_plane_write(rgrp, index, PnDSYR, drm_rect_height(dst));
533 rcar_du_plane_write(rgrp, index, PnDPXR, state->state.crtc_x); 534 rcar_du_plane_write(rgrp, index, PnDPXR, dst->x1);
534 rcar_du_plane_write(rgrp, index, PnDPYR, state->state.crtc_y); 535 rcar_du_plane_write(rgrp, index, PnDPYR, dst->y1);
535 536
536 if (rcdu->info->gen < 3) { 537 if (rcdu->info->gen < 3) {
537 /* Wrap-around and blinking, disabled */ 538 /* Wrap-around and blinking, disabled */
@@ -570,16 +571,39 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane,
570 const struct rcar_du_format_info **format) 571 const struct rcar_du_format_info **format)
571{ 572{
572 struct drm_device *dev = plane->dev; 573 struct drm_device *dev = plane->dev;
574 struct drm_crtc_state *crtc_state;
575 struct drm_rect clip;
576 int ret;
573 577
574 if (!state->fb || !state->crtc) { 578 if (!state->crtc) {
579 /*
580 * The visible field is not reset by the DRM core but only
581 * updated by drm_plane_helper_check_state(), set it manually.
582 */
583 state->visible = false;
575 *format = NULL; 584 *format = NULL;
576 return 0; 585 return 0;
577 } 586 }
578 587
579 if (state->src_w >> 16 != state->crtc_w || 588 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
580 state->src_h >> 16 != state->crtc_h) { 589 if (IS_ERR(crtc_state))
581 dev_dbg(dev->dev, "%s: scaling not supported\n", __func__); 590 return PTR_ERR(crtc_state);
582 return -EINVAL; 591
592 clip.x1 = 0;
593 clip.y1 = 0;
594 clip.x2 = crtc_state->mode.hdisplay;
595 clip.y2 = crtc_state->mode.vdisplay;
596
597 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
598 DRM_PLANE_HELPER_NO_SCALING,
599 DRM_PLANE_HELPER_NO_SCALING,
600 true, true);
601 if (ret < 0)
602 return ret;
603
604 if (!state->visible) {
605 *format = NULL;
606 return 0;
583 } 607 }
584 608
585 *format = rcar_du_format_info(state->fb->format->format); 609 *format = rcar_du_format_info(state->fb->format->format);
@@ -607,7 +631,7 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
607 struct rcar_du_plane_state *old_rstate; 631 struct rcar_du_plane_state *old_rstate;
608 struct rcar_du_plane_state *new_rstate; 632 struct rcar_du_plane_state *new_rstate;
609 633
610 if (!plane->state->crtc) 634 if (!plane->state->visible)
611 return; 635 return;
612 636
613 rcar_du_plane_setup(rplane); 637 rcar_du_plane_setup(rplane);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index dd66dcb8da23..2c260c33840b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -55,14 +55,14 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
55 struct rcar_du_plane_state state = { 55 struct rcar_du_plane_state state = {
56 .state = { 56 .state = {
57 .crtc = &crtc->crtc, 57 .crtc = &crtc->crtc,
58 .crtc_x = 0, 58 .dst.x1 = 0,
59 .crtc_y = 0, 59 .dst.y1 = 0,
60 .crtc_w = mode->hdisplay, 60 .dst.x2 = mode->hdisplay,
61 .crtc_h = mode->vdisplay, 61 .dst.y2 = mode->vdisplay,
62 .src_x = 0, 62 .src.x1 = 0,
63 .src_y = 0, 63 .src.y1 = 0,
64 .src_w = mode->hdisplay << 16, 64 .src.x2 = mode->hdisplay << 16,
65 .src_h = mode->vdisplay << 16, 65 .src.y2 = mode->vdisplay << 16,
66 .zpos = 0, 66 .zpos = 0,
67 }, 67 },
68 .format = rcar_du_format_info(DRM_FORMAT_ARGB8888), 68 .format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
@@ -178,15 +178,15 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
178 }; 178 };
179 unsigned int i; 179 unsigned int i;
180 180
181 cfg.src.left = state->state.src_x >> 16; 181 cfg.src.left = state->state.src.x1 >> 16;
182 cfg.src.top = state->state.src_y >> 16; 182 cfg.src.top = state->state.src.y1 >> 16;
183 cfg.src.width = state->state.src_w >> 16; 183 cfg.src.width = drm_rect_width(&state->state.src) >> 16;
184 cfg.src.height = state->state.src_h >> 16; 184 cfg.src.height = drm_rect_height(&state->state.src) >> 16;
185 185
186 cfg.dst.left = state->state.crtc_x; 186 cfg.dst.left = state->state.dst.x1;
187 cfg.dst.top = state->state.crtc_y; 187 cfg.dst.top = state->state.dst.y1;
188 cfg.dst.width = state->state.crtc_w; 188 cfg.dst.width = drm_rect_width(&state->state.dst);
189 cfg.dst.height = state->state.crtc_h; 189 cfg.dst.height = drm_rect_height(&state->state.dst);
190 190
191 for (i = 0; i < state->format->planes; ++i) 191 for (i = 0; i < state->format->planes; ++i)
192 cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl) 192 cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
@@ -212,7 +212,11 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
212 unsigned int i; 212 unsigned int i;
213 int ret; 213 int ret;
214 214
215 if (!state->fb) 215 /*
216 * There's no need to prepare (and unprepare) the framebuffer when the
217 * plane is not visible, as it will not be displayed.
218 */
219 if (!state->visible)
216 return 0; 220 return 0;
217 221
218 for (i = 0; i < rstate->format->planes; ++i) { 222 for (i = 0; i < rstate->format->planes; ++i) {
@@ -253,7 +257,7 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
253 struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; 257 struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
254 unsigned int i; 258 unsigned int i;
255 259
256 if (!state->fb) 260 if (!state->visible)
257 return; 261 return;
258 262
259 for (i = 0; i < rstate->format->planes; ++i) { 263 for (i = 0; i < rstate->format->planes; ++i) {
@@ -278,7 +282,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
278 struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane); 282 struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
279 struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc); 283 struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
280 284
281 if (plane->state->crtc) 285 if (plane->state->visible)
282 rcar_du_vsp_plane_setup(rplane); 286 rcar_du_vsp_plane_setup(rplane);
283 else 287 else
284 vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe, 288 vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,