Add plane lut_3d mode and lut_3d as blob properties.

lut_3d mode is an enum property with values as blob_ids.
Userspace can get supported modes and also set one of the modes.

Note: A patchset "IGT tests for pre-blending 3D LUT interfaces" for this
proposal is sent to IGT mailing list.

Signed-off-by: Alex Hung <alex.h...@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 ++
 drivers/gpu/drm/drm_atomic_state_helper.c     |  3 ++
 drivers/gpu/drm/drm_atomic_uapi.c             | 11 ++++++
 drivers/gpu/drm/drm_color_mgmt.c              | 37 +++++++++++++++++++
 include/drm/drm_mode_object.h                 |  2 +-
 include/drm/drm_plane.h                       | 31 ++++++++++++++++
 6 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f546c1326db3..ee277f357140 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8006,6 +8006,10 @@ static int amdgpu_dm_plane_init(struct 
amdgpu_display_manager *dm,
        drm_plane_attach_gamma_properties(plane);
        drm_plane_attach_ctm_property(plane);
 
+       /* TODO need to check ASICs */
+       drm_plane_create_3d_lut_properties(plane->dev, plane, 1);
+       drm_plane_attach_3dlut_properties(plane);
+
        /* Create (reset) the plane state */
        if (plane->funcs->reset)
                plane->funcs->reset(plane);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7ddf6e4b956b..85900cd1bffe 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -318,6 +318,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
drm_plane *plane,
                drm_property_blob_get(state->ctm);
        if (state->gamma_lut)
                drm_property_blob_get(state->gamma_lut);
+       if (state->lut_3d)
+               drm_property_blob_get(state->lut_3d);
 
        state->color_mgmt_changed = false;
 }
@@ -369,6 +371,7 @@ void __drm_atomic_helper_plane_destroy_state(struct 
drm_plane_state *state)
        drm_property_blob_put(state->degamma_lut);
        drm_property_blob_put(state->ctm);
        drm_property_blob_put(state->gamma_lut);
+       drm_property_blob_put(state->lut_3d);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index ba3e64cb184a..66e59e7c194d 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -622,6 +622,13 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
                                        &replaced);
                state->color_mgmt_changed |= replaced;
                return ret;
+       } else if (property == plane->lut_3d_property) {
+               ret = drm_atomic_replace_property_blob_from_id(dev,
+                                       &state->lut_3d, val, -1, 8, &replaced);
+               state->color_mgmt_changed |= replaced;
+               return 0;
+       } else if (property == plane->lut_3d_mode_property) {
+               state->lut_3d_mode = val;
        } else if (property == config->prop_fb_damage_clips) {
                ret = drm_atomic_replace_property_blob_from_id(dev,
                                        &state->fb_damage_clips,
@@ -700,6 +707,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
        } else if (property == plane->gamma_lut_property) {
                *val = (state->gamma_lut) ?
                        state->gamma_lut->base.id : 0;
+       } else if (property == plane->lut_3d_property) {
+               *val = (state->lut_3d) ? state->lut_3d->base.id : 0;
+       } else if (property == plane->lut_3d_mode_property) {
+               *val = state->lut_3d_mode;
        } else if (property == config->prop_fb_damage_clips) {
                *val = (state->fb_damage_clips) ?
                        state->fb_damage_clips->base.id : 0;
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index b5b3ff7f654d..4bfe5b5c9670 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -706,6 +706,43 @@ void drm_plane_attach_gamma_properties(struct drm_plane 
*plane)
 }
 EXPORT_SYMBOL(drm_plane_attach_gamma_properties);
 
+int drm_plane_create_3d_lut_properties(struct drm_device *dev,
+                                          struct drm_plane *plane,
+                                          int num_values)
+{
+       struct drm_property *mode;
+       struct drm_property *blob;
+
+       mode = drm_property_create(dev, DRM_MODE_PROP_ENUM, 
"PLANE_3D_LUT_MODE", num_values);
+       if (!mode)
+               return -ENOMEM;
+
+       plane->lut_3d_mode_property = mode;
+
+       blob = drm_property_create(dev, DRM_MODE_PROP_BLOB, "PLANE_3D_LUT", 0);
+       if (!blob)
+               return -ENOMEM;
+
+       plane->lut_3d_property = blob;
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_3d_lut_properties);
+
+void drm_plane_attach_3dlut_properties(struct drm_plane *plane)
+{
+       if (!plane->lut_3d_property)
+               return;
+
+       drm_object_attach_property(&plane->base, plane->lut_3d_property, 0);
+
+       if (!plane->lut_3d_mode_property)
+               return;
+
+       drm_object_attach_property(&plane->base, plane->lut_3d_mode_property, 
0);
+}
+EXPORT_SYMBOL(drm_plane_attach_3dlut_properties);
+
 int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane,
                                                 const char *name,
                                                 const struct 
drm_color_lut_range *ranges,
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index d4128c7daa08..c2b31dbf7325 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
        void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 26
+#define DRM_OBJECT_MAX_PROPERTY 28
 /**
  * struct drm_object_properties - property tracking for &drm_mode_object
  */
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 8989bb1aa46c..4e272144170f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -275,6 +275,21 @@ struct drm_plane_state {
         */
        struct drm_property_blob *gamma_lut;
 
+       /**
+        * @lut_3d_mode:
+        * This is a blob_id and exposes the platform capabilities wrt
+        * various 3dlut. This also helps user select a 3dlut mode amongst
+        * the supported ones.
+        */
+       u32 lut_3d_mode;
+
+       /**
+        * @lut_3d:
+        * 3D lookup table blob. The blob data is laid out as defined by the
+        * FOURCC value in color_format in the drm_mode_3dlut_mode struct.
+        */
+       struct drm_property_blob *lut_3d;
+
        u8 color_mgmt_changed : 1;
 };
 
@@ -818,6 +833,18 @@ struct drm_plane {
         * used to convert the framebuffer's colors to non-linear gamma.
         */
        struct drm_property *gamma_lut_property;
+
+       /**
+        * @lut_3d_mode_property: Optional Plane property to set the 3DLUT mode
+        * used to convert the framebuffer's colors to non-linear gamma.
+        */
+       struct drm_property *lut_3d_mode_property;
+
+       /**
+        * @lut_3d_property: Optional Plane property to set the 3DLUT
+        * used to convert the framebuffer's colors to non-linear gamma.
+        */
+       struct drm_property *lut_3d_property;
 };
 
 #define obj_to_plane(x) container_of(x, struct drm_plane, base)
@@ -915,6 +942,10 @@ int drm_plane_create_color_mgmt_properties(struct 
drm_device *dev,
 void drm_plane_attach_degamma_properties(struct drm_plane *plane);
 void drm_plane_attach_ctm_property(struct drm_plane *plane);
 void drm_plane_attach_gamma_properties(struct drm_plane *plane);
+int drm_plane_create_3d_lut_properties(struct drm_device *dev,
+                                          struct drm_plane *plane,
+                                          int num_values);
+void drm_plane_attach_3dlut_properties(struct drm_plane *plane);
 int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane,
                                                 const char *name,
                                                 const struct 
drm_color_lut_range *ranges,
-- 
2.37.3

Reply via email to