diff options
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_plane.c | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 |
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, | |||
332 | static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, | 332 | static 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, |