Commit 53229425 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'imx-drm-fixes-2016-08-30' of git://git.pengutronix.de/git/pza/linux into drm-fixes

imx-drm atomic modeset regression fixes

- add active plane reconfiguration support
- add back crtc vblank state reporting

* tag 'imx-drm-fixes-2016-08-30' of git://git.pengutronix.de/git/pza/linux:
  drm/imx: fix crtc vblank state regression
  drm/imx: Add active plane reconfiguration support
parents 27dd7350 a4744786
...@@ -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,
}; };
......
...@@ -76,6 +76,8 @@ static void ipu_crtc_disable(struct drm_crtc *crtc) ...@@ -76,6 +76,8 @@ static void ipu_crtc_disable(struct drm_crtc *crtc)
crtc->state->event = NULL; crtc->state->event = NULL;
} }
spin_unlock_irq(&crtc->dev->event_lock); spin_unlock_irq(&crtc->dev->event_lock);
drm_crtc_vblank_off(crtc);
} }
static void imx_drm_crtc_reset(struct drm_crtc *crtc) static void imx_drm_crtc_reset(struct drm_crtc *crtc)
...@@ -175,6 +177,8 @@ static int ipu_crtc_atomic_check(struct drm_crtc *crtc, ...@@ -175,6 +177,8 @@ static int ipu_crtc_atomic_check(struct drm_crtc *crtc,
static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state)
{ {
drm_crtc_vblank_on(crtc);
spin_lock_irq(&crtc->dev->event_lock); spin_lock_irq(&crtc->dev->event_lock);
if (crtc->state->event) { if (crtc->state->event) {
WARN_ON(drm_crtc_vblank_get(crtc)); WARN_ON(drm_crtc_vblank_get(crtc));
......
...@@ -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