From ca07b210bc5c124cc194d0c7b91354c636e36394 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 22 Jan 2018 10:25:23 +0100 Subject: drm/sun4i: backend: Wire in the frontend Now that we have a driver, we can make use of it. This is done by adding a flag to our custom plane state that will trigger whether we should use the frontend on that particular plane or not. The rest is just plumbing to set up the backend to not perform the DMA but receive its data from the frontend. Note that we're still not making any use of the frontend itself, as no one is setting the flag yet. Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/cdffc25eab2d817820cc78cbd24f1f4b99902014.1516613040.git-series.maxime.ripard@free-electrons.com --- drivers/gpu/drm/sun4i/sun4i_layer.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/sun4i/sun4i_layer.c') diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index b85a9a02d166..4652b25be0d2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -15,6 +15,7 @@ #include #include "sun4i_backend.h" +#include "sun4i_frontend.h" #include "sun4i_layer.h" #include "sunxi_engine.h" @@ -48,6 +49,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) static struct drm_plane_state * sun4i_backend_layer_duplicate_state(struct drm_plane *plane) { + struct sun4i_layer_state *orig = state_to_sun4i_layer_state(plane->state); struct sun4i_layer_state *copy; copy = kzalloc(sizeof(*copy), GFP_KERNEL); @@ -55,6 +57,7 @@ sun4i_backend_layer_duplicate_state(struct drm_plane *plane) return NULL; __drm_atomic_helper_plane_duplicate_state(plane, ©->state); + copy->uses_frontend = orig->uses_frontend; return ©->state; } @@ -72,21 +75,45 @@ static void sun4i_backend_layer_destroy_state(struct drm_plane *plane, static void sun4i_backend_layer_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(old_state); struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_backend *backend = layer->backend; sun4i_backend_layer_enable(backend, layer->id, false); + + if (layer_state->uses_frontend) { + unsigned long flags; + + spin_lock_irqsave(&backend->frontend_lock, flags); + backend->frontend_teardown = true; + spin_unlock_irqrestore(&backend->frontend_lock, flags); + } } static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { + struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane->state); struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_backend *backend = layer->backend; + struct sun4i_frontend *frontend = backend->frontend; + + if (layer_state->uses_frontend) { + sun4i_frontend_init(frontend); + sun4i_frontend_update_coord(frontend, plane); + sun4i_frontend_update_buffer(frontend, plane); + sun4i_frontend_update_formats(frontend, plane, + DRM_FORMAT_ARGB8888); + sun4i_backend_update_layer_frontend(backend, layer->id, + DRM_FORMAT_ARGB8888); + sun4i_backend_update_layer_coord(backend, layer->id, plane); + sun4i_frontend_enable(frontend); + } else { + sun4i_backend_update_layer_coord(backend, layer->id, plane); + sun4i_backend_update_layer_formats(backend, layer->id, plane); + sun4i_backend_update_layer_buffer(backend, layer->id, plane); + } - sun4i_backend_update_layer_coord(backend, layer->id, plane); - sun4i_backend_update_layer_formats(backend, layer->id, plane); - sun4i_backend_update_layer_buffer(backend, layer->id, plane); sun4i_backend_layer_enable(backend, layer->id, true); } -- cgit v1.2.3