The Rockchip VOP2 display controller allows configuring the background
color of each video output port.
Since a previous patch introduced the BACKGROUND_COLOR CRTC property,
which defaults to solid black, make use of it when programming the
hardware.
Note the maximum precision allowed by the display controller is 10bpc,
while the alpha component is not supported, hence ignored.
Tested-by: Diederik de Haas <diederik@cknow-tech.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 17 ++++++++++++++++-
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 ++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index ec3b4fde10db..1cfd5e83e4da 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1552,6 +1552,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
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;
u16 vtotal = mode->crtc_vtotal;
u16 hdisplay = mode->crtc_hdisplay;
u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
@@ -1597,7 +1598,15 @@ static void vop2_post_config(struct drm_crtc *crtc)
vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
}
- vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
+ /*
+ * Background color is programmed with 10 bits of precision.
+ * Since performance is more important than accuracy here,
+ * do *not* make use of the DRM_ARGB64_GET*_BPC() helpers.
+ */
+ val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR(bgcolor) >> 6);
+ val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG(bgcolor) >> 6);
+ val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB(bgcolor) >> 6);
+ vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
}
static int us_to_vertical_line(struct drm_display_mode *mode, int us)
@@ -1983,6 +1992,10 @@ static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
drm_get_bus_format_name(vcstate->bus_format));
seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
seq_printf(s, " color_space[%d]\n", vcstate->color_space);
+ seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n",
+ DRM_ARGB64_GETR(cstate->background_color) >> 6,
+ DRM_ARGB64_GETG(cstate->background_color) >> 6,
+ DRM_ARGB64_GETB(cstate->background_color) >> 6);
seq_printf(s, " Display mode: %dx%d%s%d\n",
mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
drm_mode_vrefresh(mode));
@@ -2472,6 +2485,8 @@ static int vop2_create_crtcs(struct vop2 *vop2)
return dev_err_probe(drm->dev, ret,
"crtc init for video_port%d failed\n", i);
+ drm_crtc_attach_background_color_property(&vp->crtc);
+
drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
if (vop2->lut_regs) {
const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 9124191899ba..37722652844a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -658,6 +658,10 @@ enum dst_factor_mode {
#define RK3588_VP_CLK_CTRL__DCLK_OUT_DIV GENMASK(3, 2)
#define RK3588_VP_CLK_CTRL__DCLK_CORE_DIV GENMASK(1, 0)
+#define RK3568_VP_DSP_BG__DSP_BG_RED GENMASK(29, 20)
+#define RK3568_VP_DSP_BG__DSP_BG_GREEN GENMASK(19, 10)
+#define RK3568_VP_DSP_BG__DSP_BG_BLUE GENMASK(9, 0)
+
#define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN BIT(1)
#define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN BIT(0)
--
2.52.0
On Tue, Jan 27, 2026 at 10:45:36AM +0200, Cristian Ciocaltea wrote: > The Rockchip VOP2 display controller allows configuring the background > color of each video output port. > > Since a previous patch introduced the BACKGROUND_COLOR CRTC property, > which defaults to solid black, make use of it when programming the > hardware. > > Note the maximum precision allowed by the display controller is 10bpc, > while the alpha component is not supported, hence ignored. ... > + /* > + * Background color is programmed with 10 bits of precision. > + * Since performance is more important than accuracy here, > + * do *not* make use of the DRM_ARGB64_GET*_BPC() helpers. > + */ > + val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR(bgcolor) >> 6); > + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG(bgcolor) >> 6); > + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB(bgcolor) >> 6); There is FIELD_MODIFY() for a few cycles already. But here it probably makes no much difference. ... > + seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n", > + DRM_ARGB64_GETR(cstate->background_color) >> 6, > + DRM_ARGB64_GETG(cstate->background_color) >> 6, > + DRM_ARGB64_GETB(cstate->background_color) >> 6); Probably you want to have the alternative to the DRM_ARGB64_GETx() macros which incorporates a right-shift. But it all in regard to DRM style and preferences. -- With Best Regards, Andy Shevchenko
On 1/27/26 4:45 PM, Andy Shevchenko wrote: > On Tue, Jan 27, 2026 at 10:45:36AM +0200, Cristian Ciocaltea wrote: >> The Rockchip VOP2 display controller allows configuring the background >> color of each video output port. >> >> Since a previous patch introduced the BACKGROUND_COLOR CRTC property, >> which defaults to solid black, make use of it when programming the >> hardware. >> >> Note the maximum precision allowed by the display controller is 10bpc, >> while the alpha component is not supported, hence ignored. > > ... > >> + /* >> + * Background color is programmed with 10 bits of precision. >> + * Since performance is more important than accuracy here, >> + * do *not* make use of the DRM_ARGB64_GET*_BPC() helpers. >> + */ >> + val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR(bgcolor) >> 6); >> + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG(bgcolor) >> 6); >> + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB(bgcolor) >> 6); > > There is FIELD_MODIFY() for a few cycles already. I've been aware, but found it more appropriate when modifying an existing value (e.g. previously read from a register) rather than when computing one from scratch. > But here it probably makes no much difference. Thinking again about this, it is actually handy when keeping the first FIELD_PREP (for initialization), and using it just for the subsequent operations. Hence considered this approach in v6. > ... > >> + seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n", >> + DRM_ARGB64_GETR(cstate->background_color) >> 6, >> + DRM_ARGB64_GETG(cstate->background_color) >> 6, >> + DRM_ARGB64_GETB(cstate->background_color) >> 6); > > Probably you want to have the alternative to the DRM_ARGB64_GETx() macros which > incorporates a right-shift. But it all in regard to DRM style and preferences. I tried to keep the API as simple as possible, but you're right, it's better to have those macros rather than open-coding the bit-shift all over. Also handled in v6. Thanks again, Cristian
© 2016 - 2026 Red Hat, Inc.