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 <daniel.vetter@xxxxxxxx> Reviewed-by: Sean Paul <seanpaul@xxxxxxxxxxxx> > --- > 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 <drm/drm_fourcc.h> > #include <drm/drm_crtc_helper.h> > #include <drm/drm_fb_helper.h> > +#include <drm/drm_plane_helper.h> > #include <drm/drm_edid.h> > > 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(&crtc_state->mode, mode); > + drm_mode_copy(&crtc_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 = plane->funcs->atomic_duplicate_state(plane); > + else if (plane->state) > + plane_state = kmemdup(plane->state, sizeof(*plane_state), > + GFP_KERNEL); > + else > + plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); > + if (!plane_state) > + return -ENOMEM; > + > + plane_state->crtc = crtc; > + plane_state->fb = crtc->primary->fb; > + plane_state->crtc_x = 0; > + plane_state->crtc_y = 0; > + plane_state->crtc_h = crtc->mode.vdisplay; > + plane_state->crtc_w = crtc->mode.hdisplay; > + plane_state->src_x = x << 16; > + plane_state->src_y = y << 16; > + plane_state->src_h = crtc->mode.vdisplay << 16; > + plane_state->src_w = crtc->mode.hdisplay << 16; > + > + return drm_plane_helper_commit(plane, plane_state, old_fb); > +} > +EXPORT_SYMBOL(drm_helper_crtc_mode_set_base); > diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c > index 45aa8c98e3fb..40ecb2c6e858 100644 > --- a/drivers/gpu/drm/drm_plane_helper.c > +++ b/drivers/gpu/drm/drm_plane_helper.c > @@ -370,9 +370,9 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, > } > EXPORT_SYMBOL(drm_crtc_init); > > -static int > -plane_commit(struct drm_plane *plane, struct drm_plane_state *plane_state, > - struct drm_framebuffer *old_fb) > +int drm_plane_helper_commit(struct drm_plane *plane, > + struct drm_plane_state *plane_state, > + struct drm_framebuffer *old_fb) > { > struct drm_plane_helper_funcs *plane_funcs; > struct drm_crtc *crtc[2]; > @@ -497,7 +497,7 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, > plane_state->src_h = src_h; > plane_state->src_w = src_w; > > - return plane_commit(plane, plane_state, plane->fb); > + return drm_plane_helper_commit(plane, plane_state, plane->fb); > } > EXPORT_SYMBOL(drm_plane_helper_update); > > @@ -536,6 +536,6 @@ int drm_plane_helper_disable(struct drm_plane *plane) > plane_state->crtc = NULL; > plane_state->fb = NULL; > > - return plane_commit(plane, plane_state, plane->fb); > + return drm_plane_helper_commit(plane, plane_state, plane->fb); > } > EXPORT_SYMBOL(drm_plane_helper_disable); > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index d0068b7af678..77ff8992a3b7 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -230,6 +230,7 @@ struct drm_atomic_state; > * struct drm_crtc_state - mutable crtc state > * @enable: whether the CRTC should be enabled, gates all other state > * @planes_changed: for use by helpers and drivers when computing state updates > + * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings > * @mode: current mode timings > * @event: optional pointer to a DRM event to signal upon completion of the > * state update > @@ -241,6 +242,9 @@ struct drm_crtc_state { > /* computed state bits used by helpers and drivers */ > bool planes_changed : 1; > > + /* adjusted_mode: for use by helpers and drivers */ > + struct drm_display_mode adjusted_mode; > + > struct drm_display_mode mode; > > struct drm_pending_vblank_event *event; > diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h > index adec48b27aa5..7adbb65ea8ae 100644 > --- a/include/drm/drm_crtc_helper.h > +++ b/include/drm/drm_crtc_helper.h > @@ -68,6 +68,7 @@ struct drm_crtc_helper_funcs { > int (*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); > + void (*mode_set_nofb)(struct drm_crtc *crtc); > > /* Move the crtc on the current fb to the given position *optional* */ > int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, > @@ -167,6 +168,12 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, > > extern void drm_helper_resume_force_mode(struct drm_device *dev); > > +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); > +int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, > + struct drm_framebuffer *old_fb); > + > /* drm_probe_helper.c */ > extern int drm_helper_probe_single_connector_modes(struct drm_connector > *connector, uint32_t maxX, > diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h > index 8a0709704af0..62acb3c940b4 100644 > --- a/include/drm/drm_plane_helper.h > +++ b/include/drm/drm_plane_helper.h > @@ -102,4 +102,8 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc, > uint32_t src_w, uint32_t src_h); > int drm_plane_helper_disable(struct drm_plane *plane); > > +/* For use by drm_crtc_helper.c */ > +int drm_plane_helper_commit(struct drm_plane *plane, > + struct drm_plane_state *plane_state, > + struct drm_framebuffer *old_fb); > #endif > -- > 2.1.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel