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@ffwll.ch
Reviewed-by: Sean Paul seanpaul@chromium.org
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@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel