On Sun, Nov 02, 2014 at 02:19:22PM +0100, Daniel Vetter wrote:
> These two functions allow drivers to reuse their atomic plane helpers
> functions for the primary plane to implement the interfaces required
> by the crtc helpers for the legacy ->set_config callback.
>
> This is purely transitional and won't be used once the driver is fully
> converted. But it allows partial conversions to the atomic plane
> helpers which are functional.
>
> v2:
> - Use ->atomic_duplicate_state if available.
> - Don't forget to run crtc_funcs->atomic_check.
>
> v3: Shift source coordinates correctly for 16.16 fixed point.
>
> v4: Don't forget to call ->atomic_destroy_state if available.
>
> v5: Fixup kerneldoc.
>
> v6: Reuse the plane_commit function from the transitional plane
> helpers to avoid too much duplication.
>
> v7:
> - Remove some stale comment.
> - Correctly handle the lack of plane->state object, necessary for
> transitional use.
>
> v8: Fixup an embarrassing h/vdisplay mixup.
>
> Signed-off-by: Daniel Vetter
Reviewed-by: Sean Paul
> ---
> drivers/gpu/drm/drm_crtc_helper.c | 110
> +
> drivers/gpu/drm/drm_plane_helper.c | 10 ++--
> include/drm/drm_crtc.h | 4 ++
> include/drm/drm_crtc_helper.h | 7 +++
> include/drm/drm_plane_helper.h | 4 ++
> 5 files changed, 130 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c
> b/drivers/gpu/drm/drm_crtc_helper.c
> index 6c65a0a28fbd..95ecbb131053 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -38,6 +38,7 @@
> #include
> #include
> #include
> +#include
> #include
>
> MODULE_AUTHOR("David Airlie, Jesse Barnes");
> @@ -888,3 +889,112 @@ void drm_helper_resume_force_mode(struct drm_device
> *dev)
> drm_modeset_unlock_all(dev);
> }
> EXPORT_SYMBOL(drm_helper_resume_force_mode);
> +
> +/**
> + * drm_helper_crtc_mode_set - mode_set implementation for atomic plane
> helpers
> + * @crtc: DRM CRTC
> + * @mode: DRM display mode which userspace requested
> + * @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
> + * @x: x offset of the CRTC scanout area on the underlying framebuffer
> + * @y: y offset of the CRTC scanout area on the underlying framebuffer
> + * @old_fb: previous framebuffer
> + *
> + * This function implements a callback useable as the ->mode_set callback
> + * required by the crtc helpers. Besides the atomic plane helper functions
> for
> + * the primary plane the driver must also provide the ->mode_set_nofb
> callback
> + * to set up the crtc.
> + *
> + * This is a transitional helper useful for converting drivers to the atomic
> + * interfaces.
> + */
> +int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode
> *mode,
> + struct drm_display_mode *adjusted_mode, int x, int y,
> + struct drm_framebuffer *old_fb)
> +{
> + struct drm_crtc_state *crtc_state;
> + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
> + int ret;
> +
> + if (crtc->funcs->atomic_duplicate_state)
> + crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
> + else if (crtc->state)
> + crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
> + GFP_KERNEL);
> + else
> + crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
> + if (!crtc_state)
> + return -ENOMEM;
> +
> + crtc_state->enable = true;
> + crtc_state->planes_changed = true;
> + drm_mode_copy(_state->mode, mode);
> + drm_mode_copy(_state->adjusted_mode, adjusted_mode);
> +
> + if (crtc_funcs->atomic_check) {
> + ret = crtc_funcs->atomic_check(crtc, crtc_state);
> + if (ret) {
> + kfree(crtc_state);
> +
> + return ret;
> + }
> + }
> +
> + swap(crtc->state, crtc_state);
> +
> + crtc_funcs->mode_set_nofb(crtc);
> +
> + if (crtc_state) {
> + if (crtc->funcs->atomic_destroy_state)
> + crtc->funcs->atomic_destroy_state(crtc, crtc_state);
> + else
> + kfree(crtc_state);
> + }
> +
> + return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
> +}
> +EXPORT_SYMBOL(drm_helper_crtc_mode_set);
> +
> +/**
> + * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic
> plane helpers
> + * @crtc: DRM CRTC
> + * @x: x offset of the CRTC scanout area on the underlying framebuffer
> + * @y: y offset of the CRTC scanout area on the underlying framebuffer
> + * @old_fb: previous framebuffer
> + *
> + * This function implements a callback useable as the ->mode_set_base used
> + * required by the crtc helpers. The driver must provide the atomic plane
> helper
> + * functions for the primary plane.
> + *
> + * This is a transitional helper useful for converting drivers to the atomic
> + * interfaces.
> + */
> +int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> + struct drm_framebuffer *old_fb)
> +{
> + struct drm_plane_state *plane_state;
> + struct drm_plane *plane = crtc->primary;
> +
> + if (plane->funcs->atomic_duplicate_state)
> + plane_state =