diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_layer.c')
| -rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_layer.c | 33 |
1 files changed, 30 insertions, 3 deletions
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 <drm/drmP.h> #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); } |