diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2015-04-28 21:51:01 (GMT) |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2015-05-25 12:34:12 (GMT) |
commit | c8af99b60421c184cab1c3a849debce1463ec792 (patch) | |
tree | f5623ebe8570267c49c3ec782adc0f2a3ad3e835 /drivers/gpu/drm/rcar-du | |
parent | 2a57e9b5af2b96c45d8c73d34416e5dfa5dd38d9 (diff) | |
download | linux-c8af99b60421c184cab1c3a849debce1463ec792.tar.xz |
drm: rcar-du: Consider plane to CRTC associations in the plane allocator
Hardware planes are driven by the timing generator of the CRTC they are
associated to. Changing the association requires restarting the CRTC
group that the plane belongs to, resulting in flicker on the other CRTC.
To avoid flicker as much as possible, try to allocate planes first from
the free planes already associated with the target CRTC. If allocation
fails then fall back to allocation from all free planes.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/rcar-du')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_kms.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index ade1350..2c6cf69 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -383,6 +383,8 @@ static int rcar_du_atomic_check(struct drm_device *dev, for (i = 0; i < dev->mode_config.num_total_plane; ++i) { struct rcar_du_plane_state *plane_state; struct rcar_du_plane *plane; + unsigned int crtc_planes; + unsigned int free; int idx; if (!state->planes[i]) @@ -401,8 +403,21 @@ static int rcar_du_atomic_check(struct drm_device *dev, !rcar_du_plane_needs_realloc(plane, plane_state)) continue; + /* Try to allocate the plane from the free planes currently + * associated with the target CRTC to avoid restarting the CRTC + * group and thus minimize flicker. If it fails fall back to + * allocating from all free planes. + */ + crtc_planes = to_rcar_crtc(plane_state->state.crtc)->index % 2 + ? plane->group->dptsr_planes + : ~plane->group->dptsr_planes; + free = group_free_planes[plane->group->index]; + idx = rcar_du_plane_hwalloc(plane_state->format->planes, - group_free_planes[plane->group->index]); + free & crtc_planes); + if (idx < 0) + idx = rcar_du_plane_hwalloc(plane_state->format->planes, + free); if (idx < 0) { dev_dbg(rcdu->dev, "%s: no available hardware plane\n", __func__); @@ -749,6 +764,11 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) rgrp->mmio_offset = mmio_offsets[i]; rgrp->index = i; + /* Pre-associate all hardware planes with the first CRTC in the + * group. + */ + rgrp->dptsr_planes = 0; + ret = rcar_du_planes_init(rgrp); if (ret < 0) return ret; |