Hello,
This patch series fixes support for planes that cross the screen boundaries. The KMS API supports such a configuration, but the DU and VSP hardware doesn't. This leads to different kind of dispay artifacts or hangs.
The series starts with a bit of refactoring to share existing code and make it easier to share new code. The second patch then clips planes that are either partially or fully off-screen, disabling planes that end up being completely invisible.
Compared to v2, the series has been rebased on top of the latest drm+drm-misc to benefit from Ville's rework of the plane state check helper, and now actually uses the clipped source and destination rectangles (and hence passes the tests).
Compared to v1, fully off-screen planes are now accepted (but obviously not shown).
The patches are based on top of Dave's latest master branch.
The series has been tested on a Salvator-XS board.
Laurent Pinchart (2): drm: rcar-du: Share plane atomic check code between Gen2 and Gen3 drm: rcar-du: Clip planes to screen boundaries
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 75 +++++++++++++++++++++++---------- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 4 ++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 64 +++++++++++----------------- 4 files changed, 83 insertions(+), 63 deletions(-)
The plane atomic check implementation is identical on Gen2 (DU planes) and Gen3 (VSP planes), but two separate functions exist as they operate on different data structures. Refactor the code to share the implementation.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Tested-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com --- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 27 +++++++++++++++++---------- drivers/gpu/drm/rcar-du/rcar_du_plane.h | 4 ++++ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 22 +--------------------- 3 files changed, 22 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 61833cc1c699..4f076c364f25 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -565,27 +565,26 @@ void __rcar_du_plane_setup(struct rcar_du_group *rgrp, } }
-static int rcar_du_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) +int __rcar_du_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state, + const struct rcar_du_format_info **format) { - struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); - struct rcar_du_plane *rplane = to_rcar_plane(plane); - struct rcar_du_device *rcdu = rplane->group->dev; + struct drm_device *dev = plane->dev;
if (!state->fb || !state->crtc) { - rstate->format = NULL; + *format = NULL; return 0; }
if (state->src_w >> 16 != state->crtc_w || state->src_h >> 16 != state->crtc_h) { - dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); + dev_dbg(dev->dev, "%s: scaling not supported\n", __func__); return -EINVAL; }
- rstate->format = rcar_du_format_info(state->fb->format->format); - if (rstate->format == NULL) { - dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, + *format = rcar_du_format_info(state->fb->format->format); + if (*format == NULL) { + dev_dbg(dev->dev, "%s: unsupported format %08x\n", __func__, state->fb->format->format); return -EINVAL; } @@ -593,6 +592,14 @@ static int rcar_du_plane_atomic_check(struct drm_plane *plane, return 0; }
+static int rcar_du_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct rcar_du_plane_state *rstate = to_rcar_plane_state(state); + + return __rcar_du_plane_atomic_check(plane, state, &rstate->format); +} + static void rcar_du_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index f62e09f195de..890321b4665d 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h @@ -73,6 +73,10 @@ to_rcar_plane_state(struct drm_plane_state *state) int rcar_du_atomic_check_planes(struct drm_device *dev, struct drm_atomic_state *state);
+int __rcar_du_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state, + const struct rcar_du_format_info **format); + int rcar_du_planes_init(struct rcar_du_group *rgrp);
void __rcar_du_plane_setup(struct rcar_du_group *rgrp, diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 2c96147bc444..dd66dcb8da23 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -268,28 +268,8 @@ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state); - struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane); - struct rcar_du_device *rcdu = rplane->vsp->dev; - - if (!state->fb || !state->crtc) { - rstate->format = NULL; - return 0; - }
- if (state->src_w >> 16 != state->crtc_w || - state->src_h >> 16 != state->crtc_h) { - dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); - return -EINVAL; - } - - rstate->format = rcar_du_format_info(state->fb->format->format); - if (rstate->format == NULL) { - dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, - state->fb->format->format); - return -EINVAL; - } - - return 0; + return __rcar_du_plane_atomic_check(plane, state, &rstate->format); }
static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
Unlike the KMS API, the hardware doesn't support planes exceeding the screen boundaries or planes being located fully off-screen. We need to clip plane coordinates to support the use case.
Fortunately the DRM core offers a drm_atomic_helper_check_plane_state() helper that valides the scaling factor and clips the plane coordinates. Use it to implement the plane atomic check and use the clipped source and destination rectangles from the plane state instead of the unclipped source and CRTC coordinates to configure the device.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com --- Changes since v2:
- Actually use the clipped source and destination rectangles - Use drm_crtc_state::mode instead of drm_crtc_state::adjusted_mode where applicable - Removed spurious semicolon - Rebased on top of latest drm+drm-misc --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 50 ++++++++++++++++++++++++--------- 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) struct rcar_du_plane *plane = &rcrtc->group->planes[i]; unsigned int j;
- if (plane->plane.state->crtc != &rcrtc->crtc) + if (plane->plane.state->crtc != &rcrtc->crtc || + !plane->plane.state->visible) continue;
/* 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, static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, const struct rcar_du_plane_state *state) { - unsigned int src_x = state->state.src_x >> 16; - unsigned int src_y = state->state.src_y >> 16; + unsigned int src_x = state->state.src.x1 >> 16; + unsigned int src_y = state->state.src.y1 >> 16; unsigned int index = state->hwindex; unsigned int pitch; bool interlaced; @@ -357,7 +357,7 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, dma[i] = gem->paddr + fb->offsets[i]; } } else { - pitch = state->state.src_w >> 16; + pitch = drm_rect_width(&state->state.src) >> 16; dma[0] = 0; dma[1] = 0; } @@ -521,6 +521,7 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp, const struct rcar_du_plane_state *state) { struct rcar_du_device *rcdu = rgrp->dev; + const struct drm_rect *dst = &state->state.dst;
if (rcdu->info->gen < 3) 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, rcar_du_plane_setup_format_gen3(rgrp, index, state);
/* Destination position and size */ - rcar_du_plane_write(rgrp, index, PnDSXR, state->state.crtc_w); - rcar_du_plane_write(rgrp, index, PnDSYR, state->state.crtc_h); - rcar_du_plane_write(rgrp, index, PnDPXR, state->state.crtc_x); - rcar_du_plane_write(rgrp, index, PnDPYR, state->state.crtc_y); + rcar_du_plane_write(rgrp, index, PnDSXR, drm_rect_width(dst)); + rcar_du_plane_write(rgrp, index, PnDSYR, drm_rect_height(dst)); + rcar_du_plane_write(rgrp, index, PnDPXR, dst->x1); + rcar_du_plane_write(rgrp, index, PnDPYR, dst->y1);
if (rcdu->info->gen < 3) { /* Wrap-around and blinking, disabled */ @@ -570,16 +571,39 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane, const struct rcar_du_format_info **format) { struct drm_device *dev = plane->dev; + struct drm_crtc_state *crtc_state; + struct drm_rect clip; + int ret;
- if (!state->fb || !state->crtc) { + if (!state->crtc) { + /* + * The visible field is not reset by the DRM core but only + * updated by drm_plane_helper_check_state(), set it manually. + */ + state->visible = false; *format = NULL; return 0; }
- if (state->src_w >> 16 != state->crtc_w || - state->src_h >> 16 != state->crtc_h) { - dev_dbg(dev->dev, "%s: scaling not supported\n", __func__); - return -EINVAL; + crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + clip.x1 = 0; + clip.y1 = 0; + clip.x2 = crtc_state->mode.hdisplay; + clip.y2 = crtc_state->mode.vdisplay; + + ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + true, true); + if (ret < 0) + return ret; + + if (!state->visible) { + *format = NULL; + return 0; }
*format = rcar_du_format_info(state->fb->format->format); @@ -607,7 +631,7 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane, struct rcar_du_plane_state *old_rstate; struct rcar_du_plane_state *new_rstate;
- if (!plane->state->crtc) + if (!plane->state->visible) return;
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) struct rcar_du_plane_state state = { .state = { .crtc = &crtc->crtc, - .crtc_x = 0, - .crtc_y = 0, - .crtc_w = mode->hdisplay, - .crtc_h = mode->vdisplay, - .src_x = 0, - .src_y = 0, - .src_w = mode->hdisplay << 16, - .src_h = mode->vdisplay << 16, + .dst.x1 = 0, + .dst.y1 = 0, + .dst.x2 = mode->hdisplay, + .dst.y2 = mode->vdisplay, + .src.x1 = 0, + .src.y1 = 0, + .src.x2 = mode->hdisplay << 16, + .src.y2 = mode->vdisplay << 16, .zpos = 0, }, .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) }; unsigned int i;
- cfg.src.left = state->state.src_x >> 16; - cfg.src.top = state->state.src_y >> 16; - cfg.src.width = state->state.src_w >> 16; - cfg.src.height = state->state.src_h >> 16; + cfg.src.left = state->state.src.x1 >> 16; + cfg.src.top = state->state.src.y1 >> 16; + cfg.src.width = drm_rect_width(&state->state.src) >> 16; + cfg.src.height = drm_rect_height(&state->state.src) >> 16;
- cfg.dst.left = state->state.crtc_x; - cfg.dst.top = state->state.crtc_y; - cfg.dst.width = state->state.crtc_w; - cfg.dst.height = state->state.crtc_h; + cfg.dst.left = state->state.dst.x1; + cfg.dst.top = state->state.dst.y1; + cfg.dst.width = drm_rect_width(&state->state.dst); + cfg.dst.height = drm_rect_height(&state->state.dst);
for (i = 0; i < state->format->planes; ++i) 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, unsigned int i; int ret;
- if (!state->fb) + /* + * There's no need to prepare (and unprepare) the framebuffer when the + * plane is not visible, as it will not be displayed. + */ + if (!state->visible) return 0;
for (i = 0; i < rstate->format->planes; ++i) { @@ -253,7 +257,7 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane, struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; unsigned int i;
- if (!state->fb) + if (!state->visible) return;
for (i = 0; i < rstate->format->planes; ++i) { @@ -278,7 +282,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane, struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane); struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
- if (plane->state->crtc) + if (plane->state->visible) rcar_du_vsp_plane_setup(rplane); else vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
Hi Laurent,
Thankyou for the patch.
On 26/11/17 11:30, Laurent Pinchart wrote:
Unlike the KMS API, the hardware doesn't support planes exceeding the screen boundaries or planes being located fully off-screen. We need to clip plane coordinates to support the use case.
Fortunately the DRM core offers a drm_atomic_helper_check_plane_state() helper that valides the scaling factor and clips the plane coordinates.
s/valides/validates/
Use it to implement the plane atomic check and use the clipped source and destination rectangles from the plane state instead of the unclipped source and CRTC coordinates to configure the device.
Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com
Aside from the spelling error above - I can't find a fault here. Maybe next time :-)
Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com
Changes since v2:
- Actually use the clipped source and destination rectangles
- Use drm_crtc_state::mode instead of drm_crtc_state::adjusted_mode where applicable
- Removed spurious semicolon
- Rebased on top of latest drm+drm-misc
drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 +- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 50 ++++++++++++++++++++++++--------- 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) struct rcar_du_plane *plane = &rcrtc->group->planes[i]; unsigned int j;
if (plane->plane.state->crtc != &rcrtc->crtc)
if (plane->plane.state->crtc != &rcrtc->crtc ||
!plane->plane.state->visible) continue;
/* 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, static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, const struct rcar_du_plane_state *state) {
- unsigned int src_x = state->state.src_x >> 16;
- unsigned int src_y = state->state.src_y >> 16;
- unsigned int src_x = state->state.src.x1 >> 16;
- unsigned int src_y = state->state.src.y1 >> 16; unsigned int index = state->hwindex; unsigned int pitch; bool interlaced;
@@ -357,7 +357,7 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp, dma[i] = gem->paddr + fb->offsets[i]; } } else {
pitch = state->state.src_w >> 16;
dma[0] = 0; dma[1] = 0; }pitch = drm_rect_width(&state->state.src) >> 16;
@@ -521,6 +521,7 @@ static void rcar_du_plane_setup_format(struct rcar_du_group *rgrp, const struct rcar_du_plane_state *state) { struct rcar_du_device *rcdu = rgrp->dev;
const struct drm_rect *dst = &state->state.dst;
if (rcdu->info->gen < 3) 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, rcar_du_plane_setup_format_gen3(rgrp, index, state);
/* Destination position and size */
- rcar_du_plane_write(rgrp, index, PnDSXR, state->state.crtc_w);
- rcar_du_plane_write(rgrp, index, PnDSYR, state->state.crtc_h);
- rcar_du_plane_write(rgrp, index, PnDPXR, state->state.crtc_x);
- rcar_du_plane_write(rgrp, index, PnDPYR, state->state.crtc_y);
rcar_du_plane_write(rgrp, index, PnDSXR, drm_rect_width(dst));
rcar_du_plane_write(rgrp, index, PnDSYR, drm_rect_height(dst));
rcar_du_plane_write(rgrp, index, PnDPXR, dst->x1);
rcar_du_plane_write(rgrp, index, PnDPYR, dst->y1);
if (rcdu->info->gen < 3) { /* Wrap-around and blinking, disabled */
@@ -570,16 +571,39 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane, const struct rcar_du_format_info **format) { struct drm_device *dev = plane->dev;
- struct drm_crtc_state *crtc_state;
- struct drm_rect clip;
- int ret;
- if (!state->fb || !state->crtc) {
- if (!state->crtc) {
/*
* The visible field is not reset by the DRM core but only
* updated by drm_plane_helper_check_state(), set it manually.
*/
*format = NULL; return 0; }state->visible = false;
- if (state->src_w >> 16 != state->crtc_w ||
state->src_h >> 16 != state->crtc_h) {
dev_dbg(dev->dev, "%s: scaling not supported\n", __func__);
return -EINVAL;
crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
clip.x1 = 0;
clip.y1 = 0;
clip.x2 = crtc_state->mode.hdisplay;
clip.y2 = crtc_state->mode.vdisplay;
ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
DRM_PLANE_HELPER_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING,
true, true);
if (ret < 0)
return ret;
if (!state->visible) {
*format = NULL;
return 0;
}
*format = rcar_du_format_info(state->fb->format->format);
@@ -607,7 +631,7 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane, struct rcar_du_plane_state *old_rstate; struct rcar_du_plane_state *new_rstate;
- if (!plane->state->crtc)
if (!plane->state->visible) return;
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) struct rcar_du_plane_state state = { .state = { .crtc = &crtc->crtc,
.crtc_x = 0,
.crtc_y = 0,
.crtc_w = mode->hdisplay,
.crtc_h = mode->vdisplay,
.src_x = 0,
.src_y = 0,
.src_w = mode->hdisplay << 16,
.src_h = mode->vdisplay << 16,
.dst.x1 = 0,
.dst.y1 = 0,
.dst.x2 = mode->hdisplay,
.dst.y2 = mode->vdisplay,
.src.x1 = 0,
.src.y1 = 0,
.src.x2 = mode->hdisplay << 16,
}, .format = rcar_du_format_info(DRM_FORMAT_ARGB8888),.src.y2 = mode->vdisplay << 16, .zpos = 0,
@@ -178,15 +178,15 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane) }; unsigned int i;
- cfg.src.left = state->state.src_x >> 16;
- cfg.src.top = state->state.src_y >> 16;
- cfg.src.width = state->state.src_w >> 16;
- cfg.src.height = state->state.src_h >> 16;
- cfg.src.left = state->state.src.x1 >> 16;
- cfg.src.top = state->state.src.y1 >> 16;
- cfg.src.width = drm_rect_width(&state->state.src) >> 16;
- cfg.src.height = drm_rect_height(&state->state.src) >> 16;
- cfg.dst.left = state->state.crtc_x;
- cfg.dst.top = state->state.crtc_y;
- cfg.dst.width = state->state.crtc_w;
- cfg.dst.height = state->state.crtc_h;
cfg.dst.left = state->state.dst.x1;
cfg.dst.top = state->state.dst.y1;
cfg.dst.width = drm_rect_width(&state->state.dst);
cfg.dst.height = drm_rect_height(&state->state.dst);
for (i = 0; i < state->format->planes; ++i) 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, unsigned int i; int ret;
- if (!state->fb)
/*
* There's no need to prepare (and unprepare) the framebuffer when the
* plane is not visible, as it will not be displayed.
*/
if (!state->visible) return 0;
for (i = 0; i < rstate->format->planes; ++i) {
@@ -253,7 +257,7 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane, struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; unsigned int i;
- if (!state->fb)
if (!state->visible) return;
for (i = 0; i < rstate->format->planes; ++i) {
@@ -278,7 +282,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane, struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane); struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
- if (plane->state->crtc)
- if (plane->state->visible) rcar_du_vsp_plane_setup(rplane); else vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
dri-devel@lists.freedesktop.org