diff options
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_atomic_uapi.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/loongson/lsdc_plane.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_plane.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 2 | ||||
-rw-r--r-- | include/drm/drm_modeset_helper_vtables.h | 7 |
9 files changed, 42 insertions, 18 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index d6a206fc9ddd..fd3d14592663 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1966,7 +1966,7 @@ int drm_atomic_helper_async_check(struct drm_device *dev, return -EBUSY; } - ret = funcs->atomic_async_check(plane, state); + ret = funcs->atomic_async_check(plane, state, false); if (ret != 0) drm_dbg_atomic(dev, "[PLANE:%d:%s] driver async check failed\n", diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 370dc676e3aa..2765ba90ad8f 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -27,8 +27,9 @@ * Daniel Vetter <daniel.vetter@ffwll.ch> */ -#include <drm/drm_atomic_uapi.h> #include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_atomic_uapi.h> #include <drm/drm_framebuffer.h> #include <drm/drm_print.h> #include <drm/drm_drv.h> @@ -1063,6 +1064,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state, struct drm_plane *plane = obj_to_plane(obj); struct drm_plane_state *plane_state; struct drm_mode_config *config = &plane->dev->mode_config; + const struct drm_plane_helper_funcs *plane_funcs = plane->helper_private; plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { @@ -1070,15 +1072,30 @@ int drm_atomic_set_property(struct drm_atomic_state *state, break; } - if (async_flip && - (plane_state->plane->type != DRM_PLANE_TYPE_PRIMARY || - (prop != config->prop_fb_id && - prop != config->prop_in_fence_fd && - prop != config->prop_fb_damage_clips))) { - ret = drm_atomic_plane_get_property(plane, plane_state, - prop, &old_val); - ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop); - break; + if (async_flip) { + /* check if the prop does a nop change */ + if ((prop != config->prop_fb_id && + prop != config->prop_in_fence_fd && + prop != config->prop_fb_damage_clips)) { + ret = drm_atomic_plane_get_property(plane, plane_state, + prop, &old_val); + ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop); + } + + /* ask the driver if this non-primary plane is supported */ + if (plane->type != DRM_PLANE_TYPE_PRIMARY) { + ret = -EINVAL; + + if (plane_funcs && plane_funcs->atomic_async_check) + ret = plane_funcs->atomic_async_check(plane, state, true); + + if (ret) { + drm_dbg_atomic(prop->dev, + "[PLANE:%d:%s] does not support async flips\n", + obj->id, plane->name); + break; + } + } } ret = drm_atomic_plane_set_property(plane, diff --git a/drivers/gpu/drm/loongson/lsdc_plane.c b/drivers/gpu/drm/loongson/lsdc_plane.c index d227a2c1dcf1..aa9a97f9c4dc 100644 --- a/drivers/gpu/drm/loongson/lsdc_plane.c +++ b/drivers/gpu/drm/loongson/lsdc_plane.c @@ -171,7 +171,8 @@ static const struct drm_plane_helper_funcs lsdc_primary_helper_funcs = { }; static int lsdc_cursor_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, + bool flip) { struct drm_plane_state *new_state; struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c index 8a48b3b0a956..655106bbb76d 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_plane.c @@ -101,7 +101,7 @@ static void mtk_plane_destroy_state(struct drm_plane *plane, } static int mtk_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, bool flip) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 62de248ed1b0..bb1601921938 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -368,7 +368,7 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane, } static int mdp5_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, bool flip) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 57747f1cff26..e3596e2b557d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1072,7 +1072,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, } static int vop_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, bool flip) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 430b2eededb2..798507a8ae56 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1025,7 +1025,8 @@ static void tegra_cursor_atomic_disable(struct drm_plane *plane, tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); } -static int tegra_cursor_atomic_async_check(struct drm_plane *plane, struct drm_atomic_state *state) +static int tegra_cursor_atomic_async_check(struct drm_plane *plane, struct drm_atomic_state *state, + bool flip) { struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane); struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index d608860d525f..c5e84d3494d2 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -2338,7 +2338,7 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, } static int vc4_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, bool flip) { struct vc4_dev *vc4 = to_vc4_dev(plane->dev); struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index b62f41f48962..ce7c7aeac887 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1400,13 +1400,18 @@ struct drm_plane_helper_funcs { * given update can be committed asynchronously, that is, if it can * jump ahead of the state currently queued for update. * + * This function is also used by drm_atomic_set_property() to determine + * if the plane can be flipped in async. The flip flag is used to + * distinguish if the function is used for just the plane state or for a + * flip. + * * RETURNS: * * Return 0 on success and any error returned indicates that the update * can not be applied in asynchronous manner. */ int (*atomic_async_check)(struct drm_plane *plane, - struct drm_atomic_state *state); + struct drm_atomic_state *state, bool flip); /** * @atomic_async_update: |