[PATCH v4 12/32] drm/amd/display: add CRTC gamma TF driver-specific property
Harry Wentland
harry.wentland at amd.com
Wed Nov 15 18:27:32 UTC 2023
On 2023-10-05 13:15, Melissa Wen wrote:
> Add AMD pre-defined transfer function property to default DRM CRTC gamma
> to convert to wire encoding with or without a user gamma LUT. There is
> no post-blending regamma ROM for pre-defined TF. When setting Gamma TF
> (!= Identity) and LUT at the same time, the color module will combine
> the pre-defined TF and the custom LUT values into the LUT that's
> actually programmed.
>
> v2:
> - enable CRTC prop in the end of driver-specific prop sequence
> - define inverse EOTFs as supported regamma TFs
> - reword driver-specific function doc to remove shaper/3D LUT
>
> v3:
> - spell out TF+LUT behavior in the commit and comments (Harry)
>
> Co-developed-by: Joshua Ashton <joshua at froggi.es>
> Signed-off-by: Joshua Ashton <joshua at froggi.es>
> Signed-off-by: Melissa Wen <mwen at igalia.com>
Reviewed-by: Harry Wentland <harry.wentland at amd.com>
Harry
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 7 ++
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 8 +++
> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 7 ++
> .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 72 +++++++++++++++++++
> 4 files changed, 94 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index dee35d208493..071cc10bfd90 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -424,6 +424,13 @@ struct amdgpu_mode_info {
> * from a combination of pre-defined TF and the custom 1D LUT).
> */
> struct drm_property *plane_blend_tf_property;
> + /* @regamma_tf_property: Transfer function for CRTC regamma
> + * (post-blending). Possible values are defined by `enum
> + * amdgpu_transfer_function`. There is no regamma ROM, but we can use
> + * AMD color modules to program LUT parameters from predefined TF (or
> + * from a combination of pre-defined TF and the custom 1D LUT).
> + */
> + struct drm_property *regamma_tf_property;
> };
>
> #define AMDGPU_MAX_BL_LEVEL 0xFF
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index 1b96c742d747..c138457ff12e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -836,6 +836,14 @@ struct dm_crtc_state {
> struct dc_info_packet vrr_infopacket;
>
> int abm_level;
> +
> + /**
> + * @regamma_tf:
> + *
> + * Pre-defined transfer function for converting internal FB -> wire
> + * encoding.
> + */
> + enum amdgpu_transfer_function regamma_tf;
> };
>
> #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> 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 82c554662faa..2ecfa0e886e8 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
> @@ -294,6 +294,13 @@ amdgpu_dm_create_color_properties(struct amdgpu_device *adev)
> return -ENOMEM;
> adev->mode_info.plane_blend_tf_property = prop;
>
> + prop = amdgpu_create_tf_property(adev_to_drm(adev),
> + "AMD_CRTC_REGAMMA_TF",
> + amdgpu_inv_eotf);
> + if (!prop)
> + return -ENOMEM;
> + adev->mode_info.regamma_tf_property = prop;
> +
> return 0;
> }
> #endif
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index 440fc0869a34..d746f0aa0f11 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -253,6 +253,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> state->freesync_config = cur->freesync_config;
> state->cm_has_degamma = cur->cm_has_degamma;
> state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb;
> + state->regamma_tf = cur->regamma_tf;
> state->crc_skip_count = cur->crc_skip_count;
> state->mpo_requested = cur->mpo_requested;
> /* TODO Duplicate dc_stream after objects are stream object is flattened */
> @@ -289,6 +290,70 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
> }
> #endif
>
> +#ifdef AMD_PRIVATE_COLOR
> +/**
> + * drm_crtc_additional_color_mgmt - enable additional color properties
> + * @crtc: DRM CRTC
> + *
> + * This function lets the driver enable post-blending CRTC regamma transfer
> + * function property in addition to DRM CRTC gamma LUT. Default value means
> + * linear transfer function, which is the default CRTC gamma LUT behaviour
> + * without this property.
> + */
> +static void
> +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> +{
> + struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +
> + if(adev->dm.dc->caps.color.mpc.ogam_ram)
> + drm_object_attach_property(&crtc->base,
> + adev->mode_info.regamma_tf_property,
> + AMDGPU_TRANSFER_FUNCTION_DEFAULT);
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> + struct drm_crtc_state *state,
> + struct drm_property *property,
> + uint64_t val)
> +{
> + struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> + struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +
> + if (property == adev->mode_info.regamma_tf_property) {
> + if (acrtc_state->regamma_tf != val) {
> + acrtc_state->regamma_tf = val;
> + acrtc_state->base.color_mgmt_changed |= 1;
> + }
> + } else {
> + drm_dbg_atomic(crtc->dev,
> + "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> + crtc->base.id, crtc->name,
> + property->base.id, property->name);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> + const struct drm_crtc_state *state,
> + struct drm_property *property,
> + uint64_t *val)
> +{
> + struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> + struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +
> + if (property == adev->mode_info.regamma_tf_property)
> + *val = acrtc_state->regamma_tf;
> + else
> + return -EINVAL;
> +
> + return 0;
> +}
> +#endif
> +
> /* Implemented only the options currently available for the driver */
> static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> .reset = dm_crtc_reset_state,
> @@ -307,6 +372,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> #if defined(CONFIG_DEBUG_FS)
> .late_register = amdgpu_dm_crtc_late_register,
> #endif
> +#ifdef AMD_PRIVATE_COLOR
> + .atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> + .atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> +#endif
> };
>
> static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> @@ -470,6 +539,9 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
>
> drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
>
> +#ifdef AMD_PRIVATE_COLOR
> + dm_crtc_additional_color_mgmt(&acrtc->base);
> +#endif
> return 0;
>
> fail:
More information about the amd-gfx
mailing list