Add Regamma LUT operation as 1D LUT colorop to AMD post-blend color
pipeline.

Signed-off-by: Melissa Wen <[email protected]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 38 ++++++++++++++++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 18 +++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 141c5238021e..67a9ec48836d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -1234,6 +1234,8 @@ __set_dm_crtc_colorop_regamma(struct drm_crtc_state 
*crtc_state,
        struct drm_atomic_commit *state = crtc_state->state;
        enum dc_transfer_func_predefined default_tf = TRANSFER_FUNCTION_LINEAR;
        struct drm_device *dev = crtc_state->state->dev;
+       const struct drm_color_lut32 *regamma_lut;
+       u32 regamma_size;
        int ret = 0;
 
        tf->type = TF_TYPE_BYPASS;
@@ -1251,6 +1253,34 @@ __set_dm_crtc_colorop_regamma(struct drm_crtc_state 
*crtc_state,
                        return ret;
        }
 
+       /* 1D LUT - Regamma LUT */
+       colorop = colorop->next;
+       if (!colorop) {
+               drm_dbg(dev, "no Regamma LUT colorop found\n");
+               return -EINVAL;
+       }
+
+       colorop_state = drm_atomic_get_new_colorop_state(state, colorop);
+
+       if (colorop_state && !colorop_state->bypass && colorop->type == 
DRM_COLOROP_1D_LUT) {
+               drm_dbg(dev, "Regamma LUT colorop with ID: %d\n", 
colorop->base.id);
+               tf->type = TF_TYPE_DISTRIBUTED_POINTS;
+               tf->tf = default_tf;
+               tf->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE;
+               regamma_lut = __extract_blob_lut32(colorop_state->data, 
&regamma_size);
+               regamma_size = regamma_lut != NULL ? regamma_size : 0;
+
+               /* Custom LUT size must be the same as supported size */
+               if (regamma_size == colorop->size) {
+                       ret = __set_output_tf_32(tf, regamma_lut, regamma_size, 
false);
+                       if (ret)
+                               return ret;
+               } else {
+                       drm_dbg(dev, "Regamma LUT size doesn't match blob 
size\n");
+                       return -EINVAL;
+               }
+       }
+
        return 0;
 }
 
@@ -1300,7 +1330,7 @@ amdgpu_dm_crtc_set_colorop_properties(struct 
drm_crtc_state *crtc_state,
                }
        }
 
-       /* 1D Curve - REGAMMA TF */
+       /* 1D Curve & LUT - REGAMMA TF & LUT */
        colorop = colorop->next;
        if (!colorop) {
                drm_dbg(dev, "no regamma TF colorop found\n");
@@ -1312,6 +1342,11 @@ amdgpu_dm_crtc_set_colorop_properties(struct 
drm_crtc_state *crtc_state,
        if (ret)
                goto cleanup;
 
+       /* REGAMMA LUT colorop is already handled, just skip here */
+       colorop = colorop->next;
+       if (!colorop)
+               ret = -EINVAL;
+
 cleanup:
        if (check_only)
                kvfree(out_tf);
@@ -1339,7 +1374,6 @@ amdgpu_dm_crtc_set_colorop_properties(struct 
drm_crtc_state *crtc_state,
  * Returns:
  * 0 on success. Error code if validation fails.
  */
-
 int amdgpu_dm_check_crtc_color_mgmt(struct dm_crtc_state *crtc,
                                    bool check_only)
 {
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 4c1204c683c4..2db17f2562ce 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
@@ -297,6 +297,24 @@ int amdgpu_dm_initialize_crtc_default_pipeline(struct 
drm_crtc *crtc,
                drm_colorop_set_next_property(ops[i-1], ops[i]);
 
                i++;
+
+               /* 1D LUT - REGAMMA LUT */
+               ops[i] = kzalloc_obj(*ops[0]);
+               if (!ops[i]) {
+                       ret = -ENOMEM;
+                       goto cleanup;
+               }
+
+               ret = drm_crtc_colorop_curve_1d_lut_init(dev, ops[i], crtc, 
&dm_colorop_funcs,
+                                                        MAX_COLOR_LUT_ENTRIES,
+                                                        
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
+                                                        
DRM_COLOROP_FLAG_ALLOW_BYPASS);
+               if (ret)
+                       goto cleanup;
+
+               drm_colorop_set_next_property(ops[i-1], ops[i]);
+
+               i++;
        }
 
        list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", 
ops[0]->base.id);
-- 
2.53.0

Reply via email to