From 0a06bc174f07753526a680a541515eb2391cdbca Mon Sep 17 00:00:00 2001 From: Melissa Wen Date: Tue, 23 Jun 2026 17:58:57 +0200 Subject: [PATCH] drm/amd/display: use GAMCOR for degamma private props in subsampled format When setting plane degamma TF via AMD driver-specific color properties, the driver uses PRE_DEGAM color block (ROM). However, this block cannot be used with subsampled formats as it affects the linearity of color space in which HW scaler operates. For subsampled format, use the AMD color module to map plane degamma predefined curve to LUT and use GAMCOR block instead (RAM). This is based on Harry's implementation for Fixed Matrix Colorop. Link: https://lore.kernel.org/dri-devel/20260330153451.99472-1-harry.wentland@amd.com/ Co-developed-by: Harry Wentland Signed-off-by: Harry Wentland Tested-by: Matthew Schwartz Reviewed-by: Harry Wentland Signed-off-by: Melissa Wen Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 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 9bcb73c95fef..357c7c5c85cf 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 @@ -1469,7 +1469,7 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, const struct drm_color_lut *degamma_lut; enum amdgpu_transfer_function tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; uint32_t degamma_size; - bool has_degamma_lut; + bool has_degamma_lut, is_subsampled_format; int ret; degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, @@ -1499,12 +1499,20 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, if (ret) return ret; } else { - dc_plane_state->in_transfer_func.type = - TF_TYPE_PREDEFINED; + /* Check if format requires post-scale color processing (subsampled formats) */ + is_subsampled_format = (dc_plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && + dc_plane_state->format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END); + + dc_plane_state->in_transfer_func.type = TF_TYPE_PREDEFINED; if (!mod_color_calculate_degamma_params(color_caps, - &dc_plane_state->in_transfer_func, NULL, false)) + &dc_plane_state->in_transfer_func, + NULL, + is_subsampled_format)) { + drm_err(plane_state->state->dev, + "Failed to calculate degamma params.\n"); return -ENOMEM; + } } return 0; }