public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
* [PATCH v2 0/2] YUV support for VOP2 background color
@ 2026-06-01 18:00 Cristian Ciocaltea
  2026-06-01 18:00 ` [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L Cristian Ciocaltea
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Cristian Ciocaltea @ 2026-06-01 18:00 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

Since commit bec7cbfa7d4f ("drm/rockchip: vop2: Support setting custom
background color") the VOP2 display controller allows configuring the
background color of each video output port.

However, this is currently limited to RGB formats.  When operating in
YUV overlay mode, the color must be programmed using YUV format.

Add the necessary RGB-to-YCbCr conversion logic, covering all color
spaces supported by the display controller: BT601L, BT601F, BT709L and
BT2020L.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>
---
Changes in v2:
- Used vop2_convert_csc_mode() helper to address an issue reported by
  vcstate->color_space holds a V4L2 colorspace enum
- Rebased onto latest drm-misc-next
- Link to v1: https://patch.msgid.link/20260524-vop2-bg-yuv-v1-0-dcb6a52923f5@collabora.com

To: Sandy Huang <hjc@rock-chips•com>
To: Heiko Stübner <heiko@sntech•de>
To: Andy Yan <andy.yan@rock-chips•com>
To: Maarten Lankhorst <maarten.lankhorst@linux•intel.com>
To: Maxime Ripard <mripard@kernel•org>
To: Thomas Zimmermann <tzimmermann@suse•de>
To: David Airlie <airlied@gmail•com>
To: Simona Vetter <simona@ffwll•ch>
Cc: kernel@collabora•com
Cc: dri-devel@lists•freedesktop.org
Cc: linux-arm-kernel@lists•infradead.org
Cc: linux-rockchip@lists•infradead.org
Cc: linux-kernel@vger•kernel.org
Sashiko: vop2_rgb16_to_yuv16() expects an enum vop_csc_format, but

---
Cristian Ciocaltea (2):
      drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L
      drm/rockchip: vop2: Add YUV support to background color

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 155 ++++++++++++++++++++++++---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |   2 +-
 2 files changed, 140 insertions(+), 17 deletions(-)
---
base-commit: e84b07e0a30b371117f9a1120a4645c213f39cd9
change-id: 20260524-vop2-bg-yuv-1b0e6a09c579



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L
  2026-06-01 18:00 [PATCH v2 0/2] YUV support for VOP2 background color Cristian Ciocaltea
@ 2026-06-01 18:00 ` Cristian Ciocaltea
  2026-06-02 13:25   ` Andy Yan
  2026-06-01 18:00 ` [PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color Cristian Ciocaltea
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Cristian Ciocaltea @ 2026-06-01 18:00 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

Rename CSC_BT2020 to CSC_BT2020L for consistency with the other
limited-range enum members (CSC_BT601L, CSC_BT709L) and to distinguish
it from a potential future full-range BT.2020 variant.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index a160077a507f..64ac07cb1b0d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -658,7 +658,7 @@ static int vop2_convert_csc_mode(int csc_mode)
 	case V4L2_COLORSPACE_JPEG:
 		return CSC_BT601F;
 	case V4L2_COLORSPACE_BT2020:
-		return CSC_BT2020;
+		return CSC_BT2020L;
 	default:
 		return CSC_BT709L;
 	}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 37722652844a..ffcb39c130aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -373,7 +373,7 @@ enum vop_csc_format {
 	CSC_BT601L,
 	CSC_BT709L,
 	CSC_BT601F,
-	CSC_BT2020,
+	CSC_BT2020L,
 };
 
 enum src_factor_mode {

-- 
2.54.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color
  2026-06-01 18:00 [PATCH v2 0/2] YUV support for VOP2 background color Cristian Ciocaltea
  2026-06-01 18:00 ` [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L Cristian Ciocaltea
@ 2026-06-01 18:00 ` Cristian Ciocaltea
  2026-06-02 13:25   ` Andy Yan
  2026-06-01 18:08 ` [PATCH v2 0/2] YUV support for VOP2 " Cristian Ciocaltea
  2026-06-02 18:47 ` Heiko Stuebner
  3 siblings, 1 reply; 7+ messages in thread
From: Cristian Ciocaltea @ 2026-06-01 18:00 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

The VOP2 background color must be programmed with 10-bit precision,
using YUV format when the overlay operates in YUV mode, and RGB
otherwise.

Add the required RGB-to-YCbCr conversion logic, covering all color
spaces supported by the display controller: BT601L, BT601F, BT709L and
BT2020L.

Since the color is currently programmed to hardware on every atomic
commit, minimize the computation cost by splitting the work across the
two paths: in atomic_enable(), perform the conversion unconditionally
(the hardware state is unknown after power-on), while in atomic_flush(),
perform it only when the DRM property has actually changed.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 153 ++++++++++++++++++++++++---
 1 file changed, 138 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 64ac07cb1b0d..9b261f0c7eec 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -728,6 +728,89 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
 	vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode);
 }
 
+/*
+ * RGB-to-YCbCr conversion based on color_to_ycbcr() and rgb2ycbcr() from
+ * drivers/media/common/v4l2-tpg/v4l2-tpg-core.c.
+ *
+ * Limited-range Y offset & chroma midpoint are expressed in 16-bit space.
+ */
+#define RGB2YUV_LIMITED_Y_OFFSET	(16 << 8)
+#define RGB2YUV_CHROMA_OFFSET		(128 << 8)
+#define COEFF(v, r)			((s32)(0.5 + (v) * (r) * 256.0))
+
+struct rgb2yuv_matrix {
+	s32 y_r,  y_g,  y_b;
+	s32 cb_r, cb_g, cb_b;
+	s32 cr_r, cr_g, cr_b;
+	s32 y_offset;
+};
+
+/* BT.601 Limited range */
+static const struct rgb2yuv_matrix rgb2yuv_bt601l = {
+	.y_r  = COEFF(0.299, 219),   .y_g  = COEFF(0.587, 219),   .y_b  = COEFF(0.114, 219),
+	.cb_r = COEFF(-0.1687, 224), .cb_g = COEFF(-0.3313, 224), .cb_b = COEFF(0.5, 224),
+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4187, 224), .cr_b = COEFF(-0.0813, 224),
+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
+};
+
+/* BT.601 Full range */
+static const struct rgb2yuv_matrix rgb2yuv_bt601f = {
+	.y_r  = COEFF(0.299, 255),   .y_g  = COEFF(0.587, 255),   .y_b  = COEFF(0.114, 255),
+	.cb_r = COEFF(-0.1687, 255), .cb_g = COEFF(-0.3313, 255), .cb_b = COEFF(0.5, 255),
+	.cr_r = COEFF(0.5, 255),     .cr_g = COEFF(-0.4187, 255), .cr_b = COEFF(-0.0813, 255),
+	.y_offset = 0,
+};
+
+/* BT.709 Limited range */
+static const struct rgb2yuv_matrix rgb2yuv_bt709l = {
+	.y_r  = COEFF(0.2126, 219),  .y_g  = COEFF(0.7152, 219),  .y_b  = COEFF(0.0722, 219),
+	.cb_r = COEFF(-0.1146, 224), .cb_g = COEFF(-0.3854, 224), .cb_b = COEFF(0.5, 224),
+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4542, 224), .cr_b = COEFF(-0.0458, 224),
+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
+};
+
+/* BT.2020 Limited range */
+static const struct rgb2yuv_matrix rgb2yuv_bt2020l = {
+	.y_r  = COEFF(0.2627, 219),  .y_g  = COEFF(0.6780, 219),  .y_b  = COEFF(0.0593, 219),
+	.cb_r = COEFF(-0.1396, 224), .cb_g = COEFF(-0.3604, 224), .cb_b = COEFF(0.5, 224),
+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4598, 224), .cr_b = COEFF(-0.0402, 224),
+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
+};
+
+static const struct rgb2yuv_matrix *
+vop2_rgb2yuv_get_matrix(enum vop_csc_format csc)
+{
+	switch (csc) {
+	case CSC_BT601L:
+		return &rgb2yuv_bt601l;
+	case CSC_BT601F:
+		return &rgb2yuv_bt601f;
+	case CSC_BT2020L:
+		return &rgb2yuv_bt2020l;
+	case CSC_BT709L:
+	default:
+		return &rgb2yuv_bt709l;
+	}
+}
+
+/* Convert an RGB (16bpc) to YUV444 (16bpc). */
+static void vop2_rgb16_to_yuv16(int v4l2_cs, u16 r, u16 g, u16 b,
+				u16 *y, u16 *cb, u16 *cr)
+{
+	enum vop_csc_format csc = vop2_convert_csc_mode(v4l2_cs);
+	const struct rgb2yuv_matrix *m = vop2_rgb2yuv_get_matrix(csc);
+	s64 rs = r, gs = g, bs = b;
+	s64 ys, cbs, crs;
+
+	ys  = m->y_r  * rs + m->y_g  * gs + m->y_b  * bs;
+	cbs = m->cb_r * rs + m->cb_g * gs + m->cb_b * bs;
+	crs = m->cr_r * rs + m->cr_g * gs + m->cr_b * bs;
+
+	*y  = (ys  >> 16) + m->y_offset;
+	*cb = (cbs >> 16) + RGB2YUV_CHROMA_OFFSET;
+	*cr = (crs >> 16) + RGB2YUV_CHROMA_OFFSET;
+}
+
 static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq)
 {
 	struct vop2 *vop2 = vp->vop2;
@@ -1554,12 +1637,58 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 				DITHER_DOWN_ALLEGRO);
 }
 
-static void vop2_post_config(struct drm_crtc *crtc)
+static void vop2_bgcolor_setup(struct drm_crtc *crtc, bool force,
+			       struct drm_crtc_state *new_crtc_state,
+			       struct drm_crtc_state *old_crtc_state)
+{
+	struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state);
+	struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state);
+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+	u64 bgcolor = new_crtc_state->background_color;
+	u16 y, cb, cr;
+	u32 val;
+
+	if (!force && old_crtc_state->background_color == bgcolor &&
+	    old_vcstate->color_space == new_vcstate->color_space)
+		return;
+
+	/*
+	 * Background color is programmed with 10 bits of precision, using YUV
+	 * format when operating in YUV overlay mode, and RGB otherwise.
+	 */
+	if (new_vcstate->yuv_overlay) {
+		vop2_rgb16_to_yuv16(new_vcstate->color_space,
+				    DRM_ARGB64_GETR(bgcolor),
+				    DRM_ARGB64_GETG(bgcolor),
+				    DRM_ARGB64_GETB(bgcolor),
+				    &y, &cb, &cr);
+
+		val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, cr >> 6);
+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, y >> 6);
+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, cb >> 6);
+	} else {
+		/*
+		 * Since performance is more important than accuracy here, make
+		 * use of the DRM_ARGB64_GET*_BPCS() helpers.
+		 */
+		val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED,
+				 DRM_ARGB64_GETR_BPCS(bgcolor, 10));
+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val,
+			     DRM_ARGB64_GETG_BPCS(bgcolor, 10));
+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val,
+			     DRM_ARGB64_GETB_BPCS(bgcolor, 10));
+	}
+
+	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
+}
+
+static void vop2_post_config(struct drm_crtc *crtc, bool force,
+			     struct drm_crtc_state *new_crtc_state,
+			     struct drm_crtc_state *old_crtc_state)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
-	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
-	u64 bgcolor = crtc->state->background_color;
+	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
@@ -1605,15 +1734,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
 		vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
 	}
 
-	/*
-	 * Background color is programmed with 10 bits of precision.
-	 * Since performance is more important than accuracy here,
-	 * make use of the DRM_ARGB64_GET*_BPCS() helpers.
-	 */
-	val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR_BPCS(bgcolor, 10));
-	FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, DRM_ARGB64_GETG_BPCS(bgcolor, 10));
-	FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, DRM_ARGB64_GETB_BPCS(bgcolor, 10));
-	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
+	vop2_bgcolor_setup(crtc, force, new_crtc_state, old_crtc_state);
 }
 
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
@@ -1628,8 +1749,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 	struct vop2 *vop2 = vp->vop2;
 	const struct vop2_data *vop2_data = vop2->data;
 	const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
+	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc_state);
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	unsigned long clock = mode->crtc_clock * 1000;
 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
@@ -1799,7 +1921,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	clk_set_rate(vp->dclk, clock);
 
-	vop2_post_config(crtc);
+	vop2_post_config(crtc, true, crtc_state, old_crtc_state);
 
 	vop2_cfg_done(vp);
 
@@ -1874,6 +1996,7 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
 				   struct drm_atomic_commit *state)
 {
 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
 
@@ -1881,7 +2004,7 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
 	if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
 		vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
 
-	vop2_post_config(crtc);
+	vop2_post_config(crtc, false, crtc_state, old_crtc_state);
 
 	vop2_cfg_done(vp);
 

-- 
2.54.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/2] YUV support for VOP2 background color
  2026-06-01 18:00 [PATCH v2 0/2] YUV support for VOP2 background color Cristian Ciocaltea
  2026-06-01 18:00 ` [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L Cristian Ciocaltea
  2026-06-01 18:00 ` [PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color Cristian Ciocaltea
@ 2026-06-01 18:08 ` Cristian Ciocaltea
  2026-06-02 18:47 ` Heiko Stuebner
  3 siblings, 0 replies; 7+ messages in thread
From: Cristian Ciocaltea @ 2026-06-01 18:08 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

Something got messed by while preparing the cover letter.
Fixed manually..

On 6/1/26 9:00 PM, Cristian Ciocaltea wrote:
> Since commit bec7cbfa7d4f ("drm/rockchip: vop2: Support setting custom
> background color") the VOP2 display controller allows configuring the
> background color of each video output port.
> 
> However, this is currently limited to RGB formats.  When operating in
> YUV overlay mode, the color must be programmed using YUV format.
> 
> Add the necessary RGB-to-YCbCr conversion logic, covering all color
> spaces supported by the display controller: BT601L, BT601F, BT709L and
> BT2020L.
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>
> ---
> Changes in v2:
> - Used vop2_convert_csc_mode() helper to address an issue reported by
>   Sashiko: vop2_rgb16_to_yuv16() expects an enum vop_csc_format, but
>   vcstate->color_space holds a V4L2 colorspace enum
> - Rebased onto latest drm-misc-next
> - Link to v1: https://patch.msgid.link/20260524-vop2-bg-yuv-v1-0-dcb6a52923f5@collabora.com
> 
> ---
> Cristian Ciocaltea (2):
>       drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L
>       drm/rockchip: vop2: Add YUV support to background color
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 155 ++++++++++++++++++++++++---
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |   2 +-
>  2 files changed, 140 insertions(+), 17 deletions(-)
> ---
> base-commit: e84b07e0a30b371117f9a1120a4645c213f39cd9
> change-id: 20260524-vop2-bg-yuv-1b0e6a09c579
> 



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re:[PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L
  2026-06-01 18:00 ` [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L Cristian Ciocaltea
@ 2026-06-02 13:25   ` Andy Yan
  0 siblings, 0 replies; 7+ messages in thread
From: Andy Yan @ 2026-06-02 13:25 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel


Hello Cristian,

At 2026-06-02 02:00:03, "Cristian Ciocaltea" <cristian.ciocaltea@collabora•com> wrote:
>Rename CSC_BT2020 to CSC_BT2020L for consistency with the other
>limited-range enum members (CSC_BT601L, CSC_BT709L) and to distinguish
>it from a potential future full-range BT.2020 variant.
>
>Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>
>---
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 +-
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index a160077a507f..64ac07cb1b0d 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -658,7 +658,7 @@ static int vop2_convert_csc_mode(int csc_mode)
> 	case V4L2_COLORSPACE_JPEG:
> 		return CSC_BT601F;
> 	case V4L2_COLORSPACE_BT2020:
>-		return CSC_BT2020;
>+		return CSC_BT2020L;
> 	default:
> 		return CSC_BT709L;
> 	}
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>index 37722652844a..ffcb39c130aa 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>@@ -373,7 +373,7 @@ enum vop_csc_format {
> 	CSC_BT601L,
> 	CSC_BT709L,
> 	CSC_BT601F,
>-	CSC_BT2020,
>+	CSC_BT2020L,
> };



  Acked-by: Andy Yan <andyshrk@163•com>


> 
> enum src_factor_mode {
>
>-- 
>2.54.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re:[PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color
  2026-06-01 18:00 ` [PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color Cristian Ciocaltea
@ 2026-06-02 13:25   ` Andy Yan
  0 siblings, 0 replies; 7+ messages in thread
From: Andy Yan @ 2026-06-02 13:25 UTC (permalink / raw)
  To: Cristian Ciocaltea
  Cc: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel


Hello,

At 2026-06-02 02:00:04, "Cristian Ciocaltea" <cristian.ciocaltea@collabora•com> wrote:
>The VOP2 background color must be programmed with 10-bit precision,
>using YUV format when the overlay operates in YUV mode, and RGB
>otherwise.
>
>Add the required RGB-to-YCbCr conversion logic, covering all color
>spaces supported by the display controller: BT601L, BT601F, BT709L and
>BT2020L.
>
>Since the color is currently programmed to hardware on every atomic
>commit, minimize the computation cost by splitting the work across the
>two paths: in atomic_enable(), perform the conversion unconditionally
>(the hardware state is unknown after power-on), while in atomic_flush(),
>perform it only when the DRM property has actually changed.
>
>Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora•com>


    Acked-by: Andy Yan <andyshrk@163•com>

    Thanks.

>---
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 153 ++++++++++++++++++++++++---
> 1 file changed, 138 insertions(+), 15 deletions(-)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index 64ac07cb1b0d..9b261f0c7eec 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -728,6 +728,89 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
> 	vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode);
> }
> 
>+/*
>+ * RGB-to-YCbCr conversion based on color_to_ycbcr() and rgb2ycbcr() from
>+ * drivers/media/common/v4l2-tpg/v4l2-tpg-core.c.
>+ *
>+ * Limited-range Y offset & chroma midpoint are expressed in 16-bit space.
>+ */
>+#define RGB2YUV_LIMITED_Y_OFFSET	(16 << 8)
>+#define RGB2YUV_CHROMA_OFFSET		(128 << 8)
>+#define COEFF(v, r)			((s32)(0.5 + (v) * (r) * 256.0))
>+
>+struct rgb2yuv_matrix {
>+	s32 y_r,  y_g,  y_b;
>+	s32 cb_r, cb_g, cb_b;
>+	s32 cr_r, cr_g, cr_b;
>+	s32 y_offset;
>+};
>+
>+/* BT.601 Limited range */
>+static const struct rgb2yuv_matrix rgb2yuv_bt601l = {
>+	.y_r  = COEFF(0.299, 219),   .y_g  = COEFF(0.587, 219),   .y_b  = COEFF(0.114, 219),
>+	.cb_r = COEFF(-0.1687, 224), .cb_g = COEFF(-0.3313, 224), .cb_b = COEFF(0.5, 224),
>+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4187, 224), .cr_b = COEFF(-0.0813, 224),
>+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
>+};
>+
>+/* BT.601 Full range */
>+static const struct rgb2yuv_matrix rgb2yuv_bt601f = {
>+	.y_r  = COEFF(0.299, 255),   .y_g  = COEFF(0.587, 255),   .y_b  = COEFF(0.114, 255),
>+	.cb_r = COEFF(-0.1687, 255), .cb_g = COEFF(-0.3313, 255), .cb_b = COEFF(0.5, 255),
>+	.cr_r = COEFF(0.5, 255),     .cr_g = COEFF(-0.4187, 255), .cr_b = COEFF(-0.0813, 255),
>+	.y_offset = 0,
>+};
>+
>+/* BT.709 Limited range */
>+static const struct rgb2yuv_matrix rgb2yuv_bt709l = {
>+	.y_r  = COEFF(0.2126, 219),  .y_g  = COEFF(0.7152, 219),  .y_b  = COEFF(0.0722, 219),
>+	.cb_r = COEFF(-0.1146, 224), .cb_g = COEFF(-0.3854, 224), .cb_b = COEFF(0.5, 224),
>+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4542, 224), .cr_b = COEFF(-0.0458, 224),
>+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
>+};
>+
>+/* BT.2020 Limited range */
>+static const struct rgb2yuv_matrix rgb2yuv_bt2020l = {
>+	.y_r  = COEFF(0.2627, 219),  .y_g  = COEFF(0.6780, 219),  .y_b  = COEFF(0.0593, 219),
>+	.cb_r = COEFF(-0.1396, 224), .cb_g = COEFF(-0.3604, 224), .cb_b = COEFF(0.5, 224),
>+	.cr_r = COEFF(0.5, 224),     .cr_g = COEFF(-0.4598, 224), .cr_b = COEFF(-0.0402, 224),
>+	.y_offset = RGB2YUV_LIMITED_Y_OFFSET,
>+};
>+
>+static const struct rgb2yuv_matrix *
>+vop2_rgb2yuv_get_matrix(enum vop_csc_format csc)
>+{
>+	switch (csc) {
>+	case CSC_BT601L:
>+		return &rgb2yuv_bt601l;
>+	case CSC_BT601F:
>+		return &rgb2yuv_bt601f;
>+	case CSC_BT2020L:
>+		return &rgb2yuv_bt2020l;
>+	case CSC_BT709L:
>+	default:
>+		return &rgb2yuv_bt709l;
>+	}
>+}
>+
>+/* Convert an RGB (16bpc) to YUV444 (16bpc). */
>+static void vop2_rgb16_to_yuv16(int v4l2_cs, u16 r, u16 g, u16 b,
>+				u16 *y, u16 *cb, u16 *cr)
>+{
>+	enum vop_csc_format csc = vop2_convert_csc_mode(v4l2_cs);
>+	const struct rgb2yuv_matrix *m = vop2_rgb2yuv_get_matrix(csc);
>+	s64 rs = r, gs = g, bs = b;
>+	s64 ys, cbs, crs;
>+
>+	ys  = m->y_r  * rs + m->y_g  * gs + m->y_b  * bs;
>+	cbs = m->cb_r * rs + m->cb_g * gs + m->cb_b * bs;
>+	crs = m->cr_r * rs + m->cr_g * gs + m->cr_b * bs;
>+
>+	*y  = (ys  >> 16) + m->y_offset;
>+	*cb = (cbs >> 16) + RGB2YUV_CHROMA_OFFSET;
>+	*cr = (crs >> 16) + RGB2YUV_CHROMA_OFFSET;
>+}
>+
> static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq)
> {
> 	struct vop2 *vop2 = vp->vop2;
>@@ -1554,12 +1637,58 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
> 				DITHER_DOWN_ALLEGRO);
> }
> 
>-static void vop2_post_config(struct drm_crtc *crtc)
>+static void vop2_bgcolor_setup(struct drm_crtc *crtc, bool force,
>+			       struct drm_crtc_state *new_crtc_state,
>+			       struct drm_crtc_state *old_crtc_state)
>+{
>+	struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state);
>+	struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state);
>+	struct vop2_video_port *vp = to_vop2_video_port(crtc);
>+	u64 bgcolor = new_crtc_state->background_color;
>+	u16 y, cb, cr;
>+	u32 val;
>+
>+	if (!force && old_crtc_state->background_color == bgcolor &&
>+	    old_vcstate->color_space == new_vcstate->color_space)
>+		return;
>+
>+	/*
>+	 * Background color is programmed with 10 bits of precision, using YUV
>+	 * format when operating in YUV overlay mode, and RGB otherwise.
>+	 */
>+	if (new_vcstate->yuv_overlay) {
>+		vop2_rgb16_to_yuv16(new_vcstate->color_space,
>+				    DRM_ARGB64_GETR(bgcolor),
>+				    DRM_ARGB64_GETG(bgcolor),
>+				    DRM_ARGB64_GETB(bgcolor),
>+				    &y, &cb, &cr);
>+
>+		val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, cr >> 6);
>+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, y >> 6);
>+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, cb >> 6);
>+	} else {
>+		/*
>+		 * Since performance is more important than accuracy here, make
>+		 * use of the DRM_ARGB64_GET*_BPCS() helpers.
>+		 */
>+		val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED,
>+				 DRM_ARGB64_GETR_BPCS(bgcolor, 10));
>+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val,
>+			     DRM_ARGB64_GETG_BPCS(bgcolor, 10));
>+		FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val,
>+			     DRM_ARGB64_GETB_BPCS(bgcolor, 10));
>+	}
>+
>+	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
>+}
>+
>+static void vop2_post_config(struct drm_crtc *crtc, bool force,
>+			     struct drm_crtc_state *new_crtc_state,
>+			     struct drm_crtc_state *old_crtc_state)
> {
> 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> 	struct vop2 *vop2 = vp->vop2;
>-	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
>-	u64 bgcolor = crtc->state->background_color;
>+	struct drm_display_mode *mode = &new_crtc_state->adjusted_mode;
> 	u16 vtotal = mode->crtc_vtotal;
> 	u16 hdisplay = mode->crtc_hdisplay;
> 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
>@@ -1605,15 +1734,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
> 		vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
> 	}
> 
>-	/*
>-	 * Background color is programmed with 10 bits of precision.
>-	 * Since performance is more important than accuracy here,
>-	 * make use of the DRM_ARGB64_GET*_BPCS() helpers.
>-	 */
>-	val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR_BPCS(bgcolor, 10));
>-	FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_GREEN, &val, DRM_ARGB64_GETG_BPCS(bgcolor, 10));
>-	FIELD_MODIFY(RK3568_VP_DSP_BG__DSP_BG_BLUE, &val, DRM_ARGB64_GETB_BPCS(bgcolor, 10));
>-	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
>+	vop2_bgcolor_setup(crtc, force, new_crtc_state, old_crtc_state);
> }
> 
> static int us_to_vertical_line(struct drm_display_mode *mode, int us)
>@@ -1628,8 +1749,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> 	struct vop2 *vop2 = vp->vop2;
> 	const struct vop2_data *vop2_data = vop2->data;
> 	const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
>+	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
> 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
>-	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
>+	struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc_state);
> 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
> 	unsigned long clock = mode->crtc_clock * 1000;
> 	u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
>@@ -1799,7 +1921,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
> 
> 	clk_set_rate(vp->dclk, clock);
> 
>-	vop2_post_config(crtc);
>+	vop2_post_config(crtc, true, crtc_state, old_crtc_state);
> 
> 	vop2_cfg_done(vp);
> 
>@@ -1874,6 +1996,7 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
> 				   struct drm_atomic_commit *state)
> {
> 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
>+	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
> 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
> 	struct vop2 *vop2 = vp->vop2;
> 
>@@ -1881,7 +2004,7 @@ static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
> 	if (!drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->color_mgmt_changed)
> 		vop2_crtc_atomic_try_set_gamma_locked(vop2, vp, crtc, crtc_state);
> 
>-	vop2_post_config(crtc);
>+	vop2_post_config(crtc, false, crtc_state, old_crtc_state);
> 
> 	vop2_cfg_done(vp);
> 
>
>-- 
>2.54.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/2] YUV support for VOP2 background color
  2026-06-01 18:00 [PATCH v2 0/2] YUV support for VOP2 background color Cristian Ciocaltea
                   ` (2 preceding siblings ...)
  2026-06-01 18:08 ` [PATCH v2 0/2] YUV support for VOP2 " Cristian Ciocaltea
@ 2026-06-02 18:47 ` Heiko Stuebner
  3 siblings, 0 replies; 7+ messages in thread
From: Heiko Stuebner @ 2026-06-02 18:47 UTC (permalink / raw)
  To: Sandy Huang, Andy Yan, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter,
	Cristian Ciocaltea
  Cc: Heiko Stuebner, kernel, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel


On Mon, 01 Jun 2026 21:00:02 +0300, Cristian Ciocaltea wrote:
> Since commit bec7cbfa7d4f ("drm/rockchip: vop2: Support setting custom
> background color") the VOP2 display controller allows configuring the
> background color of each video output port.
> 
> However, this is currently limited to RGB formats.  When operating in
> YUV overlay mode, the color must be programmed using YUV format.
> 
> [...]

Applied, thanks!

[1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L
      commit: 09dfa47fc557f945871dcf279c8e687e55d3550d
[2/2] drm/rockchip: vop2: Add YUV support to background color
      commit: 28e670a0885cf2501fd51189ce7b6f5b7cacebf9

Best regards,
-- 
Heiko Stuebner <heiko@sntech•de>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-02 18:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 18:00 [PATCH v2 0/2] YUV support for VOP2 background color Cristian Ciocaltea
2026-06-01 18:00 ` [PATCH v2 1/2] drm/rockchip: vop2: Rename CSC_BT2020 to CSC_BT2020L Cristian Ciocaltea
2026-06-02 13:25   ` Andy Yan
2026-06-01 18:00 ` [PATCH v2 2/2] drm/rockchip: vop2: Add YUV support to background color Cristian Ciocaltea
2026-06-02 13:25   ` Andy Yan
2026-06-01 18:08 ` [PATCH v2 0/2] YUV support for VOP2 " Cristian Ciocaltea
2026-06-02 18:47 ` Heiko Stuebner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox