* [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:22 ` sashiko-bot
2026-07-20 4:51 ` [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline Chaitanya Kumar Borah
` (12 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel
Cc: Chaitanya Kumar Borah, Melissa Wen, Harry Wentland
Introduce DRM_COLOROP_FIXED_MATRIX, a new colorop type representing a
hardware that performs a fixed matrix operation.
Unlike CTM-based colorops, this block does not expose programmable
coefficients. Instead, userspace selects one of the predefined
hardware modes via a new FIXED_MATRIX_TYPE enum property. Supported modes
include common YCbCr->RGB and RGB709->RGB2020 conversions.
v2:
- Naming changes (Pekka)
v3:
- Fix NC matrix enum name and string (Melissa)
- Rebase
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
---
drivers/gpu/drm/drm_atomic.c | 4 ++
drivers/gpu/drm/drm_atomic_uapi.c | 7 ++
drivers/gpu/drm/drm_colorop.c | 106 ++++++++++++++++++++++++++++++
include/drm/drm_colorop.h | 84 +++++++++++++++++++++++
include/uapi/drm/drm_mode.h | 12 ++++
5 files changed, 213 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index e5c8ef06caed..45df6376f408 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -925,6 +925,10 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
drm_get_colorop_lut3d_interpolation_name(state->lut3d_interpolation));
drm_printf_indent(p, 1, "data blob id=%d\n", state->data ? state->data->base.id : 0);
break;
+ case DRM_COLOROP_FIXED_MATRIX:
+ drm_printf_indent(p, 1, "fixed_matrix_type=%s\n",
+ drm_get_colorop_fixed_matrix_type_name(state->fixed_matrix_type));
+ break;
default:
break;
}
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 1050dddadb17..d52504d823bc 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -786,6 +786,11 @@ static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
return drm_atomic_color_set_data_property(colorop, state,
property, val,
replaced);
+ } else if (property == colorop->fixed_matrix_type_property) {
+ if (state->fixed_matrix_type != val) {
+ state->fixed_matrix_type = val;
+ *replaced = true;
+ }
} else {
drm_dbg_atomic(colorop->dev,
"[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
@@ -818,6 +823,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
*val = state->lut3d_interpolation;
else if (property == colorop->data_property)
*val = (state->data) ? state->data->base.id : 0;
+ else if (property == colorop->fixed_matrix_type_property)
+ *val = state->fixed_matrix_type;
else
return -EINVAL;
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 682fcc651525..483defad699c 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -68,6 +68,7 @@ static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
{ DRM_COLOROP_MULTIPLIER, "Multiplier"},
{ DRM_COLOROP_3D_LUT, "3D LUT"},
+ { DRM_COLOROP_FIXED_MATRIX, "Fixed Matrix"},
};
static const char * const colorop_curve_1d_type_names[] = {
@@ -90,6 +91,14 @@ static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[] =
{ DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
};
+static const char * const colorop_fixed_matrix_type_names[] = {
+ [DRM_COLOROP_FM_YCBCR601_FULL_RGB] = "YCbCr 601 Full to RGB",
+ [DRM_COLOROP_FM_YCBCR709_FULL_RGB] = "YCbCr 709 Full to RGB",
+ [DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB] = "YCbCr 2020 NC Full to RGB",
+ [DRM_COLOROP_FM_YCBCR_LIMITED_FULL] = "YCbCr limited to full",
+ [DRM_COLOROP_FM_RGB709_RGB2020] = "RGB709 to RGB2020",
+};
+
/* Init Helpers */
static int drm_plane_colorop_init(struct drm_device *dev, struct drm_colorop *colorop,
@@ -453,6 +462,80 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
}
EXPORT_SYMBOL(drm_plane_colorop_3dlut_init);
+/**
+ * drm_plane_colorop_fixed_matrix_init - Initialize a DRM_COLOROP_FIXED_MATRIX
+ *
+ * @dev: DRM device
+ * @colorop: The drm_colorop object to initialize
+ * @plane: The associated drm_plane
+ * @funcs: control functions for the new colorop
+ * @supported_fm: A bitfield of supported drm_colorop_fixed_matrix_type enum values,
+ * created using BIT(fixed_matrix_type) and combined with the OR '|'
+ * operator.
+ * @flags: bitmask of misc, see DRM_COLOROP_FLAG_* defines.
+ * @return zero on success, -E value on failure
+ */
+int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
+ struct drm_plane *plane,
+ const struct drm_colorop_funcs *funcs,
+ u64 supported_fm, uint32_t flags)
+{
+ struct drm_prop_enum_list enum_list[DRM_COLOROP_FM_COUNT];
+ int i, len;
+ struct drm_property *prop;
+ int ret;
+
+ if (!supported_fm) {
+ drm_err(dev,
+ "No supported FM type op for new Fixed Matrix colorop on [PLANE:%d:%s]\n",
+ plane->base.id, plane->name);
+ return -EINVAL;
+ }
+
+ if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
+ drm_err(dev, "Unknown Fixed Matrix provided on [PLANE:%d:%s]\n",
+ plane->base.id, plane->name);
+ return -EINVAL;
+ }
+
+ ret = drm_plane_colorop_init(dev, colorop, plane, funcs, DRM_COLOROP_FIXED_MATRIX, flags);
+ if (ret)
+ return ret;
+
+ len = 0;
+ for (i = 0; i < DRM_COLOROP_FM_COUNT; i++) {
+ if ((supported_fm & BIT(i)) == 0)
+ continue;
+
+ enum_list[len].type = i;
+ enum_list[len].name = colorop_fixed_matrix_type_names[i];
+ len++;
+ }
+
+ if (WARN_ON(len <= 0))
+ return -EINVAL;
+
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC, "FIXED_MATRIX_TYPE",
+ enum_list, len);
+
+ if (!prop)
+ return -ENOMEM;
+
+ colorop->fixed_matrix_type_property = prop;
+ /*
+ * Default to the first supported CSC mode as provided by the driver.
+ * Intuitively this should be something that keeps the colorop in pixel bypass
+ * mode but that is already handled via the standard colorop bypass
+ * property.
+ */
+ drm_object_attach_property(&colorop->base, colorop->fixed_matrix_type_property,
+ enum_list[0].type);
+ drm_colorop_reset(colorop);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_plane_colorop_fixed_matrix_init);
+
static void __drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop,
struct drm_colorop_state *state)
{
@@ -533,6 +616,13 @@ static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
&val))
colorop_state->lut3d_interpolation = val;
}
+
+ if (colorop->fixed_matrix_type_property) {
+ if (!drm_object_property_get_default_value(&colorop->base,
+ colorop->fixed_matrix_type_property,
+ &val))
+ colorop_state->fixed_matrix_type = val;
+ }
}
/**
@@ -596,6 +686,7 @@ static const char * const colorop_type_name[] = {
[DRM_COLOROP_CTM_3X4] = "3x4 Matrix",
[DRM_COLOROP_MULTIPLIER] = "Multiplier",
[DRM_COLOROP_3D_LUT] = "3D LUT",
+ [DRM_COLOROP_FIXED_MATRIX] = "Fixed Matrix",
};
static const char * const colorop_lu3d_interpolation_name[] = {
@@ -652,6 +743,21 @@ const char *drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_inte
return colorop_lu3d_interpolation_name[type];
}
+/**
+ * drm_get_colorop_fixed_matrix_type_name: return a string for fixed matrix type
+ * @type: fixed matrix type to compute name of
+ *
+ * In contrast to the other drm_get_*_name functions this one here returns a
+ * const pointer and hence is threadsafe.
+ */
+const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type)
+{
+ if (WARN_ON(type >= ARRAY_SIZE(colorop_fixed_matrix_type_names)))
+ return "unknown";
+
+ return colorop_fixed_matrix_type_names[type];
+}
+
/**
* drm_colorop_set_next_property - sets the next pointer
* @colorop: drm colorop
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index 224fae40ed2b..6257f6b893cd 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -134,6 +134,71 @@ enum drm_colorop_curve_1d_type {
DRM_COLOROP_1D_CURVE_COUNT
};
+/**
+ * enum drm_colorop_fixed_matrix_type - type of Fixed Matrix
+ *
+ * Describes a Fixed Matrix operation to be applied by the DRM_COLOROP_FIXED_MATRIX
+ */
+enum drm_colorop_fixed_matrix_type {
+ /**
+ * @DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+ *
+ * enum string "YCbCr 601 Full to RGB"
+ *
+ * This selects the matrix that converts full range YCbCr into RGB
+ * according to the BT.601 coefficients.
+ */
+ DRM_COLOROP_FM_YCBCR601_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+ *
+ * enum string "YCbCr 709 Full to RGB"
+ *
+ * This selects the matrix that converts full range YCbCr into RGB
+ * according to the BT.709 coefficients.
+ */
+ DRM_COLOROP_FM_YCBCR709_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+ *
+ * enum string "YCbCr 2020 NC Full to RGB"
+ *
+ * This selects the matrix that converts full range YCbCr into RGB
+ * according to the BT.2020 non-constant luminance coefficients.
+ */
+ DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB,
+
+ /**
+ * @DRM_COLOROP_FM_YCBCR_LIMITED_FULL:
+ *
+ * enum string "YCbCr limited to full"
+ *
+ * This selects the matrix that converts limited range YCbCr into
+ * full range YCbCr. Though not strictly a matrix operation but
+ * can be represented as one.
+ */
+ DRM_COLOROP_FM_YCBCR_LIMITED_FULL,
+
+ /**
+ * @DRM_COLOROP_FM_RGB709_RGB2020:
+ *
+ * enum string "RGB709 to RGB2020"
+ *
+ * Selects the fixed-function CSC preset that converts RGB
+ * (BT.709) colorimetry to RGB (BT.2020).
+ */
+ DRM_COLOROP_FM_RGB709_RGB2020,
+
+ /**
+ * @DRM_COLOROP_FM_COUNT:
+ *
+ * enum value denoting the size of the enum
+ */
+ DRM_COLOROP_FM_COUNT
+};
+
/**
* struct drm_colorop_state - mutable colorop state
*/
@@ -197,6 +262,13 @@ struct drm_colorop_state {
*/
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
+ /**
+ * @fixed_matrix_type:
+ *
+ * Type of Fixed Matrix operation.
+ */
+ enum drm_colorop_fixed_matrix_type fixed_matrix_type;
+
/** @state: backpointer to global drm_atomic_commit */
struct drm_atomic_commit *state;
};
@@ -366,6 +438,13 @@ struct drm_colorop {
*/
struct drm_property *data_property;
+ /**
+ * @fixed_matrix_type_property:
+ *
+ * Sub-type for DRM_COLOROP_FIXED_MATRIX type.
+ */
+ struct drm_property *fixed_matrix_type_property;
+
/**
* @next_property:
*
@@ -422,6 +501,10 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
uint32_t lut_size,
enum drm_colorop_lut3d_interpolation_type interpolation,
uint32_t flags);
+int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
+ struct drm_plane *plane,
+ const struct drm_colorop_funcs *funcs,
+ u64 supported_fm, uint32_t flags);
struct drm_colorop_state *
drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
@@ -480,6 +563,7 @@ drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_ty
const char *
drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type);
+const char *drm_get_colorop_fixed_matrix_type_name(enum drm_colorop_fixed_matrix_type type);
void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next);
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index bd435effdcee..ed1a660a3dfd 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -955,6 +955,18 @@ enum drm_colorop_type {
* color = lut3d[index]
*/
DRM_COLOROP_3D_LUT,
+
+ /**
+ * @DRM_COLOROP_FIXED_MATRIX:
+ *
+ * enum string "Fixed Matrix"
+ *
+ * A Colorop block that performs a pre-defined matrix operation selected
+ * via the FIXED_MATRIX_TYPE enum property. The driver advertises the supported
+ * operations through this property.
+ */
+ DRM_COLOROP_FIXED_MATRIX,
+
};
/**
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
2026-07-20 4:51 ` [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Chaitanya Kumar Borah
@ 2026-07-20 5:22 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:22 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Validation of the 64-bit `supported_fm` mask uses the 32-bit `BIT()` macro, causing invalid bits in the upper 32 bits to silently bypass validation on 32-bit architectures.
--
--- Patch [1]: [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX ---
commit 25b997b331b57b2649988bc81ff156f876274b02
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/colorop: Add DRM_COLOROP_FIXED_MATRIX
Introduce DRM_COLOROP_FIXED_MATRIX, a new colorop type representing a
hardware that performs a fixed matrix operation. Userspace selects one of
the predefined hardware modes via a new FIXED_MATRIX_TYPE enum property.
> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
> index 682fcc6515259..483defad699c0 100644
> --- a/drivers/gpu/drm/drm_colorop.c
> +++ b/drivers/gpu/drm/drm_colorop.c
[ ... ]
> @@ -453,6 +462,80 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
[ ... ]
> +int drm_plane_colorop_fixed_matrix_init(struct drm_device *dev, struct drm_colorop *colorop,
> + struct drm_plane *plane,
> + const struct drm_colorop_funcs *funcs,
> + u64 supported_fm, uint32_t flags)
> +{
> + struct drm_prop_enum_list enum_list[DRM_COLOROP_FM_COUNT];
> + int i, len;
> + struct drm_property *prop;
> + int ret;
> +
> + if (!supported_fm) {
> + drm_err(dev,
> + "No supported FM type op for new Fixed Matrix colorop on [PLANE:%d:%s]\n",
> + plane->base.id, plane->name);
> + return -EINVAL;
> + }
> +
> + if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
[Severity: Medium]
Since supported_fm is a u64, could using the 32-bit BIT() macro here cause
validation issues on 32-bit architectures?
On 32-bit architectures, BIT() evaluates to an unsigned long (32 bits). When
negated and then promoted to u64 for the bitwise AND with supported_fm, it
zero-extends the upper 32 bits (e.g., 0x00000000FFFFFFE0ULL). This means any
invalid bits set in the upper 32 bits of supported_fm would be zeroed out
during the operation and silently bypass this validation check.
Would it be better to use BIT_ULL(DRM_COLOROP_FM_COUNT) or GENMASK_ULL to
ensure the mask is properly validated across its entire 64-bit range?
> + drm_err(dev, "Unknown Fixed Matrix provided on [PLANE:%d:%s]\n",
> + plane->base.id, plane->name);
> + return -EINVAL;
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:33 ` sashiko-bot
2026-07-20 4:51 ` [v5 03/14] drm/i915/display: extract glk_plane_color_ctl_input_csc helper Chaitanya Kumar Borah
` (11 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Add the fixed-function CSC block to color pipeline in SDR planes
as a DRM_COLOROP_FIXED_MATRIX colorop.
v2:
- s/DRM_COLOROP_FM_YCBCR2020_FULL_RGB_NC/
DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB
- Inline icl_is_hdr_plane() instead of storing in local variable
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
.../drm/i915/display/intel_color_pipeline.c | 21 ++++++++++++++++++-
.../drm/i915/display/intel_display_limits.h | 1 +
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
index 6cf8080ee800..2ef42a133a98 100644
--- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
+++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
@@ -43,6 +43,16 @@ static const enum intel_color_block hdr_plane_pipeline[] = {
INTEL_PLANE_CB_POST_CSC_LUT,
};
+static const enum intel_color_block sdr_plane_pipeline[] = {
+ INTEL_PLANE_CB_CSC_FF,
+};
+
+static const u64 intel_plane_supported_csc_ff =
+ BIT(DRM_COLOROP_FM_YCBCR601_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR709_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB) |
+ BIT(DRM_COLOROP_FM_RGB709_RGB2020);
+
static bool plane_has_3dlut(struct intel_display *display, enum pipe pipe,
struct drm_plane *plane)
{
@@ -92,6 +102,12 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
DRM_COLOROP_FLAG_ALLOW_BYPASS);
break;
+ case INTEL_PLANE_CB_CSC_FF:
+ ret = drm_plane_colorop_fixed_matrix_init(dev, &colorop->base, plane,
+ &intel_colorop_funcs,
+ intel_plane_supported_csc_ff,
+ DRM_COLOROP_FLAG_ALLOW_BYPASS);
+ break;
default:
drm_err(plane->dev, "Invalid colorop id [%d]", id);
ret = -EINVAL;
@@ -126,9 +142,12 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
if (plane_has_3dlut(display, pipe, plane)) {
pipeline = xe3plpd_primary_plane_pipeline;
pipeline_len = ARRAY_SIZE(xe3plpd_primary_plane_pipeline);
- } else {
+ } else if (icl_is_hdr_plane(display, to_intel_plane(plane)->id)) {
pipeline = hdr_plane_pipeline;
pipeline_len = ARRAY_SIZE(hdr_plane_pipeline);
+ } else {
+ pipeline = sdr_plane_pipeline;
+ pipeline_len = ARRAY_SIZE(sdr_plane_pipeline);
}
for (i = 0; i < pipeline_len; i++) {
diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h
index ea89473c177f..7ba7360c574e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_limits.h
+++ b/drivers/gpu/drm/i915/display/intel_display_limits.h
@@ -169,6 +169,7 @@ enum aux_ch {
enum intel_color_block {
INTEL_PLANE_CB_PRE_CSC_LUT,
INTEL_PLANE_CB_CSC,
+ INTEL_PLANE_CB_CSC_FF,
INTEL_PLANE_CB_POST_CSC_LUT,
INTEL_PLANE_CB_3DLUT,
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline
2026-07-20 4:51 ` [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline Chaitanya Kumar Borah
@ 2026-07-20 5:33 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:33 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [High] Missing backend implementation for exposed `INTEL_PLANE_CB_CSC_FF` colorop.
- [Medium] Unreachable SDR plane color pipeline logic.
- [Medium] Validation bypass for 64-bit bitmasks on 32-bit architectures.
Pre-existing issues:
- [High] NULL pointer dereference in error cleanup path of `intel_color_pipeline_plane_add_colorop`.
- [High] Leaked DRM mode object ID on colorop cleanup leads to a Use-After-Free.
--
--- Patch [2]: [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline ---
commit 406763c8b5fb35d6a8f9c41091f76f4b8453fc5a
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/color: Add CSC on SDR plane color pipeline
Add the fixed-function CSC block to color pipeline in SDR planes
as a DRM_COLOROP_FIXED_MATRIX colorop.
> diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> index 6cf8080ee8000..2ef42a133a987 100644
> --- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> +++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
[ ... ]
> @@ -92,6 +102,12 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
> DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
> DRM_COLOROP_FLAG_ALLOW_BYPASS);
> break;
> + case INTEL_PLANE_CB_CSC_FF:
> + ret = drm_plane_colorop_fixed_matrix_init(dev, &colorop->base, plane,
> + &intel_colorop_funcs,
> + intel_plane_supported_csc_ff,
> + DRM_COLOROP_FLAG_ALLOW_BYPASS);
> + break;
[Severity: Medium]
Can this bypass validation for invalid upper bits on 32-bit architectures?
When calling drm_plane_colorop_fixed_matrix_init() and passing the 64-bit mask
intel_plane_supported_csc_ff, the validation check uses the BIT() macro:
drivers/gpu/drm/drm_colorop.c:drm_plane_colorop_fixed_matrix_init() {
...
if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
...
}
Since BIT() returns an unsigned long, which is 32 bits on 32-bit
architectures, negating it produces a 32-bit mask (0xFFFFFFFx) that is
zero-extended when ANDed with the 64-bit supported_fm mask. Does this silently
ignore bits 32-63 during validation?
[Severity: High]
Does the i915 driver have the backend implementation to process this newly
exposed fixed-matrix colorop?
The INTEL_PLANE_CB_CSC_FF colorop exposes the fixed_matrix_type property to
userspace. However, looking at the parsing logic:
drivers/gpu/drm/i915/display/intel_plane.c:
intel_plane_color_copy_uapi_to_hw_state() {
...
blob = new_colorop_state->bypass ? NULL : new_colorop_state->data;
intel_colorop = to_intel_colorop(colorop);
changed |= intel_plane_colorop_replace_blob(plane_state,
intel_colorop,
blob);
...
}
This appears to only handle blobs (LUTs, CTMs) and completely ignores the
fixed_matrix_type state. Could this cause the userspace configuration to be
silently discarded and never programmed to the hardware?
[Severity: High]
This isn't a bug introduced by this patch, but if
drm_plane_colorop_fixed_matrix_init() fails, will the cleanup path trigger
a NULL pointer dereference?
If initialization fails, it jumps to the cleanup label:
drivers/gpu/drm/i915/display/intel_color_pipeline.c:
intel_color_pipeline_plane_add_colorop() {
...
cleanup:
intel_colorop_destroy(&colorop->base);
return ERR_PTR(ret);
}
Which then calls drm_colorop_cleanup():
drivers/gpu/drm/drm_colorop.c:drm_colorop_cleanup() {
struct drm_device *dev = colorop->dev;
struct drm_mode_config *config = &dev->mode_config;
list_del(&colorop->head);
...
}
If the failure happens early in initialization before colorop->dev or
colorop->head are set, dev will be NULL and this will crash.
[Severity: High]
This is a pre-existing issue, but does drm_colorop_cleanup() leak the DRM
mode object ID?
When drm_plane_colorop_init() executes successfully, it allocates an ID in the
DRM device's IDR by calling drm_mode_object_add(). However,
drm_colorop_cleanup() appears to be missing a call to
drm_mode_object_unregister(dev, &colorop->base).
Does this mean the ID remains allocated forever, potentially leading to a
use-after-free if userspace later queries the leaked ID after the memory is
freed?
> default:
> drm_err(plane->dev, "Invalid colorop id [%d]", id);
> ret = -EINVAL;
> @@ -126,9 +142,12 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
> if (plane_has_3dlut(display, pipe, plane)) {
> pipeline = xe3plpd_primary_plane_pipeline;
> pipeline_len = ARRAY_SIZE(xe3plpd_primary_plane_pipeline);
> - } else {
> + } else if (icl_is_hdr_plane(display, to_intel_plane(plane)->id)) {
> pipeline = hdr_plane_pipeline;
> pipeline_len = ARRAY_SIZE(hdr_plane_pipeline);
> + } else {
> + pipeline = sdr_plane_pipeline;
> + pipeline_len = ARRAY_SIZE(sdr_plane_pipeline);
> }
[Severity: Medium]
Will this else branch ever be executed for SDR planes?
Looking at the caller, intel_color_pipeline_plane_init(), there is an explicit
early return for non-HDR planes:
drivers/gpu/drm/i915/display/intel_color_pipeline.c:
intel_color_pipeline_plane_init() {
...
/* Currently expose pipeline only for HDR planes */
if (!icl_is_hdr_plane(display, to_intel_plane(plane)->id))
return 0;
...
}
It seems this prevents the newly added SDR logic from ever being reached.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=2
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 03/14] drm/i915/display: extract glk_plane_color_ctl_input_csc helper
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 01/14] drm/colorop: Add DRM_COLOROP_FIXED_MATRIX Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 02/14] drm/i915/color: Add CSC on SDR plane color pipeline Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 04/14] drm/i915/display: simplify glk_plane_color_ctl_input_csc Chaitanya Kumar Borah
` (10 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Extract the input CSC and YUV range correction logic from
glk_plane_color_ctl() into a dedicated glk_plane_color_ctl_input_csc()
helper. No functional change.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
.../drm/i915/display/skl_universal_plane.c | 32 +++++++++++--------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index b246fc48558b..f831c1958ff4 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1240,37 +1240,43 @@ static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
return plane_color_ctl;
}
-static u32 glk_plane_color_ctl(const struct intel_plane_state *plane_state)
+static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
- u32 plane_color_ctl = 0;
-
- plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
- plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
+ u32 ctl = 0;
if (fb->format->is_yuv && !icl_is_hdr_plane(display, plane->id)) {
switch (plane_state->hw.color_encoding) {
case DRM_COLOR_YCBCR_BT709:
- plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
+ ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
break;
case DRM_COLOR_YCBCR_BT2020:
- plane_color_ctl |=
- PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
+ ctl |= PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
break;
default:
- plane_color_ctl |=
- PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
+ ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
}
if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
- plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
+ ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
} else if (fb->format->is_yuv) {
- plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
+ ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
- plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
+ ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
}
+ return ctl;
+}
+
+static u32 glk_plane_color_ctl(const struct intel_plane_state *plane_state)
+{
+ u32 plane_color_ctl = 0;
+
+ plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
+ plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
+ plane_color_ctl |= glk_plane_color_ctl_input_csc(plane_state);
+
if (plane_state->force_black)
plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 04/14] drm/i915/display: simplify glk_plane_color_ctl_input_csc
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (2 preceding siblings ...)
2026-07-20 4:51 ` [v5 03/14] drm/i915/display: extract glk_plane_color_ctl_input_csc helper Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 05/14] drm/i915/display: Track CSC mode in intel plane state Chaitanya Kumar Borah
` (9 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Add early return for non-YUV formats and hoist the duplicated
color_range check out of the if/else branches. No functional change.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/skl_universal_plane.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index f831c1958ff4..e09743179c0c 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1247,7 +1247,10 @@ static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_s
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
u32 ctl = 0;
- if (fb->format->is_yuv && !icl_is_hdr_plane(display, plane->id)) {
+ if (!fb->format->is_yuv)
+ return 0;
+
+ if (!icl_is_hdr_plane(display, plane->id)) {
switch (plane_state->hw.color_encoding) {
case DRM_COLOR_YCBCR_BT709:
ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
@@ -1258,14 +1261,13 @@ static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_s
default:
ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
}
- if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
- ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
- } else if (fb->format->is_yuv) {
+ } else {
ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
- if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
- ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
}
+ if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+ ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
+
return ctl;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 05/14] drm/i915/display: Track CSC mode in intel plane state
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (3 preceding siblings ...)
2026-07-20 4:51 ` [v5 04/14] drm/i915/display: simplify glk_plane_color_ctl_input_csc Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:28 ` sashiko-bot
2026-07-20 4:51 ` [v5 06/14] drm/i915/display: Program input CSC on SDR planes Chaitanya Kumar Borah
` (8 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Add CSC mode to hw plane state to enable programming the fixed-function
CSC block for SDR planes based on the DRM_COLOROP_FIXED_MATRIX state.
Track the bypass state explicitly as a boolean since bypass is managed
separately from the FIXED_MATRIX enum value in the colorop framework.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++
drivers/gpu/drm/i915/display/intel_plane.c | 12 ++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 17336ad6d5e9..ba295cbea0f2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -683,6 +683,8 @@ struct intel_plane_state {
enum drm_color_range color_range;
enum drm_scaling_filter scaling_filter;
struct drm_property_blob *ctm, *degamma_lut, *gamma_lut, *lut_3d;
+ enum drm_colorop_fixed_matrix_type csc_ff_type; /* For SDR plane */
+ bool csc_ff_enable;
} hw;
struct i915_vma *ggtt_vma;
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index d0f99a87c42e..d9908b976ca1 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -485,11 +485,19 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
while (iter_colorop) {
for_each_new_colorop_in_state(&state->base, colorop, new_colorop_state, i) {
if (new_colorop_state->colorop == iter_colorop) {
- blob = new_colorop_state->bypass ? NULL : new_colorop_state->data;
intel_colorop = to_intel_colorop(colorop);
- changed |= intel_plane_colorop_replace_blob(plane_state,
+ if (intel_colorop->id == INTEL_PLANE_CB_CSC_FF) {
+ plane_state->hw.csc_ff_enable =
+ !new_colorop_state->bypass;
+ plane_state->hw.csc_ff_type =
+ new_colorop_state->fixed_matrix_type;
+ } else {
+ blob = new_colorop_state->bypass ?
+ NULL : new_colorop_state->data;
+ changed |= intel_plane_colorop_replace_blob(plane_state,
intel_colorop,
blob);
+ }
}
}
iter_colorop = iter_colorop->next;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 05/14] drm/i915/display: Track CSC mode in intel plane state
2026-07-20 4:51 ` [v5 05/14] drm/i915/display: Track CSC mode in intel plane state Chaitanya Kumar Borah
@ 2026-07-20 5:28 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:28 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Unmodified plane color pipeline state (including the newly added CSC_FF configuration) is inadvertently wiped and silently disabled when an atomic commit modifies unrelated plane properties.
--
--- Patch [5]: [v5 05/14] drm/i915/display: Track CSC mode in intel plane state ---
commit ff45547703318a58efbb8be7b806421f22234b15
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/display: Track CSC mode in intel plane state
This commit adds CSC mode to the hardware plane state to enable programming
the fixed-function CSC block for SDR planes based on the
DRM_COLOROP_FIXED_MATRIX state. It also explicitly tracks the bypass state
as a boolean.
> diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
> --- a/drivers/gpu/drm/i915/display/intel_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_plane.c
[ ... ]
> @@ -430,11 +430,19 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
> while (iter_colorop) {
> for_each_new_colorop_in_state(&state->base, colorop, new_colorop_state, i) {
[Severity: High]
This is a pre-existing issue, but I have a question about how unmodified
colorops are handled here.
Does this cause the hardware colorop configuration to be lost when unrelated
plane properties are updated?
Since for_each_new_colorop_in_state() only iterates over colorops actively
included in the current atomic commit, unmodified colorops won't be in the
state during a simple plane update like a page flip.
Because the hardware state is wiped earlier by intel_plane_clear_hw_state(),
unmodified plane color pipeline state (including the newly added CSC_FF
configuration) appears to be left zeroed and silently disabled.
Can this lead to incorrect display output, and should this path handle
copying state from unmodified colorops?
> if (new_colorop_state->colorop == iter_colorop) {
> - blob = new_colorop_state->bypass ? NULL : new_colorop_state->data;
> intel_colorop = to_intel_colorop(colorop);
> - changed |= intel_plane_colorop_replace_blob(plane_state,
> + if (intel_colorop->id == INTEL_PLANE_CB_CSC_FF) {
> + plane_state->hw.csc_ff_enable =
> + !new_colorop_state->bypass;
> + plane_state->hw.csc_ff_type =
> + new_colorop_state->fixed_matrix_type;
> + } else {
> + blob = new_colorop_state->bypass ?
> + NULL : new_colorop_state->data;
> + changed |= intel_plane_colorop_replace_blob(plane_state,
> intel_colorop,
> blob);
> + }
> }
> }
> iter_colorop = iter_colorop->next;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=5
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 06/14] drm/i915/display: Program input CSC on SDR planes
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (4 preceding siblings ...)
2026-07-20 4:51 ` [v5 05/14] drm/i915/display: Track CSC mode in intel plane state Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:27 ` sashiko-bot
2026-07-20 4:51 ` [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support Chaitanya Kumar Borah
` (7 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
When a color pipeline is active, program the SDR plane fixed-function
CSC. Keep the legacy color_encoding/color_range properties mutually
exclusive with color pipeline uapi.
v2:
- Do not skip programming legacy property if color pipeline is not set.
Support for YUV buffers in color pipeline uAPI is a work in progress.
Therefore, color-pipeline-aware userspace might still use the legacy
COLOR_RANGE and COLOR_ENCODING property while keeping the color
pipeline to Bypass. Therefore, skip programming based on legacy
properties only when a color pipeline is set.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com> #v1
---
.../drm/i915/display/skl_universal_plane.c | 63 ++++++++++++++-----
1 file changed, 46 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index e09743179c0c..c5e5081e67c2 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1240,33 +1240,62 @@ static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
return plane_color_ctl;
}
+static u32 intel_csc_ff_type_to_csc_mode(enum drm_colorop_fixed_matrix_type csc_ff_type)
+{
+ u32 csc_mode;
+
+ switch (csc_ff_type) {
+ case DRM_COLOROP_FM_YCBCR601_FULL_RGB:
+ csc_mode = PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
+ break;
+ case DRM_COLOROP_FM_YCBCR709_FULL_RGB:
+ csc_mode = PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
+ break;
+ case DRM_COLOROP_FM_YCBCR2020_NC_FULL_RGB:
+ csc_mode = PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
+ break;
+ case DRM_COLOROP_FM_RGB709_RGB2020:
+ csc_mode = PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020;
+ break;
+ default:
+ csc_mode = PLANE_COLOR_CSC_MODE_BYPASS;
+ }
+ return csc_mode;
+}
+
static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_state)
{
struct intel_display *display = to_intel_display(plane_state);
const struct drm_framebuffer *fb = plane_state->hw.fb;
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ bool color_pipeline = !!plane_state->uapi.color_pipeline;
u32 ctl = 0;
- if (!fb->format->is_yuv)
- return 0;
+ if (!color_pipeline) {
+ if (!fb->format->is_yuv)
+ return 0;
- if (!icl_is_hdr_plane(display, plane->id)) {
- switch (plane_state->hw.color_encoding) {
- case DRM_COLOR_YCBCR_BT709:
- ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
- break;
- case DRM_COLOR_YCBCR_BT2020:
- ctl |= PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
- break;
- default:
- ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
+ if (!icl_is_hdr_plane(display, plane->id)) {
+ switch (plane_state->hw.color_encoding) {
+ case DRM_COLOR_YCBCR_BT709:
+ ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
+ break;
+ case DRM_COLOR_YCBCR_BT2020:
+ ctl |= PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020;
+ break;
+ default:
+ ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601;
+ }
+ } else {
+ ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
}
- } else {
- ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
- }
- if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
- ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
+ if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
+ ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
+ } else if (!icl_is_hdr_plane(display, plane->id)) {
+ if (plane_state->hw.csc_ff_enable)
+ ctl |= intel_csc_ff_type_to_csc_mode(plane_state->hw.csc_ff_type);
+ }
return ctl;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 06/14] drm/i915/display: Program input CSC on SDR planes
2026-07-20 4:51 ` [v5 06/14] drm/i915/display: Program input CSC on SDR planes Chaitanya Kumar Borah
@ 2026-07-20 5:27 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:27 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] YUV range correction is not disabled for full-range YCbCr formats when a color pipeline is active on an SDR plane.
--
--- Patch [6]: [v5 06/14] drm/i915/display: Program input CSC on SDR planes ---
commit 8a9ffb3a71cf84165b43a62eef15fa69e1d8e5a0
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/display: Program input CSC on SDR planes
When a color pipeline is active, program the SDR plane fixed-function
CSC. Keep the legacy color_encoding/color_range properties mutually
exclusive with color pipeline uapi.
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index da2df5be9848d..9893b061da5fa 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
[ ... ]
> @@ -1240,33 +1240,62 @@ static u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
[ ... ]
> static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_state)
> {
[ ... ]
> + if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
> + ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
> + } else if (!icl_is_hdr_plane(display, plane->id)) {
> + if (plane_state->hw.csc_ff_enable)
> + ctl |= intel_csc_ff_type_to_csc_mode(plane_state->hw.csc_ff_type);
> + }
[Severity: High]
Does this code miss disabling YUV range correction for full-range YCbCr formats
when a color pipeline is active?
Userspace configuring an SDR plane with a color pipeline using one of the
supported DRM_COLOROP_FM_YCBCR*_FULL_RGB fixed matrix operations will map to
PLANE_COLOR_CSC_MODE_YUV* modes, but it doesn't appear to set the
PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE bit here.
Could this lead to the hardware performing an unintended limited-to-full
range correction on full-range YCbCr data?
>
> return ctl;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=6
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (5 preceding siblings ...)
2026-07-20 4:51 ` [v5 06/14] drm/i915/display: Program input CSC on SDR planes Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:28 ` sashiko-bot
2026-07-20 4:51 ` [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline Chaitanya Kumar Borah
` (6 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Add support for color block which performs YCbCr limited-to-full
range expansion in the plane color pipeline. The color block is
represented using DRM_COLOROP_FIXED_MATRIX colorop.
v2:
- s/yuv_range_correct/yuv_range_correction_disable/ to mirror
HW register bit naming
- Fix inverted bypass logic: assign bypass state directly since
bypass=true means HW range correction should be disabled
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color_pipeline.c | 6 ++++++
drivers/gpu/drm/i915/display/intel_display_limits.h | 1 +
drivers/gpu/drm/i915/display/intel_display_types.h | 1 +
drivers/gpu/drm/i915/display/intel_plane.c | 3 +++
drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 ++
5 files changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
index 2ef42a133a98..7d25f4fbfa9b 100644
--- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
+++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
@@ -108,6 +108,12 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
intel_plane_supported_csc_ff,
DRM_COLOROP_FLAG_ALLOW_BYPASS);
break;
+ case INTEL_PLANE_CB_YUV_RANGE_CORRECT:
+ ret = drm_plane_colorop_fixed_matrix_init(dev, &colorop->base, plane,
+ &intel_colorop_funcs,
+ BIT(DRM_COLOROP_FM_YCBCR_LIMITED_FULL),
+ DRM_COLOROP_FLAG_ALLOW_BYPASS);
+ break;
default:
drm_err(plane->dev, "Invalid colorop id [%d]", id);
ret = -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h
index 7ba7360c574e..9493d333a242 100644
--- a/drivers/gpu/drm/i915/display/intel_display_limits.h
+++ b/drivers/gpu/drm/i915/display/intel_display_limits.h
@@ -172,6 +172,7 @@ enum intel_color_block {
INTEL_PLANE_CB_CSC_FF,
INTEL_PLANE_CB_POST_CSC_LUT,
INTEL_PLANE_CB_3DLUT,
+ INTEL_PLANE_CB_YUV_RANGE_CORRECT,
INTEL_CB_MAX
};
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ba295cbea0f2..b0a2fac24bee 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -685,6 +685,7 @@ struct intel_plane_state {
struct drm_property_blob *ctm, *degamma_lut, *gamma_lut, *lut_3d;
enum drm_colorop_fixed_matrix_type csc_ff_type; /* For SDR plane */
bool csc_ff_enable;
+ bool yuv_range_correction_disable;
} hw;
struct i915_vma *ggtt_vma;
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index d9908b976ca1..ca8903045195 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -491,6 +491,9 @@ intel_plane_color_copy_uapi_to_hw_state(struct intel_atomic_state *state,
!new_colorop_state->bypass;
plane_state->hw.csc_ff_type =
new_colorop_state->fixed_matrix_type;
+ } else if (intel_colorop->id == INTEL_PLANE_CB_YUV_RANGE_CORRECT) {
+ plane_state->hw.yuv_range_correction_disable =
+ new_colorop_state->bypass;
} else {
blob = new_colorop_state->bypass ?
NULL : new_colorop_state->data;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index c5e5081e67c2..4d17ea452a25 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1295,6 +1295,8 @@ static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_s
} else if (!icl_is_hdr_plane(display, plane->id)) {
if (plane_state->hw.csc_ff_enable)
ctl |= intel_csc_ff_type_to_csc_mode(plane_state->hw.csc_ff_type);
+ if (plane_state->hw.yuv_range_correction_disable)
+ ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
}
return ctl;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support
2026-07-20 4:51 ` [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support Chaitanya Kumar Borah
@ 2026-07-20 5:28 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:28 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] YUV range correction is incorrectly enabled by default for all color pipelines, corrupting both RGB and YUV surfaces.
- [Medium] The INTEL_PLANE_CB_YUV_RANGE_CORRECT color block is never added to the plane color pipeline arrays, making the feature unreachable.
Pre-existing issues:
- [Critical] Use-After-Free via leaked DRM IDR pointer during colorop cleanup.
- [High] NULL Pointer Dereference on colorop initialization error path.
--
--- Patch [7]: [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support ---
commit 63b36f46939531b2add35ef940340e77707f342a
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/color: Add YCbCr limited-to-full range color block support
Add support for color block which performs YCbCr limited-to-full
range expansion in the plane color pipeline. The color block is
represented using DRM_COLOROP_FIXED_MATRIX colorop.
> diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> index 2ef42a133a987..7d25f4fbfa9b7 100644
> --- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> +++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> @@ -108,6 +108,12 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
> intel_plane_supported_csc_ff,
> DRM_COLOROP_FLAG_ALLOW_BYPASS);
> break;
> + case INTEL_PLANE_CB_YUV_RANGE_CORRECT:
> + ret = drm_plane_colorop_fixed_matrix_init(dev, &colorop->base, plane,
> + &intel_colorop_funcs,
> + BIT(DRM_COLOROP_FM_YCBCR_LIMITED_FULL),
> + DRM_COLOROP_FLAG_ALLOW_BYPASS);
[Severity: Medium]
Is INTEL_PLANE_CB_YUV_RANGE_CORRECT actually reachable? It appears this color
block is omitted from the pipeline definition arrays like sdr_plane_pipeline,
which means it will never be added to the pipeline.
[Severity: High]
This is a pre-existing issue, but does drm_colorop_cleanup() dereference a
NULL pointer if drm_plane_colorop_fixed_matrix_init() fails?
If drm_mode_object_add() fails during initialization, it returns an error
before colorop->dev is set. The cleanup path calls drm_colorop_cleanup(),
which unconditionally dereferences colorop->dev:
void drm_colorop_cleanup(struct drm_colorop *colorop)
{
struct drm_device *dev = colorop->dev;
struct drm_mode_config *config = &dev->mode_config;
This would result in a crash during device probe.
[Severity: Critical]
This is also a pre-existing issue, but does drm_colorop_cleanup() leak the
DRM IDR pointer?
drm_plane_colorop_fixed_matrix_init() registers the colorop with the DRM IDR
via drm_mode_object_add(). However, drm_colorop_cleanup() fails to call
drm_mode_object_unregister(), leaving a dangling pointer in the IDR:
void drm_colorop_cleanup(struct drm_colorop *colorop)
{
...
list_del(&colorop->head);
config->num_colorop--;
if (colorop->state)
drm_colorop_atomic_destroy_state(colorop, colorop->state);
}
Could this lead to a Use-After-Free if userspace invokes DRM IOCTLs (like
DRM_IOCTL_MODE_OBJ_GETPROPERTIES) using the leaked ID?
> + break;
> default:
> drm_err(plane->dev, "Invalid colorop id [%d]", id);
> ret = -EINVAL;
[ ... ]
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 9893b061da5fa..88df4a76a0ab8 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -1295,6 +1295,8 @@ static u32 glk_plane_color_ctl_input_csc(const struct intel_plane_state *plane_s
> } else if (!icl_is_hdr_plane(display, plane->id)) {
> if (plane_state->hw.csc_ff_enable)
> ctl |= intel_csc_ff_type_to_csc_mode(plane_state->hw.csc_ff_type);
> + if (plane_state->hw.yuv_range_correction_disable)
> + ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
[Severity: High]
Does this logic inadvertently enable YUV range correction by default for all
color pipelines, corrupting RGB and YUV surfaces?
When a color pipeline is active, the early return for non-YUV surfaces is
skipped in glk_plane_color_ctl_input_csc():
if (!fb->format->is_yuv)
return 0;
Since INTEL_PLANE_CB_YUV_RANGE_CORRECT is missing from the pipeline array,
yuv_range_correction_disable defaults to false. This leaves the
PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE bit unset (meaning enabled).
Furthermore, HDR planes skip this bit assignment entirely due to the
!icl_is_hdr_plane() check, meaning range correction is unconditionally enabled
for them as well.
> }
>
> return ctl;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=7
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (6 preceding siblings ...)
2026-07-20 4:51 ` [v5 07/14] drm/i915/color: Add YCbCr limited-to-full range color block support Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:29 ` sashiko-bot
2026-07-20 4:51 ` [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes Chaitanya Kumar Borah
` (5 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Insert the INTEL_PLANE_CB_YUV_RANGE_CORRECT color block into the SDR
plane color pipeline. This enables YCbCr limited-to-full range expansion
ahead of the CSC block that expects full range pixel data. With this,
the pipeline can accept limited range framebuffers.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color_pipeline.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
index 7d25f4fbfa9b..7457fa51cb97 100644
--- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
+++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
@@ -44,6 +44,7 @@ static const enum intel_color_block hdr_plane_pipeline[] = {
};
static const enum intel_color_block sdr_plane_pipeline[] = {
+ INTEL_PLANE_CB_YUV_RANGE_CORRECT,
INTEL_PLANE_CB_CSC_FF,
};
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline
2026-07-20 4:51 ` [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline Chaitanya Kumar Borah
@ 2026-07-20 5:29 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:29 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Medium] The SDR plane color pipeline is never exposed to userspace because `intel_color_pipeline_plane_init()` unconditionally early-returns for non-HDR planes.
- [Low] The fixed matrix support mask validation fails to check bits 32-63 on 32-bit architectures due to unsigned integer zero-extension.
Pre-existing issues:
- [High] If colorop initialization fails early, the cleanup path dereferences a NULL `colorop->dev` pointer and uninitialized list head, causing a kernel panic.
--
--- Patch [8]: [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline ---
commit cf2ffd1a2b5d8ea9f91da1ef444dd3fa882dd254
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/color: Add YUV range correction to SDR plane pipeline
Insert the INTEL_PLANE_CB_YUV_RANGE_CORRECT color block into the SDR
plane color pipeline. This enables YCbCr limited-to-full range expansion
ahead of the CSC block that expects full range pixel data. With this,
the pipeline can accept limited range framebuffers.
> diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> index 7d25f4fbfa9b7..7457fa51cb97a 100644
> --- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> +++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> @@ -44,6 +44,7 @@ static const enum intel_color_block hdr_plane_pipeline[] = {
> };
>
> static const enum intel_color_block sdr_plane_pipeline[] = {
> + INTEL_PLANE_CB_YUV_RANGE_CORRECT,
> INTEL_PLANE_CB_CSC_FF,
> };
[Severity: Medium]
Will this newly added SDR plane pipeline actually be exposed to userspace?
Looking at intel_color_pipeline_plane_init(), there appears to be an early
return that completely prevents color pipelines from being initialized for SDR
planes:
drivers/gpu/drm/i915/display/intel_color_pipeline.c:intel_color_pipeline_plane_init() {
...
/* Currently expose pipeline only for HDR planes */
if (!icl_is_hdr_plane(display, to_intel_plane(plane)->id))
return 0;
...
}
Because of this early return, doesn't the assignment in
_intel_color_pipeline_plane_init() become dead code, leaving the new SDR
pipeline features inaccessible?
[Severity: High]
This is a pre-existing issue, but could the error path in
intel_color_pipeline_plane_add_colorop() cause a kernel panic?
If drm_plane_colorop_init() fails early (e.g., if drm_mode_object_add()
returns -ENOMEM), it returns before colorop->dev is set and before
colorop->head is added to the list.
When intel_color_pipeline_plane_add_colorop() jumps to the cleanup label:
drivers/gpu/drm/i915/display/intel_color_pipeline.c:intel_color_pipeline_plane_add_colorop() {
...
cleanup:
intel_colorop_destroy(&colorop->base);
return ERR_PTR(ret);
}
This calls drm_colorop_cleanup(), which unconditionally dereferences
colorop->dev and calls list_del() on the zeroed list head:
drivers/gpu/drm/drm_colorop.c:drm_colorop_cleanup() {
struct drm_device *dev = colorop->dev;
struct drm_mode_config *config = &dev->mode_config;
list_del(&colorop->head);
...
}
Would this lead to a NULL pointer dereference for colorop->dev and a list
corruption panic?
[Severity: Low]
Does the bitwise validation in drm_plane_colorop_fixed_matrix_init()
correctly handle checking on 32-bit architectures?
Looking at drivers/gpu/drm/drm_colorop.c:drm_plane_colorop_fixed_matrix_init():
if ((supported_fm & -BIT(DRM_COLOROP_FM_COUNT)) != 0) {
The check evaluates -BIT(5). On 32-bit platforms, this becomes a 32-bit
unsigned value (0xFFFFFFE0). When bitwise ANDed with the u64 supported_fm,
C integer promotion zero-extends it to 0x00000000FFFFFFE0.
Would this allow any invalid bits set in supported_fm between 32 and 63 to
silently bypass the check?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=8
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (7 preceding siblings ...)
2026-07-20 4:51 ` [v5 08/14] drm/i915/color: Add YUV range correction to SDR plane pipeline Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:28 ` sashiko-bot
2026-07-20 4:51 ` [v5 10/14] drm/i915/color: Extract HDR pre-CSC LUT programming to helper function Chaitanya Kumar Borah
` (4 subsequent siblings)
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Extend the SDR plane color pipeline to include pre- and post-CSC
1D LUT blocks.
SDR planes use a smaller LUT size than HDR planes and therefore
initialize the 1D LUT colorops with the appropriate hardware
capacity.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color_pipeline.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
index 7457fa51cb97..136b9378ca48 100644
--- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
+++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
@@ -15,6 +15,7 @@
#define MAX_COLOROP 4
#define PLANE_DEGAMMA_SIZE 128
#define PLANE_GAMMA_SIZE 32
+#define PLANE_DEGAMMA_SIZE_SDR 32
static const struct drm_colorop_funcs intel_colorop_funcs = {
.destroy = intel_colorop_destroy,
@@ -45,7 +46,9 @@ static const enum intel_color_block hdr_plane_pipeline[] = {
static const enum intel_color_block sdr_plane_pipeline[] = {
INTEL_PLANE_CB_YUV_RANGE_CORRECT,
+ INTEL_PLANE_CB_PRE_CSC_LUT,
INTEL_PLANE_CB_CSC_FF,
+ INTEL_PLANE_CB_POST_CSC_LUT,
};
static const u64 intel_plane_supported_csc_ff =
@@ -68,8 +71,10 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
enum intel_color_block id)
{
struct drm_device *dev = plane->dev;
+ struct intel_display *display = to_intel_display(dev);
struct intel_colorop *colorop;
int ret;
+ bool is_hdr = icl_is_hdr_plane(display, to_intel_plane(plane)->id);
colorop = intel_colorop_create(id);
@@ -81,7 +86,9 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
ret = drm_plane_colorop_curve_1d_lut_init(dev,
&colorop->base, plane,
&intel_colorop_funcs,
- PLANE_DEGAMMA_SIZE,
+ is_hdr ?
+ PLANE_DEGAMMA_SIZE :
+ PLANE_DEGAMMA_SIZE_SDR,
DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
DRM_COLOROP_FLAG_ALLOW_BYPASS);
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes
2026-07-20 4:51 ` [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes Chaitanya Kumar Borah
@ 2026-07-20 5:28 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:28 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but if colorop initialization fails early, the cleanup path calls `intel_colorop_destroy()` on a partially initialized object, leading to a NULL pointer dereference and uninitialized list head usage.
- [High] This problem wasn't introduced by this patch, but an unchecked return value from `kasprintf()` leads to a NULL pointer dereference when creating the color pipeline property.
--
--- Patch [9]: [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes ---
commit e6938001b7cb4179a20fa4b4c3bd94fef8282c50
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/color: Add support for 1D LUT in SDR planes
Extend the SDR plane color pipeline to include pre- and post-CSC 1D LUT blocks.
SDR planes use a smaller LUT size than HDR planes and therefore initialize the
1D LUT colorops with the appropriate hardware capacity.
> diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> index 7457fa51cb97a..136b9378ca484 100644
> --- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> +++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
[ ... ]
> @@ -81,7 +86,9 @@ struct intel_colorop *intel_color_pipeline_plane_add_colorop(struct drm_plane *p
> ret = drm_plane_colorop_curve_1d_lut_init(dev,
> &colorop->base, plane,
> &intel_colorop_funcs,
> - PLANE_DEGAMMA_SIZE,
> + is_hdr ?
> + PLANE_DEGAMMA_SIZE :
> + PLANE_DEGAMMA_SIZE_SDR,
> DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR,
> DRM_COLOROP_FLAG_ALLOW_BYPASS);
> break;
[Severity: High]
This isn't a bug introduced by this patch, but if colorop initialization fails
early, the cleanup path calls intel_colorop_destroy() on a partially
initialized object. Could this lead to a NULL pointer dereference and
uninitialized list head usage?
If drm_plane_colorop_init() fails early (e.g., drm_mode_object_add() returns
-ENOMEM), colorop->dev remains NULL and colorop->head is zero-filled. The error
path jumps to cleanup and invokes intel_colorop_destroy(), which delegates to
drm_colorop_cleanup():
drivers/gpu/drm/drm_colorop.c:drm_colorop_cleanup() {
struct drm_mode_config *config = &dev->mode_config;
list_del(&colorop->head);
config->num_colorop--;
}
This unconditionally dereferences dev (which is NULL) and calls list_del() on a
zero-filled list head.
[Severity: High]
This is also a pre-existing issue in the same file, but an unchecked return
value from kasprintf() can lead to a NULL pointer dereference when creating the
color pipeline property.
In _intel_color_pipeline_plane_init(), kasprintf() allocates memory for
list->name:
drivers/gpu/drm/i915/display/intel_color_pipeline.c:_intel_color_pipeline_plane_init() {
...
list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d", colorop[0]->base.base.id);
return 0;
}
If kasprintf() fails, it returns NULL, and the function unconditionally returns
success. This NULL name is later passed to drm_property_add_enum(), where a
strlen(name) call will crash the kernel:
drivers/gpu/drm/drm_property.c:drm_property_add_enum() {
...
if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN))
return 0;
...
}
Should the return value of kasprintf() be checked and handled as an error here?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=9
^ permalink raw reply [flat|nested] 23+ messages in thread
* [v5 10/14] drm/i915/color: Extract HDR pre-CSC LUT programming to helper function
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (8 preceding siblings ...)
2026-07-20 4:51 ` [v5 09/14] drm/i915/color: Add support for 1D LUT in SDR planes Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 11/14] drm/i915/color: Program Pre-CSC registers for SDR Chaitanya Kumar Borah
` (3 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel
Cc: Pranay Samala, Chaitanya Kumar Borah, Uma Shankar
From: Pranay Samala <pranay.samala@intel.com>
As we prepare to add support for LUT programming in SDR planes,
refactor HDR plane pre-CSC LUT programming to a helper.
Signed-off-by: Pranay Samala <pranay.samala@intel.com>
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color.c | 30 ++++++++++++++--------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 87ced9f6ff40..2a32ab62721c 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -3959,20 +3959,15 @@ xelpd_load_plane_csc_matrix(struct intel_dsb *dsb,
}
static void
-xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
- const struct intel_plane_state *plane_state)
+xelpd_load_hdr_pre_csc_lut(struct intel_display *display,
+ struct intel_dsb *dsb,
+ enum pipe pipe,
+ enum plane_id plane,
+ const struct drm_color_lut32 *pre_csc_lut)
{
- struct intel_display *display = to_intel_display(plane_state);
- const struct drm_plane_state *state = &plane_state->uapi;
- enum pipe pipe = to_intel_plane(state->plane)->pipe;
- enum plane_id plane = to_intel_plane(state->plane)->id;
- const struct drm_color_lut32 *pre_csc_lut = plane_state->hw.degamma_lut->data;
int i, lut_size = 128;
u32 lut_val;
- if (!icl_is_hdr_plane(display, plane))
- return;
-
intel_de_write_dsb(display, dsb,
PLANE_PRE_CSC_GAMC_INDEX_ENH(pipe, plane, 0),
PLANE_PAL_PREC_AUTO_INCREMENT);
@@ -3997,6 +3992,21 @@ xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
intel_de_write_dsb(display, dsb, PLANE_PRE_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0);
}
+static void
+xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
+ const struct intel_plane_state *plane_state)
+{
+ struct intel_display *display = to_intel_display(plane_state);
+ const struct drm_plane_state *state = &plane_state->uapi;
+ enum pipe pipe = to_intel_plane(state->plane)->pipe;
+ enum plane_id plane = to_intel_plane(state->plane)->id;
+ const struct drm_color_lut32 *pre_csc_lut = plane_state->hw.degamma_lut ?
+ plane_state->hw.degamma_lut->data : NULL;
+
+ if (icl_is_hdr_plane(display, plane))
+ xelpd_load_hdr_pre_csc_lut(display, dsb, pipe, plane, pre_csc_lut);
+}
+
static void
xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 11/14] drm/i915/color: Program Pre-CSC registers for SDR
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (9 preceding siblings ...)
2026-07-20 4:51 ` [v5 10/14] drm/i915/color: Extract HDR pre-CSC LUT programming to helper function Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 12/14] drm/i915/color: Extract HDR post-CSC LUT programming to helper function Chaitanya Kumar Borah
` (2 subsequent siblings)
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel
Cc: Pranay Samala, Chaitanya Kumar Borah, Uma Shankar
From: Pranay Samala <pranay.samala@intel.com>
Implement plane pre-CSC LUT support for SDR planes.
v2:
- s/drm_color_lut_extract/drm_color_lut32_extract
v3:
- Restructure loop to match HDR function pattern
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Pranay Samala <pranay.samala@intel.com>
Co-developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color.c | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 2a32ab62721c..abf3b3a2e177 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -3992,6 +3992,46 @@ xelpd_load_hdr_pre_csc_lut(struct intel_display *display,
intel_de_write_dsb(display, dsb, PLANE_PRE_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0);
}
+static void
+xelpd_load_sdr_pre_csc_lut(struct intel_display *display,
+ struct intel_dsb *dsb,
+ enum pipe pipe,
+ enum plane_id plane,
+ const struct drm_color_lut32 *pre_csc_lut)
+{
+ int i, lut_size = 32;
+ u32 lut_val;
+
+ /*
+ * First 3 planes are HDR, so reduce by 3 to get to the right
+ * SDR plane offset
+ */
+ plane = plane - 3;
+
+ intel_de_write_dsb(display, dsb,
+ PLANE_PRE_CSC_GAMC_INDEX(pipe, plane, 0),
+ PLANE_PAL_PREC_AUTO_INCREMENT);
+
+ for (i = 0; i < lut_size + 3; i++) {
+ if (pre_csc_lut) {
+ if (i < lut_size)
+ lut_val = drm_color_lut32_extract(pre_csc_lut[i].green, 16);
+ /* else duplicate last lut_val */
+ } else {
+ if (i < lut_size)
+ lut_val = (i * ((1 << 16) - 1)) / (lut_size - 1);
+ else
+ lut_val = 1 << 16;
+ }
+
+ intel_de_write_dsb(display, dsb,
+ PLANE_PRE_CSC_GAMC_DATA(pipe, plane, 0),
+ lut_val);
+ }
+
+ intel_de_write_dsb(display, dsb, PLANE_PRE_CSC_GAMC_INDEX(pipe, plane, 0), 0);
+}
+
static void
xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state)
@@ -4005,6 +4045,8 @@ xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
if (icl_is_hdr_plane(display, plane))
xelpd_load_hdr_pre_csc_lut(display, dsb, pipe, plane, pre_csc_lut);
+ else
+ xelpd_load_sdr_pre_csc_lut(display, dsb, pipe, plane, pre_csc_lut);
}
static void
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 12/14] drm/i915/color: Extract HDR post-CSC LUT programming to helper function
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (10 preceding siblings ...)
2026-07-20 4:51 ` [v5 11/14] drm/i915/color: Program Pre-CSC registers for SDR Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 13/14] drm/i915/color: Program Plane Post CSC registers for SDR planes Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 14/14] drm/i915/color: Add color pipeline support " Chaitanya Kumar Borah
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel
Cc: Pranay Samala, Chaitanya Kumar Borah, Uma Shankar
From: Pranay Samala <pranay.samala@intel.com>
Move HDR plane post-CSC LUT programming to improve code organization.
While at it, remove the segment 0 index register writes as it is not
currently programmed.
Signed-off-by: Pranay Samala <pranay.samala@intel.com>
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color.c | 35 ++++++++++++----------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index abf3b3a2e177..360046979556 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -4050,25 +4050,17 @@ xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb,
}
static void
-xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
- const struct intel_plane_state *plane_state)
+xelpd_load_hdr_post_csc_lut(struct intel_display *display,
+ struct intel_dsb *dsb,
+ enum pipe pipe,
+ enum plane_id plane,
+ const struct drm_color_lut32 *post_csc_lut)
{
- struct intel_display *display = to_intel_display(plane_state);
- const struct drm_plane_state *state = &plane_state->uapi;
- enum pipe pipe = to_intel_plane(state->plane)->pipe;
- enum plane_id plane = to_intel_plane(state->plane)->id;
- const struct drm_color_lut32 *post_csc_lut = plane_state->hw.gamma_lut->data;
int i, lut_size = 32;
u32 lut_val;
- if (!icl_is_hdr_plane(display, plane))
- return;
-
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0),
PLANE_PAL_PREC_AUTO_INCREMENT);
- /* TODO: Add macro */
- intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0),
- PLANE_PAL_PREC_AUTO_INCREMENT);
for (i = 0; i < lut_size + 3; i++) {
if (post_csc_lut) {
@@ -4088,8 +4080,21 @@ xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
}
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0);
- intel_de_write_dsb(display, dsb,
- PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0), 0);
+}
+
+static void
+xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
+ const struct intel_plane_state *plane_state)
+{
+ struct intel_display *display = to_intel_display(plane_state);
+ const struct drm_plane_state *state = &plane_state->uapi;
+ enum pipe pipe = to_intel_plane(state->plane)->pipe;
+ enum plane_id plane = to_intel_plane(state->plane)->id;
+ const struct drm_color_lut32 *post_csc_lut = plane_state->hw.gamma_lut ?
+ plane_state->hw.gamma_lut->data : NULL;
+
+ if (icl_is_hdr_plane(display, plane))
+ xelpd_load_hdr_post_csc_lut(display, dsb, pipe, plane, post_csc_lut);
}
static void
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 13/14] drm/i915/color: Program Plane Post CSC registers for SDR planes
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (11 preceding siblings ...)
2026-07-20 4:51 ` [v5 12/14] drm/i915/color: Extract HDR post-CSC LUT programming to helper function Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 4:51 ` [v5 14/14] drm/i915/color: Add color pipeline support " Chaitanya Kumar Borah
13 siblings, 0 replies; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel
Cc: Pranay Samala, Chaitanya Kumar Borah, Uma Shankar
From: Pranay Samala <pranay.samala@intel.com>
Implement plane post-CSC LUT support for SDR planes.
v2:
- Restructure loop to match HDR function pattern
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Pranay Samala <pranay.samala@intel.com>
Co-developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color.c | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 360046979556..be2e1d8ce0e6 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -4082,6 +4082,45 @@ xelpd_load_hdr_post_csc_lut(struct intel_display *display,
intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0);
}
+static void
+xelpd_load_sdr_post_csc_lut(struct intel_display *display,
+ struct intel_dsb *dsb,
+ enum pipe pipe,
+ enum plane_id plane,
+ const struct drm_color_lut32 *post_csc_lut)
+{
+ int i, lut_size = 32;
+ u32 lut_val;
+
+ /*
+ * First 3 planes are HDR, so reduce by 3 to get to the right
+ * SDR plane offset
+ */
+ plane = plane - 3;
+
+ intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0),
+ PLANE_PAL_PREC_AUTO_INCREMENT);
+
+ for (i = 0; i < lut_size + 3; i++) {
+ if (post_csc_lut) {
+ if (i < lut_size)
+ lut_val = drm_color_lut32_extract(post_csc_lut[i].green, 16);
+ /* else duplicate last lut_val */
+ } else {
+ if (i < lut_size)
+ lut_val = (i * ((1 << 16) - 1)) / (lut_size - 1);
+ else
+ lut_val = 1 << 16;
+ }
+
+ intel_de_write_dsb(display, dsb,
+ PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0),
+ lut_val);
+ }
+
+ intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0), 0);
+}
+
static void
xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
const struct intel_plane_state *plane_state)
@@ -4095,6 +4134,8 @@ xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb,
if (icl_is_hdr_plane(display, plane))
xelpd_load_hdr_post_csc_lut(display, dsb, pipe, plane, post_csc_lut);
+ else
+ xelpd_load_sdr_post_csc_lut(display, dsb, pipe, plane, post_csc_lut);
}
static void
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [v5 14/14] drm/i915/color: Add color pipeline support for SDR planes
2026-07-20 4:51 [v5 00/14] drm/i915/color: Enable SDR plane color pipeline Chaitanya Kumar Borah
` (12 preceding siblings ...)
2026-07-20 4:51 ` [v5 13/14] drm/i915/color: Program Plane Post CSC registers for SDR planes Chaitanya Kumar Borah
@ 2026-07-20 4:51 ` Chaitanya Kumar Borah
2026-07-20 5:39 ` sashiko-bot
13 siblings, 1 reply; 23+ messages in thread
From: Chaitanya Kumar Borah @ 2026-07-20 4:51 UTC (permalink / raw)
To: intel-gfx, intel-xe, dri-devel; +Cc: Chaitanya Kumar Borah, Uma Shankar
Now that everything is in place expose the SDR plane color pipeline
to user-space.
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
drivers/gpu/drm/i915/display/intel_color_pipeline.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
index 136b9378ca48..a99b6eb20448 100644
--- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
+++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
@@ -188,17 +188,11 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
int intel_color_pipeline_plane_init(struct drm_plane *plane, enum pipe pipe)
{
- struct drm_device *dev = plane->dev;
- struct intel_display *display = to_intel_display(dev);
struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES] = {};
int len = 0;
int ret = 0;
int i;
- /* Currently expose pipeline only for HDR planes */
- if (!icl_is_hdr_plane(display, to_intel_plane(plane)->id))
- return 0;
-
/* Add pipeline consisting of transfer functions */
ret = _intel_color_pipeline_plane_init(plane, &pipelines[len], pipe);
if (ret)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [v5 14/14] drm/i915/color: Add color pipeline support for SDR planes
2026-07-20 4:51 ` [v5 14/14] drm/i915/color: Add color pipeline support " Chaitanya Kumar Borah
@ 2026-07-20 5:39 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-07-20 5:39 UTC (permalink / raw)
To: Chaitanya Kumar Borah; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] A missing NULL check for the `kasprintf()` allocation in `_intel_color_pipeline_plane_init()` causes a NULL pointer dereference in `drm_property_add_enum()`.
- [High] Early initialization failures during colorop creation cause `drm_colorop_cleanup()` to access uninitialized structure members, leading to a crash.
- [High] Missing `drm_mode_object_unregister()` in `drm_colorop_cleanup()` leaves destroyed colorops in the DRM object IDR, leading to a Use-After-Free.
--
--- Patch [14]: [v5 14/14] drm/i915/color: Add color pipeline support for SDR planes ---
commit 898c62da94ca7a00530f154f1e3d4b18c45aaa47
Author: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
drm/i915/color: Add color pipeline support for SDR planes
This commit exposes the SDR plane color pipeline to user-space by removing
the check that previously limited it to HDR planes.
> diff --git a/drivers/gpu/drm/i915/display/intel_color_pipeline.c b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> index 136b9378ca484..a99b6eb204488 100644
> --- a/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> +++ b/drivers/gpu/drm/i915/display/intel_color_pipeline.c
> @@ -188,17 +188,11 @@ int _intel_color_pipeline_plane_init(struct drm_plane *plane, struct drm_prop_en
>
> int intel_color_pipeline_plane_init(struct drm_plane *plane, enum pipe pipe)
> {
> - struct drm_device *dev = plane->dev;
> - struct intel_display *display = to_intel_display(dev);
> struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES] = {};
> int len = 0;
> int ret = 0;
> int i;
>
> - /* Currently expose pipeline only for HDR planes */
> - if (!icl_is_hdr_plane(display, to_intel_plane(plane)->id))
> - return 0;
> -
> /* Add pipeline consisting of transfer functions */
> ret = _intel_color_pipeline_plane_init(plane, &pipelines[len], pipe);
[Severity: High]
This isn't a bug introduced by this patch, but opening this up to SDR planes
makes a pre-existing issue more reachable.
In _intel_color_pipeline_plane_init(), kasprintf() can fail and return NULL
under memory pressure:
list->name = kasprintf(GFP_KERNEL, "Color Pipeline %d",
colorop[0]->base.base.id);
Because there is no check for failure, a NULL name gets passed down to
drm_plane_create_color_pipeline_property(), then to drm_property_create_enum(),
and finally to drm_property_add_enum(), which dereferences it during
strlen(name) and crashes. Should we add a NULL check for kasprintf() in
_intel_color_pipeline_plane_init()?
[Severity: High]
This is also a pre-existing issue, but since we are expanding the usage of
this pipeline:
If an early initialization failure occurs in
intel_color_pipeline_plane_add_colorop() (such as drm_mode_object_add()
returning an error), the cleanup path calls intel_colorop_destroy() which
invokes drm_colorop_cleanup().
At this point, drm_colorop_cleanup() will dereference colorop->dev:
void drm_colorop_cleanup(struct drm_colorop *colorop)
{
struct drm_device *dev = colorop->dev;
struct drm_mode_config *config = &dev->mode_config;
...
If drm_mode_object_add() failed, colorop->dev remains NULL, causing an
immediate crash. Additionally, list_del(&colorop->head) is called on a
zero-initialized list node. Can this cleanup path be made safe for objects
that failed early initialization?
[Severity: High]
This is another pre-existing issue exposed by the expanded plane support:
If a colorop initialization fails midway (for instance, if
drm_property_create_enum() fails after drm_mode_object_add() succeeds),
the error path calls drm_colorop_cleanup() to free the memory.
However, drm_colorop_cleanup() does not call drm_mode_object_unregister().
This leaves a freed object pointer in the DRM device's object IDR. Is there
a risk that a user could trigger a use-after-free by passing the leaked
object ID to an ioctl like DRM_IOCTL_MODE_OBJ_GETPROPERTIES?
> if (ret)
> goto out;
> len++;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720045131.971650-1-chaitanya.kumar.borah@intel.com?part=14
^ permalink raw reply [flat|nested] 23+ messages in thread