From 337c7d29bb2d15a711dd1c7b313b3b8ba57c356d Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 3 Mar 2026 21:24:17 +0200 Subject: [PATCH 1/4] uapi: Provide DIV_ROUND_CLOSEST() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit de9e2b3d88af upstream. Currently DIV_ROUND_CLOSEST() is only available for the kernel via include/linux/math.h. Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as a common definition in uapi. Additionally, ensure it allows building ISO C applications by switching from the 'typeof' GNU extension to the ISO-friendly __typeof__. Reviewed-by: NĂ­colas F. R. A. Prado Tested-by: Diederik de Haas Acked-by: Andy Shevchenko Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Cristian Ciocaltea Link: https://patch.msgid.link/20260303-rk3588-bgcolor-v8-1-fee377037ad1@collabora.com Signed-off-by: Daniel Stone --- include/linux/math.h | 18 +----------------- include/uapi/linux/const.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/linux/math.h b/include/linux/math.h index 0198c92cbe3ef5..24bb868f971cf2 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -89,23 +89,7 @@ } \ ) -/* - * Divide positive or negative dividend by positive or negative divisor - * and round to closest integer. Result is undefined for negative - * divisors if the dividend variable type is unsigned and for negative - * dividends if the divisor variable type is unsigned. - */ -#define DIV_ROUND_CLOSEST(x, divisor)( \ -{ \ - typeof(x) __x = x; \ - typeof(divisor) __d = divisor; \ - (((typeof(x))-1) > 0 || \ - ((typeof(divisor))-1) > 0 || \ - (((__x) > 0) == ((__d) > 0))) ? \ - (((__x) + ((__d) / 2)) / (__d)) : \ - (((__x) - ((__d) / 2)) / (__d)); \ -} \ -) +#define DIV_ROUND_CLOSEST __KERNEL_DIV_ROUND_CLOSEST /* * Same as above but for u64 dividends. divisor must be a 32-bit * number. diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h index b8f629ef135f35..565f309b9df8b1 100644 --- a/include/uapi/linux/const.h +++ b/include/uapi/linux/const.h @@ -50,4 +50,22 @@ #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +/* + * Divide positive or negative dividend by positive or negative divisor + * and round to closest integer. Result is undefined for negative + * divisors if the dividend variable type is unsigned and for negative + * dividends if the divisor variable type is unsigned. + */ +#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor) \ +({ \ + __typeof__(x) __x = x; \ + __typeof__(divisor) __d = divisor; \ + \ + (((__typeof__(x))-1) > 0 || \ + ((__typeof__(divisor))-1) > 0 || \ + (((__x) > 0) == ((__d) > 0))) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ +}) + #endif /* _UAPI_LINUX_CONST_H */ From 1b33eee4ee86652f93668dc153bd53bd9bdb8456 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 3 Mar 2026 21:24:18 +0200 Subject: [PATCH 2/4] drm: Add CRTC background color property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 4c684596cde4 upstream. 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 couple of dedicated DRM_ARGB64_PREP*() helpers. Individual color components can be extracted with desired precision using the corresponding DRM_ARGB64_GET*() macros. Co-developed-by: Matt Roper Signed-off-by: Matt Roper Reviewed-by: NĂ­colas F. R. A. Prado Tested-by: Diederik de Haas Signed-off-by: Cristian Ciocaltea Link: https://patch.msgid.link/20260303-rk3588-bgcolor-v8-2-fee377037ad1@collabora.com Signed-off-by: Daniel Stone --- drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 1 + drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_blend.c | 39 +++++++++-- drivers/gpu/drm/drm_mode_config.c | 6 ++ include/drm/drm_blend.h | 4 +- include/drm/drm_crtc.h | 12 ++++ include/drm/drm_mode_config.h | 5 ++ include/uapi/drm/drm_mode.h | 80 +++++++++++++++++++++++ 9 files changed, 147 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 4e9a84db479b93..cef19351a411ee 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -453,6 +453,7 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask); drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask); drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode)); + drm_printf(p, "\tbackground_color=%llx\n", state->background_color); if (crtc->funcs->atomic_print_state) crtc->funcs->atomic_print_state(p, state); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index a6414a2c488e81..e62cca50875d50 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -75,6 +75,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_PREP(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 d1556527cca37b..adc75d821d1d36 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -407,6 +407,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); @@ -452,6 +454,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 e802c9f0331abf..ad8e52c0793981 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -191,10 +191,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 * @@ -207,6 +203,25 @@ * * 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 up with drm_crtc_attach_background_color_property(), + * and expects a 64-bit ARGB value following DRM_FORMAT_ARGB16161616, as + * generated by the DRM_ARGB64_PREP*() helpers. It controls the 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 + * CRTC degamma/CSC/gamma transformations applied after the planes blending. + * Note that the color value includes an alpha channel, hence non-opaque + * background color values are allowed, but since physically transparent + * monitors do not (yet) exists, the final alpha value may not reach the + * video sink or it may simply ignore it. */ /** @@ -654,3 +669,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_PREP*() helpers. + */ +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_PREP(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 cd0a81df3f335a..3e67bc06931d16 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -375,6 +375,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..87fbf64e664923 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,6 +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, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c85b9f6b94f152..ed7b1490a49ff1 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 CRTC's background color. The background + * color (aka "canvas color") of a CRTC 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_PREP*() + * helpers, while the individual color components can be extracted with + * desired precision via the DRM_ARGB64_GET*() macros. + */ + u64 background_color; + /** * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 2e848b81621858..ea422afec5c410 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -814,6 +814,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 6a04b6107614fe..dc5a4049df1d06 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -27,6 +27,9 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H +#include +#include + #include "drm.h" #if defined(__cplusplus) @@ -1364,6 +1367,83 @@ 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. + * + * If the component values being provided contain less than 16 bits of + * precision, use a conversion ratio to get a better color approximation. + * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are + * the input and output precision, respectively. + * Also note bpc must be greater than 0. + */ +#define __DRM_ARGB64_PREP(c, shift) \ + (((__u64)(c) & __GENMASK(15, 0)) << (shift)) + +#define __DRM_ARGB64_PREP_BPC(c, shift, bpc) \ +({ \ + __u16 mask = __GENMASK((bpc) - 1, 0); \ + __u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) * \ + __GENMASK(15, 0), mask);\ + __DRM_ARGB64_PREP(conv, shift); \ +}) + +#define DRM_ARGB64_PREP(alpha, red, green, blue) \ +( \ + __DRM_ARGB64_PREP(alpha, 48) | \ + __DRM_ARGB64_PREP(red, 32) | \ + __DRM_ARGB64_PREP(green, 16) | \ + __DRM_ARGB64_PREP(blue, 0) \ +) + +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc) \ +({ \ + __typeof__(bpc) __bpc = bpc; \ + __DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) | \ + __DRM_ARGB64_PREP_BPC(red, 32, __bpc) | \ + __DRM_ARGB64_PREP_BPC(green, 16, __bpc) | \ + __DRM_ARGB64_PREP_BPC(blue, 0, __bpc); \ +}) + +/* + * Extract the specified color component from a standard 64-bit ARGB value. + * + * If the requested precision is less than 16 bits, make use of a conversion + * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the + * output and input precision, respectively. + * + * If speed is more important than accuracy, use DRM_ARGB64_GET*_BPCS() + * instead of DRM_ARGB64_GET*_BPC() in order to replace the expensive + * division with a simple bit right-shift operation. + */ +#define __DRM_ARGB64_GET(c, shift) \ + ((__u16)(((__u64)(c) >> (shift)) & __GENMASK(15, 0))) + +#define __DRM_ARGB64_GET_BPC(c, shift, bpc) \ +({ \ + __u16 comp = __DRM_ARGB64_GET(c, shift); \ + __KERNEL_DIV_ROUND_CLOSEST(comp * __GENMASK((bpc) - 1, 0), \ + __GENMASK(15, 0)); \ +}) + +#define __DRM_ARGB64_GET_BPCS(c, shift, bpc) \ + (__DRM_ARGB64_GET(c, shift) >> (16 - (bpc))) + +#define DRM_ARGB64_GETA(c) __DRM_ARGB64_GET(c, 48) +#define DRM_ARGB64_GETR(c) __DRM_ARGB64_GET(c, 32) +#define DRM_ARGB64_GETG(c) __DRM_ARGB64_GET(c, 16) +#define DRM_ARGB64_GETB(c) __DRM_ARGB64_GET(c, 0) + +#define DRM_ARGB64_GETA_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 48, bpc) +#define DRM_ARGB64_GETR_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 32, bpc) +#define DRM_ARGB64_GETG_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 16, bpc) +#define DRM_ARGB64_GETB_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 0, bpc) + +#define DRM_ARGB64_GETA_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 48, bpc) +#define DRM_ARGB64_GETR_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 32, bpc) +#define DRM_ARGB64_GETG_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 16, bpc) +#define DRM_ARGB64_GETB_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 0, bpc) + #if defined(__cplusplus) } #endif From 031f6522470d5652258740d6cf046ca284bcf0af Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Sep 2025 16:22:45 +0100 Subject: [PATCH 3/4] 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 68d83d27c32ad9..2ce8a4f4a70c5d 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 From b5fbae3e4c0aba5e8efba74bd2a55d2821c63a2e Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Tue, 2 Sep 2025 14:35:10 +0100 Subject: [PATCH 4/4] 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 | 35 ++++++++++++++++++++++++++++++++-- drivers/gpu/drm/vc4/vc4_regs.h | 34 ++++++++++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 5ce7ad53e184a3..64265651dbb2e0 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 @@ -1434,6 +1435,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 9f7cff04a6ef12..4ae905855bb466 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,46 @@ 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), + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_BLUE) | + VC4_SET_FIELD(DRM_ARGB64_GETA_BPCS(bgcolor, 8), + SCALER6_DISPX_BGND_FILL_ALPHA)); + } else { + /* GEN_6_D takes a 12bit background colour */ + HVS_WRITE(SCALER6D_DISPX_BGND0(channel), + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND0_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND0_FILL_BLUE)); + HVS_WRITE(SCALER6D_DISPX_BGND1(channel), + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND1_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETA_BPCS(bgcolor, 12), + SCALER6D_DISPX_BGND1_FILL_ALPHA)); + } 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_MASK) | + VC4_SET_FIELD(DRM_ARGB64_GETR_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_RED) | + VC4_SET_FIELD(DRM_ARGB64_GETG_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_GREEN) | + VC4_SET_FIELD(DRM_ARGB64_GETB_BPCS(bgcolor, 8), + SCALER_DISPBKGND_FILL_BLUE) | SCALER_DISPBKGND_FILL); } diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 2ce8a4f4a70c5d..c4387459046838 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -402,6 +402,15 @@ * opaque display planes will cover everything. */ # define SCALER_DISPBKGND_FILL BIT(24) +# define SCALER_DISPBKGND_FILL_RED_MASK VC4_MASK(23, 16) +# define SCALER_DISPBKGND_FILL_RED_SHIFT 16 +# define SCALER_DISPBKGND_FILL_GREEN_MASK VC4_MASK(15, 8) +# define SCALER_DISPBKGND_FILL_GREEN_SHIFT 8 +# define SCALER_DISPBKGND_FILL_BLUE_MASK VC4_MASK(7, 0) +# define SCALER_DISPBKGND_FILL_BLUE_SHIFT 0 +# define SCALER_DISPBKGND_FILL_MASK (SCALER_DISPBKGND_FILL_RED_MASK | \ + SCALER_DISPBKGND_FILL_GREEN_MASK | \ + SCALER_DISPBKGND_FILL_BLUE_MASK) #define SCALER_DISPSTAT0 0x00000048 # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) @@ -580,9 +589,16 @@ # 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_DISPX_BGND_FILL_ALPHA_MASK VC4_MASK(31, 24) +# define SCALER6_DISPX_BGND_FILL_ALPHA_SHIFT 24 +# define SCALER6_DISPX_BGND_FILL_RED_MASK VC4_MASK(23, 16) +# define SCALER6_DISPX_BGND_FILL_RED_SHIFT 16 +# define SCALER6_DISPX_BGND_FILL_GREEN_MASK VC4_MASK(15, 8) +# define SCALER6_DISPX_BGND_FILL_GREEN_SHIFT 8 +# define SCALER6_DISPX_BGND_FILL_BLUE_MASK VC4_MASK(7, 0) +# define SCALER6_DISPX_BGND_FILL_BLUE_SHIFT 0 #define SCALER6_DISP0_LPTRS 0x0000003c #define SCALER6_DISPX_LPTRS(x) ((hvs->vc4->gen == VC4_GEN_6_C) ? \ @@ -701,7 +717,19 @@ #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_DISPX_BGND0_FILL_GREEN_MASK VC4_MASK(31, 20) +# define SCALER6D_DISPX_BGND0_FILL_GREEN_SHIFT 20 +# define SCALER6D_DISPX_BGND0_FILL_BLUE_MASK VC4_MASK(15, 4) +# define SCALER6D_DISPX_BGND0_FILL_BLUE_SHIFT 4 #define SCALER6D_DISP0_BGND1 0x0000010c +#define SCALER6D_DISPX_BGND1(x) \ + (SCALER6D_DISP0_BGND1 + ((x) * (SCALER6D_DISP1_BGND1 - SCALER6D_DISP0_BGND1))) +# define SCALER6D_DISPX_BGND1_FILL_ALPHA_MASK VC4_MASK(31, 20) +# define SCALER6D_DISPX_BGND1_FILL_ALPHA_SHIFT 20 +# define SCALER6D_DISPX_BGND1_FILL_RED_MASK VC4_MASK(15, 4) +# define SCALER6D_DISPX_BGND1_FILL_RED_SHIFT 4 #define SCALER6D_DISP0_LPTRS 0x00000110 #define SCALER6D_DISP0_COB 0x00000114 #define SCALER6D_DISP0_STATUS 0x00000118