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, ®amma_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
