On 02/26, Harry Wentland wrote: > From: Alex Hung <alex.hung@xxxxxxx> > > Expose one 1D curve colorop with support for > DRM_COLOROP_1D_CURVE_SRGB_EOTF and program HW to perform > the sRGB transform when the colorop is not in bypass. > > With this change the following IGT test passes: > kms_colorop --run plane-XR30-XR30-srgb_eotf > > The color pipeline now consists of a single colorop: > 1. 1D curve colorop w/ sRGB EOTF > > Signed-off-by: Alex Hung <alex.hung@xxxxxxx> > Signed-off-by: Harry Wentland <harry.wentland@xxxxxxx> > Co-developed-by: Harry Wentland <harry.wentland@xxxxxxx> > --- > .../gpu/drm/amd/display/amdgpu_dm/Makefile | 3 +- > .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 88 +++++++++++++++++++ > .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 58 ++++++++++++ > .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h | 34 +++++++ > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 10 +++ > 5 files changed, 192 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c > create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile > index ab2a97e354da..46158d67ab12 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile > @@ -38,7 +38,8 @@ AMDGPUDM = \ > amdgpu_dm_pp_smu.o \ > amdgpu_dm_psr.o \ > amdgpu_dm_replay.o \ > - amdgpu_dm_wb.o > + amdgpu_dm_wb.o \ > + amdgpu_dm_colorop.o > > ifdef CONFIG_DRM_AMD_DC_FP > AMDGPUDM += dc_fpu.o > 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 9b527bffe11a..3ec759934669 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 > @@ -668,6 +668,19 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf) > } > } > > +static enum dc_transfer_func_predefined > +amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf) > +{ > + switch (tf) > + { > + case DRM_COLOROP_1D_CURVE_SRGB_EOTF: > + case DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF: > + return TRANSFER_FUNCTION_SRGB; > + default: > + return TRANSFER_FUNCTION_LINEAR;; > + } > +} > + > static void __to_dc_lut3d_color(struct dc_rgb *rgb, > const struct drm_color_lut lut, > int bit_precision) > @@ -1137,6 +1150,59 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, > return 0; > } > > +static int > +__set_colorop_in_tf_1d_curve(struct dc_plane_state *dc_plane_state, > + struct drm_colorop_state *colorop_state) > +{ > + struct dc_transfer_func *tf = dc_plane_state->in_transfer_func; For this patch and the next two, it ^ should be: `&dc_plane_state->in_transfer_func` (same for shape and blend), right? > + struct drm_colorop *colorop = colorop_state->colorop; > + struct drm_device *drm = colorop->dev; > + > + if (colorop->type != DRM_COLOROP_1D_CURVE && > + colorop_state->curve_1d_type != DRM_COLOROP_1D_CURVE_SRGB_EOTF) > + return -EINVAL; > + > + if (colorop_state->bypass) { > + tf->type = TF_TYPE_BYPASS; > + tf->tf = TRANSFER_FUNCTION_LINEAR; > + return 0; > + } > + > + drm_dbg(drm, "Degamma colorop with ID: %d\n", colorop->base.id); > + > + tf->type = TF_TYPE_PREDEFINED; > + tf->tf = amdgpu_colorop_tf_to_dc_tf(colorop_state->curve_1d_type); > + > + return 0; > +} > + > +static int > +__set_dm_plane_colorop_degamma(struct drm_plane_state *plane_state, > + struct dc_plane_state *dc_plane_state, > + struct drm_colorop *colorop) > +{ > + struct drm_colorop *old_colorop; > + struct drm_colorop_state *colorop_state = NULL, *new_colorop_state; > + struct drm_atomic_state *state = plane_state->state; > + int i = 0; > + > + old_colorop = colorop; > + > + /* 1st op: 1d curve - degamma */ > + for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) { > + if (new_colorop_state->colorop == old_colorop && > + new_colorop_state->curve_1d_type == DRM_COLOROP_1D_CURVE_SRGB_EOTF) { > + colorop_state = new_colorop_state; > + break; > + } > + } > + > + if (!colorop_state) > + return -EINVAL; > + > + return __set_colorop_in_tf_1d_curve(dc_plane_state, colorop_state); > +} > + > static int > amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, > struct dc_plane_state *dc_plane_state) > @@ -1187,6 +1253,25 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, > return 0; > } > > +static int > +amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, > + struct dc_plane_state *dc_plane_state) > +{ > + struct drm_colorop *colorop = plane_state->color_pipeline; > + int ret; > + > + /* 1D Curve - DEGAM TF */ > + if (!colorop) { > + return -EINVAL; > + } > + > + ret = __set_dm_plane_colorop_degamma(plane_state, dc_plane_state, colorop); > + if (ret) > + return ret; > + > + return 0; > +} > + > /** > * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. > * @crtc: amdgpu_dm crtc state > @@ -1283,5 +1368,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, > dc_plane_state->input_csc_color_matrix.enable_adjustment = false; > } > > + if (!amdgpu_dm_plane_set_colorop_properties(plane_state, dc_plane_state)) > + return 0; > + > return amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state); > } > 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 > new file mode 100644 > index 000000000000..e8b7fc8bb0f1 > --- /dev/null > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c > @@ -0,0 +1,58 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright 2023 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: AMD > + * > + */ > + > +#include <drm/drm_print.h> > +#include <drm/drm_plane.h> > +#include <drm/drm_property.h> > +#include <drm/drm_colorop.h> > + > +#include "amdgpu_dm_colorop.h" > + > +const u64 amdgpu_dm_supported_degam_tfs = > + BIT(DRM_COLOROP_1D_CURVE_SRGB_EOTF); > + > +int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list) > +{ > + struct drm_colorop *op; > + struct drm_device *dev = plane->dev; > + int ret; > + > + /* 1D curve - DEGAM TF */ > + op = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); > + if (!op) { > + DRM_ERROR("KMS: Failed to allocate colorop\n"); > + return -ENOMEM; > + } > + > + ret = drm_colorop_curve_1d_init(dev, op, plane, amdgpu_dm_supported_degam_tfs); > + if (ret) > + return ret; > + > + list->type = op->base.id; > + list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", op->base.id); > + > + return 0; > +} > \ No newline at end of file > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h > new file mode 100644 > index 000000000000..f16de6a9fbde > --- /dev/null > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h > @@ -0,0 +1,34 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright 2023 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: AMD > + * > + */ > + > +#ifndef __AMDGPU_DM_COLOROP_H__ > +#define __AMDGPU_DM_COLOROP_H__ > + > +extern const u64 amdgpu_dm_supported_degam_tfs; > + > +int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list); > + > +#endif /* __AMDGPU_DM_COLOROP_H__*/ > \ No newline at end of file > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > index d3f64f586243..3adab18332d8 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c > @@ -35,6 +35,7 @@ > #include "amdgpu_display.h" > #include "amdgpu_dm_trace.h" > #include "amdgpu_dm_plane.h" > +#include "amdgpu_dm_colorop.h" > #include "gc/gc_11_0_0_offset.h" > #include "gc/gc_11_0_0_sh_mask.h" > > @@ -1658,10 +1659,19 @@ dm_plane_init_colorops(struct drm_plane *plane) > { > struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES]; > int len = 0; > + int ret; > > if (plane->type == DRM_PLANE_TYPE_CURSOR) > return 0; > > + /* initialize default pipeline */ > + ret = amdgpu_dm_initialize_default_pipeline(plane, &(pipelines[len])); > + if (ret) { > + DRM_ERROR("Failed to create color pipeline for plane %d: %d\n", plane->base.id, ret); > + return ret; > + } > + len++; > + > /* Create COLOR_PIPELINE property and attach */ > drm_plane_create_color_pipeline_property(plane, pipelines, len); > > -- > 2.44.0 >