From 49dd1228e649e6a0f97475b45aba251c29dba4c4 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Sep 2025 18:07:19 +0100 Subject: [PATCH 1/5] workflows: Increase timeout for toolchain install 5 minutes seems to be failing on a regular basis, so increase to 10. Signed-off-by: Dave Stevenson --- .github/workflows/kernel-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kernel-build.yml b/.github/workflows/kernel-build.yml index 1d879fb53712cd..8caa1da0324baa 100644 --- a/.github/workflows/kernel-build.yml +++ b/.github/workflows/kernel-build.yml @@ -67,7 +67,7 @@ jobs: else sudo apt-get install gcc-arm-linux-gnueabihf; fi - timeout-minutes: 5 + timeout-minutes: 10 - uses: actions/checkout@v4 with: From e90bee2f9ca83fb1fb897056423db070675ed81f Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 2 Sep 2025 12:27:56 +0300 Subject: [PATCH 2/5] drm: Add CRTC background color property Some display controllers can be hardware programmed to show non-black colors for pixels that are either not covered by any plane or are exposed through transparent regions of higher planes. This feature can help reduce memory bandwidth usage, e.g. in compositors managing a UI with a solid background color while using smaller planes to render the remaining content. To support this capability, introduce the BACKGROUND_COLOR standard DRM mode property, which can be attached to a CRTC through the drm_crtc_attach_background_color_property() helper function. Additionally, define a 64-bit ARGB format value to be built with the help of a dedicated drm_argb64() utility macro. Individual color components can be extracted with desired precision using the corresponding DRM_ARGB64_*() macros. Co-developed-by: Matt Roper Signed-off-by: Matt Roper Signed-off-by: Cristian Ciocaltea --- drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_atomic_uapi.c | 4 +++ drivers/gpu/drm/drm_blend.c | 37 ++++++++++++++++++++--- drivers/gpu/drm/drm_mode_config.c | 6 ++++ include/drm/drm_blend.h | 5 +-- include/drm/drm_crtc.h | 12 ++++++++ include/drm/drm_mode_config.h | 5 +++ include/uapi/drm/drm_mode.h | 30 ++++++++++++++++++ 8 files changed, 94 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index c7ff2123780650..d7ae49d332ffa9 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -74,6 +74,7 @@ __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state, struct drm_crtc *crtc) { crtc_state->crtc = crtc; + crtc_state->background_color = drm_argb64(0xffff, 0, 0, 0); } EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 4f8bf87c1949de..b5025cc66f8004 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -405,6 +405,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, &replaced); state->color_mgmt_changed |= replaced; return ret; + } else if (property == config->background_color_property) { + state->background_color = val; } else if (property == config->prop_out_fence_ptr) { s32 __user *fence_ptr = u64_to_user_ptr(val); @@ -450,6 +452,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->ctm) ? state->ctm->base.id : 0; else if (property == config->gamma_lut_property) *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + else if (property == config->background_color_property) + *val = state->background_color; else if (property == config->prop_out_fence_ptr) *val = 0; else if (property == crtc->scaling_filter_property) diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 4e63000713dbfd..70077e1034ba51 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -185,10 +185,6 @@ * plane does not expose the "alpha" property, then this is * assumed to be 1.0 * - * Note that all the property extensions described here apply either to the - * plane or the CRTC (e.g. for the background color, which currently is not - * exposed and assumed to be black). - * * SCALING_FILTER: * Indicates scaling filter to be used for plane scaler * @@ -201,6 +197,23 @@ * * Drivers can set up this property for a plane by calling * drm_plane_create_scaling_filter_property + * + * The property extensions described above all apply to the plane. Drivers + * may also expose the following crtc property extension: + * + * BACKGROUND_COLOR: + * Background color is set via drm_crtc_attach_background_color_property(). + * It controls the ARGB color of a full-screen layer that exists below all + * planes. This color will be used for pixels not covered by any plane and + * may also be blended with plane contents as allowed by a plane's alpha + * values. The background color defaults to black, and is assumed to be + * black for drivers that do not expose this property. Although background + * color isn't a plane, it is assumed that the color provided here + * undergoes the same pipe-level degamma/CSC/gamma transformations that + * planes undergo. Note that the color value provided here includes an + * alpha channel, hence non-opaque background color values are allowed, but + * are generally only honored in special cases (e.g. when a memory + * writeback connector is in use). */ /** @@ -648,3 +661,19 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane, return 0; } EXPORT_SYMBOL(drm_plane_create_blend_mode_property); + +/** + * drm_crtc_attach_background_color_property - attach background color property + * @crtc: drm crtc + * + * Attaches the background color property to @crtc. The property defaults to + * solid black and will accept 64-bit ARGB values in the format generated by + * drm_argb64(). + */ +void drm_crtc_attach_background_color_property(struct drm_crtc *crtc) +{ + drm_object_attach_property(&crtc->base, + crtc->dev->mode_config.background_color_property, + drm_argb64(0xffff, 0, 0, 0)); +} +EXPORT_SYMBOL(drm_crtc_attach_background_color_property); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index fdc44fd1c56d41..1a6c4c7395193d 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -365,6 +365,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create_range(dev, 0, + "BACKGROUND_COLOR", 0, U64_MAX); + if (!prop) + return -ENOMEM; + dev->mode_config.background_color_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, "IN_FORMATS", 0); diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index a84c58f3f13cdc..2599c27e09c3d3 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h @@ -31,8 +31,9 @@ #define DRM_MODE_BLEND_COVERAGE 1 #define DRM_MODE_BLEND_PIXEL_NONE 2 -struct drm_device; struct drm_atomic_state; +struct drm_crtc; +struct drm_device; struct drm_plane; struct drm_connector; @@ -59,7 +60,7 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, struct drm_atomic_state *state); int drm_plane_create_blend_mode_property(struct drm_plane *plane, unsigned int supported_modes); - +void drm_crtc_attach_background_color_property(struct drm_crtc *crtc); int drm_connector_create_rotation_property(struct drm_connector *conn, unsigned int rotation, unsigned int supported_rotations); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index dd7ad1a44717e8..a092c9c4550d6a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -274,6 +274,18 @@ struct drm_crtc_state { */ struct drm_property_blob *gamma_lut; + /** + * @background_color: + * + * RGB value representing the pipe's background color. The background + * color (aka "canvas color") of a pipe is the color that will be used + * for pixels not covered by a plane, or covered by transparent pixels + * of a plane. The value here should be built using drm_argb64(), while + * the individual color components can be extracted with desired + * precision via the DRM_ARGB64_*() macros. + */ + u64 background_color; + /** * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 271765e2e9f2da..735f3a5eb73aa2 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -813,6 +813,11 @@ struct drm_mode_config { * gamma LUT as supported by the driver (read-only). */ struct drm_property *gamma_lut_size_property; + /** + * @background_color_property: Optional CRTC property to set the + * background color. + */ + struct drm_property *background_color_property; /** * @suggested_x_property: Optional connector property with a hint for diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 563e337d55a508..5a81c9f14271cc 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -1356,6 +1356,36 @@ struct drm_mode_closefb { __u32 pad; }; +/* + * Put 16-bit ARGB values into a standard 64-bit representation that + * can be used for ioctl parameters, inter-driver communication, etc. + */ +static inline __u64 +drm_argb64(__u16 alpha, __u16 red, __u16 green, __u16 blue) +{ + return (__u64)alpha << 48 | (__u64)red << 32 | (__u64)green << 16 | blue; +} + +/* + * Extract the specified number of least-significant bits of a specific + * color component from a standard 64-bit ARGB value. + */ +#define DRM_ARGB64_COMP(c, shift, numlsb) \ + ((__u16)(((c) >> (shift)) & ((1UL << (numlsb) % 17) - 1))) +#define DRM_ARGB64_ALPHA_LSB(c, numlsb) DRM_ARGB64_COMP(c, 48, numlsb) +#define DRM_ARGB64_RED_LSB(c, numlsb) DRM_ARGB64_COMP(c, 32, numlsb) +#define DRM_ARGB64_GREEN_LSB(c, numlsb) DRM_ARGB64_COMP(c, 16, numlsb) +#define DRM_ARGB64_BLUE_LSB(c, numlsb) DRM_ARGB64_COMP(c, 0, numlsb) + +/* + * Convenience wrappers to extract all 16 bits of a specific color + * component from a standard 64-bit ARGB value. + */ +#define DRM_ARGB64_ALPHA(c) DRM_ARGB64_ALPHA_LSB(c, 16) +#define DRM_ARGB64_RED(c) DRM_ARGB64_RED_LSB(c, 16) +#define DRM_ARGB64_GREEN(c) DRM_ARGB64_GREEN_LSB(c, 16) +#define DRM_ARGB64_BLUE(c) DRM_ARGB64_BLUE_LSB(c, 16) + #if defined(__cplusplus) } #endif From 45643f558913e6aefcff690a272b6a40f9e7d1a7 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 2 Sep 2025 12:27:57 +0300 Subject: [PATCH 3/5] drm/rockchip: vop2: Support setting custom background color VOP2 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, take it into account when programming the hardware. Note that only the 10 least significant bits of each color component are used, as this is the maximum precision supported by the display controller. Signed-off-by: Cristian Ciocaltea --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 9 ++++++++- drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 5d7df4c3b08c47..bc6582f1193a69 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -1544,6 +1544,7 @@ static void vop2_post_config(struct drm_crtc *crtc) { struct vop2_video_port *vp = to_vop2_video_port(crtc); 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,11 @@ 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 */ + val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_RED(bgcolor)); + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GREEN(bgcolor)); + val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_BLUE(bgcolor)); + vop2_vp_write(vp, RK3568_VP_DSP_BG, val); } static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) @@ -2884,6 +2889,8 @@ static int vop2_create_crtcs(struct vop2 *vop2) return ret; } + drm_crtc_attach_background_color_property(&vp->crtc); + drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs); init_completion(&vp->dsp_hold_completion); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index 130aaa40316d13..45edf1fc72c711 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -421,6 +421,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) From 9868c201610d2c905f53df97881549a3c0833ac9 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Sep 2025 14:35:10 +0100 Subject: [PATCH 4/5] drm/vc4: crtc: Add support for a custom background color Since a previous patch introduced the BACKGROUND_COLOR CRTC property, which defaults to solid black, take it into account when programming the hardware. The exact registers used varies between the hardware generations, but is supported by all of them. Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_crtc.c | 3 +++ drivers/gpu/drm/vc4/vc4_hvs.c | 21 +++++++++++++++++++-- drivers/gpu/drm/vc4/vc4_regs.h | 10 +++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 307a533136692c..8a3eb29ef10de1 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1437,6 +1438,8 @@ int __vc4_crtc_init(struct drm_device *drm, if (ret) return ret; + drm_crtc_attach_background_color_property(crtc); + drm_crtc_helper_add(crtc, crtc_helper_funcs); if (vc4->gen == VC4_GEN_4) { diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 73680550bcef74..b2146a71a21e8c 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -1256,6 +1256,7 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); unsigned int channel = vc4_state->assigned_channel; + u64 bgcolor = crtc->state->background_color; struct drm_plane *plane; struct vc4_plane_state *vc4_plane_state; bool debug_dump_regs = false; @@ -1320,16 +1321,32 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm->mm_node.size); if (vc4->gen >= VC4_GEN_6_C) { - /* This sets a black background color fill, as is the case + /* This sets the background color fill, as is the case * with other DRM drivers. */ + if (vc4->gen == VC4_GEN_6_C) { + HVS_WRITE(SCALER6_DISPX_BGND(channel), + ((bgcolor & 0xFF0000000000) >> 24) | + ((bgcolor & 0xFF000000) >> 16) | + ((bgcolor & 0xFF00) >> 8)); + } else { + /* GEN_6_D takes a 12bit background colour */ + HVS_WRITE(SCALER6D_DISPX_BGND0(channel), + bgcolor & 0xFFF0FFF0); + HVS_WRITE(SCALER6D_DISPX_BGND1(channel), + (bgcolor >> 32) & 0xFFF0); + } hvs->bg_fill[channel] = enable_bg_fill; } else { /* we can actually run with a lower core clock when background * fill is enabled on VC4_GEN_5 so leave it enabled always. */ HVS_WRITE(SCALER_DISPBKGNDX(channel), - HVS_READ(SCALER_DISPBKGNDX(channel)) | + (HVS_READ(SCALER_DISPBKGNDX(channel)) & + ~SCALER_DISPBKGND_FILL_COLOUR) | + ((bgcolor & 0xFF0000000000) >> 24) | + ((bgcolor & 0xFF000000) >> 16) | + ((bgcolor & 0xFF00) >> 8) | SCALER_DISPBKGND_FILL); } diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 68d83d27c32ad9..2b043db306bd1c 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -402,6 +402,7 @@ * opaque display planes will cover everything. */ # define SCALER_DISPBKGND_FILL BIT(24) +# define SCALER_DISPBKGND_FILL_COLOUR VC4_MASK(23, 0) #define SCALER_DISPSTAT0 0x00000048 # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) @@ -580,9 +581,8 @@ # define SCALER6_DISPX_CTRL1_INTLACE BIT(0) #define SCALER6_DISP0_BGND 0x00000038 -#define SCALER6_DISPX_BGND(x) ((hvs->vc4->gen == VC4_GEN_6_C) ? \ - (SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND))) : \ - (SCALER6D_DISP0_BGND + ((x) * (SCALER6D_DISP1_BGND - SCALER6D_DISP0_BGND)))) +#define SCALER6_DISPX_BGND(x) \ + (SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND))) #define SCALER6_DISP0_LPTRS 0x0000003c #define SCALER6_DISPX_LPTRS(x) ((hvs->vc4->gen == VC4_GEN_6_C) ? \ @@ -707,7 +707,11 @@ #define SCALER6D_DISP0_CTRL0 0x00000100 #define SCALER6D_DISP0_CTRL1 0x00000104 #define SCALER6D_DISP0_BGND0 0x00000108 +#define SCALER6D_DISPX_BGND0(x) \ + (SCALER6D_DISP0_BGND0 + ((x) * (SCALER6D_DISP1_BGND0 - SCALER6D_DISP0_BGND0))) #define SCALER6D_DISP0_BGND1 0x0000010c +#define SCALER6D_DISPX_BGND1(x) \ + (SCALER6D_DISP0_BGND1 + ((x) * (SCALER6D_DISP1_BGND1 - SCALER6D_DISP0_BGND1))) #define SCALER6D_DISP0_LPTRS 0x00000110 #define SCALER6D_DISP0_COB 0x00000114 #define SCALER6D_DISP0_STATUS 0x00000118 From f34739fe5224a86a796f4bd32e19fb7aa397aa8e Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Sep 2025 16:22:45 +0100 Subject: [PATCH 5/5] drm/vc4: Remove duplicated defines for GEN_6D registers When adding the register definitions for the GEN_6D hardware, 6 defines managed to get added twice. Remove that duplication. Fixes: 3ca2940242a3 ("drm/vc4: hvs: Add in support for 2712 D-step.") Signed-off-by: Dave Stevenson --- drivers/gpu/drm/vc4/vc4_regs.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 2b043db306bd1c..afd3eda5aaf413 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -698,12 +698,6 @@ #define SCALER6D_HISTBIN7 0x000000f0 #define SCALER6D_HVS_ID 0x000000fc -#define SCALER6D_DISP0_CTRL0 0x00000100 -#define SCALER6D_DISP0_CTRL1 0x00000104 -#define SCALER6D_DISP0_BGND 0x00000108 -#define SCALER6D_DISP0_LPTRS 0x00000110 -#define SCALER6D_DISP0_COB 0x00000114 -#define SCALER6D_DISP0_STATUS 0x00000118 #define SCALER6D_DISP0_CTRL0 0x00000100 #define SCALER6D_DISP0_CTRL1 0x00000104 #define SCALER6D_DISP0_BGND0 0x00000108