We want to make sure userspace is aware of the 1D LUT
interpolation. While linear interpolation is common it
might not be supported on all HW. Give driver implementers
a way to specify their interpolation.

Signed-off-by: Harry Wentland <harry.wentl...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c |  6 ++--
 drivers/gpu/drm/drm_atomic.c                  |  1 +
 drivers/gpu/drm/drm_colorop.c                 | 36 ++++++++++++++++++-
 include/drm/drm_colorop.h                     | 19 +++++++++-
 include/uapi/drm/drm_mode.h                   | 13 +++++++
 5 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
index 8a86849e1529..c85e344eaccb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
@@ -121,7 +121,8 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane 
*plane, struct drm_pr
                return -ENOMEM;
        }
 
-       ret = drm_colorop_curve_1d_lut_init(dev, op, plane, 
MAX_COLOR_LUT_ENTRIES);
+       ret = drm_colorop_curve_1d_lut_init(dev, op, plane, 
MAX_COLOR_LUT_ENTRIES,
+                                           
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR);
        if (ret)
                return ret;
 
@@ -151,7 +152,8 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane 
*plane, struct drm_pr
                return -ENOMEM;
        }
 
-       ret = drm_colorop_curve_1d_lut_init(dev, op, plane, 
MAX_COLOR_LUT_ENTRIES);
+       ret = drm_colorop_curve_1d_lut_init(dev, op, plane, 
MAX_COLOR_LUT_ENTRIES,
+                                           
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR);
        if (ret)
                return ret;
 
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 2ab797e9d946..dbb8776ae433 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -798,6 +798,7 @@ static void drm_atomic_colorop_print_state(struct 
drm_printer *p,
                break;
        case DRM_COLOROP_1D_LUT:
                drm_printf(p, "\tsize=%d\n", state->size);
+               drm_printf(p, "\tinterpolation=%s\n", 
drm_get_colorop_lut1d_interpolation_name(colorop->lut1d_interpolation));
                drm_printf(p, "\tdata blob id=%d\n", state->data ? 
state->data->base.id : 0);
                break;
        case DRM_COLOROP_CTM_3X4:
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 9634effab73a..47a9877099c3 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -77,6 +77,9 @@ static const char * const colorop_curve_1d_type_names[] = {
        [DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF] = "PQ 125 Inverse EOTF",
 };
 
+static const struct drm_prop_enum_list drm_colorop_lut1d_interpolation_list[] 
= {
+       { DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" },
+};
 
 /* Init Helpers */
 
@@ -233,10 +236,12 @@ static int drm_colorop_create_data_prop(struct drm_device 
*dev, struct drm_color
  * @colorop: The drm_colorop object to initialize
  * @plane: The associated drm_plane
  * @lut_size: LUT size supported by driver
+ * @lut1d_interpolation: 1D LUT interpolation type
  * @return zero on success, -E value on failure
  */
 int drm_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop 
*colorop,
-                                 struct drm_plane *plane, uint32_t lut_size)
+                                 struct drm_plane *plane, uint32_t lut_size,
+                                 enum drm_colorop_lut1d_interpolation_type 
lut1d_interpolation)
 {
        struct drm_property *prop;
        int ret;
@@ -255,6 +260,17 @@ int drm_colorop_curve_1d_lut_init(struct drm_device *dev, 
struct drm_colorop *co
        colorop->size_property = prop;
        drm_object_attach_property(&colorop->base, colorop->size_property, 
lut_size);
 
+       /* Interpolation */
+       prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, 
"LUT1D_INTERPOLATION",
+                                       drm_colorop_lut1d_interpolation_list,
+                                       
ARRAY_SIZE(drm_colorop_lut1d_interpolation_list));
+       if (!prop)
+               return -ENOMEM;
+
+       colorop->lut1d_interpolation_property = prop;
+       drm_object_attach_property(&colorop->base, prop, lut1d_interpolation);
+       colorop->lut1d_interpolation = lut1d_interpolation;
+
        /* data */
        ret = drm_colorop_create_data_prop(dev, colorop);
        if (ret)
@@ -407,6 +423,9 @@ static const char * const colorop_type_name[] = {
        [DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
        [DRM_COLOROP_MULTIPLIER] = "Multiplier",
 };
+static const char * const colorop_lut1d_interpolation_name[] = {
+       [DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR] = "Linear",
+};
 
 const char *drm_get_colorop_type_name(enum drm_colorop_type type)
 {
@@ -424,6 +443,21 @@ const char *drm_get_colorop_curve_1d_type_name(enum 
drm_colorop_curve_1d_type ty
        return colorop_curve_1d_type_names[type];
 }
 
+/**
+ * drm_get_colorop_lut1d_interpolation_name: return a string for interpolation 
type
+ * @type: interpolation type to compute name of
+ *
+ * In contrast to the other drm_get_*_name functions this one here returns a
+ * const pointer and hence is threadsafe.
+ */
+const char *drm_get_colorop_lut1d_interpolation_name(enum 
drm_colorop_lut1d_interpolation_type type)
+{
+       if (WARN_ON(type >= ARRAY_SIZE(colorop_lut1d_interpolation_name)))
+               return "unknown";
+
+       return colorop_lut1d_interpolation_name[type];
+}
+
 /**
  * drm_colorop_set_next_property - sets the next pointer
  * @colorop: drm colorop
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index 09e96b9a8eff..1304b19c96b5 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -238,6 +238,21 @@ struct drm_colorop {
         */
        struct drm_property *bypass_property;
 
+       /**
+        * @lut1d_interpolation:
+        *
+        * Read-only
+        * Interpolation for DRM_COLOROP_1D_LUT
+        */
+       enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
+
+       /**
+        * @lut1d_interpolation_property:
+        *
+        * Read-only property for DRM_COLOROP_1D_LUT interpolation
+        */
+       struct drm_property *lut1d_interpolation_property;
+
        /**
         * @curve_1d_type_property:
         *
@@ -306,7 +321,8 @@ static inline struct drm_colorop *drm_colorop_find(struct 
drm_device *dev,
 int drm_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop 
*colorop,
                              struct drm_plane *plane, u64 supported_tfs);
 int drm_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop 
*colorop,
-                                 struct drm_plane *plane, uint32_t lut_size);
+                                 struct drm_plane *plane, uint32_t lut_size,
+                                 enum drm_colorop_lut1d_interpolation_type 
lut1d_interpolation);
 int drm_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop 
*colorop,
                             struct drm_plane *plane);
 int drm_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop,
@@ -360,6 +376,7 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type 
type);
  * const pointer and hence is threadsafe.
  */
 const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type 
type);
+const char *drm_get_colorop_lut1d_interpolation_name(enum 
drm_colorop_lut1d_interpolation_type type);
 
 void drm_colorop_set_next_property(struct drm_colorop *colorop, struct 
drm_colorop *next);
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8e9886200f4d..b64f9515bd0a 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -916,6 +916,19 @@ enum drm_colorop_type {
        DRM_COLOROP_MULTIPLIER,
 };
 
+/**
+ * enum drm_colorop_lut1d_interpolation_type - type of interpolation for 1D 
LUTs
+ */
+enum drm_colorop_lut1d_interpolation_type {
+       /**
+        * @DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR:
+        *
+        * Linear interpolation. Values between points of the LUT will be
+        * linearly interpolated.
+        */
+       DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
+};
+
 /**
  * struct drm_plane_size_hint - Plane size hints
  *
-- 
2.46.0

Reply via email to