Insert a CSC Fixed-Function colorop as the first operation in the
amdgpu color pipeline, before the existing DEGAM 1D curve. This
allows userspace to select YUV-to-RGB conversion via the color
pipeline for YCbCr framebuffers.

The CSC FF colorop advertises support for all six YUV-to-RGB
conversion presets:
  - YUV601/709/2020 full-range to RGB
  - YUV601/709/2020 limited-range to RGB

Assisted-by Claude:claude-opus-4.6

Signed-off-by: Harry Wentland <[email protected]>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 27 ++++++++++++++++++-
 .../amd/display/amdgpu_dm/amdgpu_dm_colorop.h |  1 +
 2 files changed, 27 insertions(+), 1 deletion(-)

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 3e05e48a8792..13521095e021 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
@@ -51,6 +51,14 @@ const u64 amdgpu_dm_supported_blnd_tfs =
        BIT(DRM_COLOROP_1D_CURVE_BT2020_INV_OETF) |
        BIT(DRM_COLOROP_1D_CURVE_GAMMA22_INV);
 
+const u64 amdgpu_dm_supported_csc_ff =
+       BIT(DRM_COLOROP_CSC_FF_YUV601_RGB601) |
+       BIT(DRM_COLOROP_CSC_FF_YUV601_LIMITED_RGB601) |
+       BIT(DRM_COLOROP_CSC_FF_YUV709_RGB709) |
+       BIT(DRM_COLOROP_CSC_FF_YUV709_LIMITED_RGB709) |
+       BIT(DRM_COLOROP_CSC_FF_YUV2020_RGB2020) |
+       BIT(DRM_COLOROP_CSC_FF_YUV2020_LIMITED_RGB2020);
+
 #define MAX_COLOR_PIPELINE_OPS 10
 
 #define LUT3D_SIZE             17
@@ -70,6 +78,23 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane 
*plane, struct drm_pr
 
        memset(ops, 0, sizeof(ops));
 
+       /* CSC Fixed-Function (YUV to RGB) */
+       ops[i] = kzalloc_obj(*ops[0]);
+       if (!ops[i]) {
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       ret = drm_plane_colorop_csc_ff_init(dev, ops[i], plane, 
&dm_colorop_funcs,
+                                           amdgpu_dm_supported_csc_ff,
+                                           DRM_COLOROP_FLAG_ALLOW_BYPASS);
+       if (ret)
+               goto cleanup;
+
+       list->type = ops[i]->base.id;
+
+       i++;
+
        /* 1D curve - DEGAM TF */
        ops[i] = kzalloc_obj(*ops[0]);
        if (!ops[i]) {
@@ -83,7 +108,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane 
*plane, struct drm_pr
        if (ret)
                goto cleanup;
 
-       list->type = ops[i]->base.id;
+       drm_colorop_set_next_property(ops[i - 1], ops[i]);
 
        i++;
 
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
index 2e1617ffc8ee..e509646b5567 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.h
@@ -30,6 +30,7 @@
 extern const u64 amdgpu_dm_supported_degam_tfs;
 extern const u64 amdgpu_dm_supported_shaper_tfs;
 extern const u64 amdgpu_dm_supported_blnd_tfs;
+extern const u64 amdgpu_dm_supported_csc_ff;
 
 int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct 
drm_prop_enum_list *list);
 
-- 
2.53.0

Reply via email to