]> git.hungrycats.org Git - linux/commitdiff
drm/amd/display: use GAMCOR for degamma private props in subsampled format
authorMelissa Wen <mwen@igalia.com>
Tue, 23 Jun 2026 15:58:57 +0000 (17:58 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jul 2026 15:20:58 +0000 (11:20 -0400)
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 <harry.wentland@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Tested-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c

index 9bcb73c95fef045ffd4a7ae86ea8a03fbf1ca90e..357c7c5c85cffbd22a6fd044a8cbe0d009e30cda 100644 (file)
@@ -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;
 }