Commit c6c1f9bc authored by Liu Ying's avatar Liu Ying Committed by Philipp Zabel

drm/imx: Add active plane reconfiguration support

We don't support configuring active plane on-the-fly for imx-drm.
The relevant CRTC should be disabled before the plane configuration.
Of course, the plane itself should be disabled as well.
This patch adds active plane reconfiguration support by forcing CRTC
mode change and disabling-enabling plane in plane's ->atomic_update
callback.
Suggested-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Peter Senna Tschudin <peter.senna@gmail.com>
Signed-off-by: default avatarLiu Ying <gnuiyl@gmail.com>
Tested-by: default avatarPeter Senna Tschudin <peter.senna@gmail.com>
Tested-by: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent fa8410b3
...@@ -171,10 +171,34 @@ static void imx_drm_output_poll_changed(struct drm_device *drm) ...@@ -171,10 +171,34 @@ static void imx_drm_output_poll_changed(struct drm_device *drm)
drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
} }
static int imx_drm_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
int ret;
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
return ret;
ret = drm_atomic_helper_check_planes(dev, state);
if (ret)
return ret;
/*
* Check modeset again in case crtc_state->mode_changed is
* updated in plane's ->atomic_check callback.
*/
ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
return ret;
return ret;
}
static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
.fb_create = drm_fb_cma_create, .fb_create = drm_fb_cma_create,
.output_poll_changed = imx_drm_output_poll_changed, .output_poll_changed = imx_drm_output_poll_changed,
.atomic_check = drm_atomic_helper_check, .atomic_check = imx_drm_atomic_check,
.atomic_commit = drm_atomic_helper_commit, .atomic_commit = drm_atomic_helper_commit,
}; };
......
...@@ -319,13 +319,14 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, ...@@ -319,13 +319,14 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL; return -EINVAL;
/* /*
* since we cannot touch active IDMAC channels, we do not support * We support resizing active plane or changing its format by
* resizing the enabled plane or changing its format * forcing CRTC mode change and disabling-enabling plane in plane's
* ->atomic_update callback.
*/ */
if (old_fb && (state->src_w != old_state->src_w || if (old_fb && (state->src_w != old_state->src_w ||
state->src_h != old_state->src_h || state->src_h != old_state->src_h ||
fb->pixel_format != old_fb->pixel_format)) fb->pixel_format != old_fb->pixel_format))
return -EINVAL; crtc_state->mode_changed = true;
eba = drm_plane_state_to_eba(state); eba = drm_plane_state_to_eba(state);
...@@ -336,7 +337,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, ...@@ -336,7 +337,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL; return -EINVAL;
if (old_fb && fb->pitches[0] != old_fb->pitches[0]) if (old_fb && fb->pitches[0] != old_fb->pitches[0])
return -EINVAL; crtc_state->mode_changed = true;
switch (fb->pixel_format) { switch (fb->pixel_format) {
case DRM_FORMAT_YUV420: case DRM_FORMAT_YUV420:
...@@ -372,7 +373,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, ...@@ -372,7 +373,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL; return -EINVAL;
if (old_fb && old_fb->pitches[1] != fb->pitches[1]) if (old_fb && old_fb->pitches[1] != fb->pitches[1])
return -EINVAL; crtc_state->mode_changed = true;
} }
return 0; return 0;
...@@ -392,10 +393,16 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -392,10 +393,16 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
enum ipu_color_space ics; enum ipu_color_space ics;
if (old_state->fb) { if (old_state->fb) {
struct drm_crtc_state *crtc_state = state->crtc->state;
if (!crtc_state->mode_changed) {
ipu_plane_atomic_set_base(ipu_plane, old_state); ipu_plane_atomic_set_base(ipu_plane, old_state);
return; return;
} }
ipu_disable_plane(plane);
}
switch (ipu_plane->dp_flow) { switch (ipu_plane->dp_flow) {
case IPU_DP_FLOW_SYNC_BG: case IPU_DP_FLOW_SYNC_BG:
ipu_dp_setup_channel(ipu_plane->dp, ipu_dp_setup_channel(ipu_plane->dp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment