---
 drivers/gpu/drm/logicvc/logicvc_drm.h   |   3 +
 drivers/gpu/drm/logicvc/logicvc_layer.c | 143 +++++++++++++++++++++++-
 drivers/gpu/drm/logicvc/logicvc_layer.h |   7 ++
 3 files changed, 149 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.h 
b/drivers/gpu/drm/logicvc/logicvc_drm.h
index 68bbac6c4ab9..d69a686ab0f1 100644
--- a/drivers/gpu/drm/logicvc/logicvc_drm.h
+++ b/drivers/gpu/drm/logicvc/logicvc_drm.h
@@ -59,6 +59,9 @@ struct logicvc_drm {
        struct list_head layers_list;
        struct logicvc_crtc *crtc;
        struct logicvc_interface *interface;
+
+       struct drm_property *colorkey_enabled_property;
+       struct drm_property *colorkey_value_property;
 };
 
 #endif
diff --git a/drivers/gpu/drm/logicvc/logicvc_layer.c 
b/drivers/gpu/drm/logicvc/logicvc_layer.c
index 98c3c70b37b0..6a8254103145 100644
--- a/drivers/gpu/drm/logicvc/logicvc_layer.c
+++ b/drivers/gpu/drm/logicvc/logicvc_layer.c
@@ -23,6 +23,8 @@
 
 #define logicvc_layer(p) \
        container_of(p, struct logicvc_layer, drm_plane)
+#define logicvc_layer_state(p) \
+       container_of(p, struct logicvc_layer_state, drm_plane_state)
 
 static uint32_t logicvc_layer_formats_rgb16[] = {
        DRM_FORMAT_RGB565,
@@ -135,6 +137,7 @@ static void logicvc_plane_atomic_update(struct drm_plane 
*drm_plane,
        struct logicvc_layer *layer = logicvc_layer(drm_plane);
        struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
        struct drm_plane_state *state = drm_plane->state;
+       struct logicvc_layer_state *layer_state = logicvc_layer_state(state);
        struct drm_crtc *drm_crtc = &logicvc->crtc->drm_crtc;
        struct drm_display_mode *mode = &drm_crtc->state->adjusted_mode;
        struct drm_framebuffer *fb = state->fb;
@@ -210,6 +213,15 @@ static void logicvc_plane_atomic_update(struct drm_plane 
*drm_plane,
                             alpha);
        }
 
+       /* Layer colorkey */
+
+       if (layer_state->colorkey_enabled) {
+               reg = layer_state->colorkey_value;
+
+               regmap_write(logicvc->regmap,
+                            LOGICVC_LAYER_COLOR_KEY_REG(index), reg);
+       }
+
        /* Layer control */
 
        reg = LOGICVC_LAYER_CTRL_ENABLE;
@@ -217,7 +229,8 @@ static void logicvc_plane_atomic_update(struct drm_plane 
*drm_plane,
        if (logicvc_layer_format_inverted(fb->format->format))
                reg |= LOGICVC_LAYER_CTRL_PIXEL_FORMAT_INVERT;
 
-       reg |= LOGICVC_LAYER_CTRL_COLOR_KEY_DISABLE;
+       if (!layer_state->colorkey_enabled)
+               reg |= LOGICVC_LAYER_CTRL_COLOR_KEY_DISABLE;
 
        regmap_write(logicvc->regmap, LOGICVC_LAYER_CTRL_REG(index), reg);
 }
@@ -238,13 +251,108 @@ static struct drm_plane_helper_funcs 
logicvc_plane_helper_funcs = {
        .atomic_disable         = logicvc_plane_atomic_disable,
 };
 
+static void logicvc_plane_reset(struct drm_plane *drm_plane)
+{
+       struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
+       struct device *dev = logicvc->drm_dev.dev;
+       struct logicvc_layer_state *layer_state;
+
+       if (drm_plane->state) {
+               layer_state = logicvc_layer_state(drm_plane->state);
+               __drm_atomic_helper_plane_destroy_state(drm_plane->state);
+               devm_kfree(dev, layer_state);
+               drm_plane->state = NULL;
+       }
+
+       layer_state = devm_kzalloc(dev, sizeof(*layer_state), GFP_KERNEL);
+       if (!layer_state)
+               return;
+
+       __drm_atomic_helper_plane_reset(drm_plane,
+                                       &layer_state->drm_plane_state);
+}
+
+static struct drm_plane_state *logicvc_plane_atomic_duplicate_state(struct 
drm_plane *drm_plane)
+{
+       struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
+       struct device *dev = logicvc->drm_dev.dev;
+       struct logicvc_layer_state *layer_state_current;
+       struct logicvc_layer_state *layer_state;
+
+       if (WARN_ON(!drm_plane->state))
+               return NULL;
+
+       layer_state_current = logicvc_layer_state(drm_plane->state);
+       layer_state = devm_kzalloc(dev, sizeof(*layer_state), GFP_KERNEL);
+       if (!layer_state)
+               return NULL;
+
+       layer_state->colorkey_enabled = layer_state_current->colorkey_enabled;
+       layer_state->colorkey_value = layer_state_current->colorkey_value;
+
+       __drm_atomic_helper_plane_duplicate_state(drm_plane,
+                                                 
&layer_state->drm_plane_state);
+
+       return &layer_state->drm_plane_state;
+}
+
+static void logicvc_plane_destroy_state(struct drm_plane *drm_plane,
+                                       struct drm_plane_state *state)
+{
+       struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
+       struct device *dev = logicvc->drm_dev.dev;
+       struct logicvc_layer_state *layer_state = logicvc_layer_state(state);
+
+       __drm_atomic_helper_plane_destroy_state(&layer_state->drm_plane_state);
+
+       devm_kfree(dev, layer_state);
+}
+
+static int logicvc_plane_atomic_set_property(struct drm_plane *drm_plane,
+                                            struct drm_plane_state *state,
+                                            struct drm_property *property,
+                                            uint64_t value)
+{
+       struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
+       struct logicvc_layer_state *layer_state = logicvc_layer_state(state);
+
+       if (property == logicvc->colorkey_enabled_property)
+               layer_state->colorkey_enabled = !!value;
+       else if (property == logicvc->colorkey_value_property)
+               layer_state->colorkey_value = (uint32_t)value;
+       else
+               return -ENOENT;
+
+       return 0;
+}
+
+static int logicvc_plane_atomic_get_property(struct drm_plane *drm_plane,
+                                            const struct drm_plane_state 
*state,
+                                            struct drm_property *property,
+                                            uint64_t *value)
+{
+       struct logicvc_drm *logicvc = logicvc_drm(drm_plane->dev);
+       struct logicvc_layer_state *layer_state = logicvc_layer_state(state);
+
+       if (property == logicvc->colorkey_enabled_property)
+               *value = layer_state->colorkey_enabled;
+       else if (property == logicvc->colorkey_value_property)
+               *value = layer_state->colorkey_value;
+       else
+               return -ENOENT;
+
+       return 0;
+}
+
 static const struct drm_plane_funcs logicvc_plane_funcs = {
        .update_plane           = drm_atomic_helper_update_plane,
        .disable_plane          = drm_atomic_helper_disable_plane,
        .destroy                = drm_plane_cleanup,
-       .reset                  = drm_atomic_helper_plane_reset,
-       .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-       .atomic_destroy_state   = drm_atomic_helper_plane_destroy_state,
+       .reset                  = logicvc_plane_reset,
+       .atomic_duplicate_state = logicvc_plane_atomic_duplicate_state,
+       .atomic_destroy_state   = logicvc_plane_destroy_state,
+       .atomic_set_property    = logicvc_plane_atomic_set_property,
+       .atomic_get_property    = logicvc_plane_atomic_get_property,
 };
 
 int logicvc_layer_buffer_find_setup(struct logicvc_drm *logicvc,
@@ -519,6 +627,11 @@ static int logicvc_layer_init(struct logicvc_drm *logicvc,
 
        drm_plane_create_zpos_immutable_property(&layer->drm_plane, zpos);
 
+       drm_object_attach_property(&layer->drm_plane.base,
+                                  logicvc->colorkey_enabled_property, 0);
+       drm_object_attach_property(&layer->drm_plane.base,
+                                  logicvc->colorkey_value_property, 0);
+
        DRM_DEBUG_DRIVER("Registering layer #%d\n", index);
 
        layer->formats = formats;
@@ -567,6 +680,17 @@ int logicvc_layers_init(struct logicvc_drm *logicvc)
        struct logicvc_layer *next;
        int ret = 0;
 
+       logicvc->colorkey_enabled_property =
+               drm_property_create_bool(drm_dev, 0, "colorkey_enabled");
+       if (!logicvc->colorkey_enabled_property)
+               goto error;
+
+       logicvc->colorkey_value_property =
+               drm_property_create_range(drm_dev, 0, "colorkey_value",
+                                         0, 0xffffffff);
+       if (!logicvc->colorkey_value_property)
+               goto error;
+
        layers_node = of_get_child_by_name(of_node, "layers");
        if (!layers_node) {
                DRM_ERROR("No layers node found in the description\n");
@@ -605,5 +729,16 @@ int logicvc_layers_init(struct logicvc_drm *logicvc)
        list_for_each_entry_safe(layer, next, &logicvc->layers_list, list)
                logicvc_layer_fini(logicvc, layer);
 
+       if (logicvc->colorkey_value_property) {
+               drm_property_destroy(drm_dev, logicvc->colorkey_value_property);
+               logicvc->colorkey_value_property = NULL;
+       }
+
+       if (logicvc->colorkey_enabled_property) {
+               drm_property_destroy(drm_dev,
+                                    logicvc->colorkey_enabled_property);
+               logicvc->colorkey_enabled_property = NULL;
+       }
+
        return ret;
 }
diff --git a/drivers/gpu/drm/logicvc/logicvc_layer.h 
b/drivers/gpu/drm/logicvc/logicvc_layer.h
index c5767c81f446..69bb208ad79c 100644
--- a/drivers/gpu/drm/logicvc/logicvc_layer.h
+++ b/drivers/gpu/drm/logicvc/logicvc_layer.h
@@ -39,6 +39,13 @@ struct logicvc_layer_formats {
        uint32_t *formats;
 };
 
+struct logicvc_layer_state {
+       struct drm_plane_state drm_plane_state;
+
+       bool colorkey_enabled;
+       uint32_t colorkey_value;
+};
+
 struct logicvc_layer {
        struct logicvc_layer_config config;
        struct logicvc_layer_formats *formats;
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to