[PATCH 2/4] drm/imx: ipuv3-plane: add the pixel blend mode property
Dmitry Baryshkov
dmitry.baryshkov at oss.qualcomm.com
Mon Aug 10 07:51:47 PDT 2026
All three IPUv3 planes advertise formats with an alpha channel, but none
of them ever created the "pixel blend mode" property, so userspace has no
way to learn how that alpha is interpreted. drm_mode_config_validate()
points this out once per plane at every boot:
WARNING: drivers/gpu/drm/drm_mode_config.c:872 at drm_mode_config_validate
[PLANE:35:plane-0] pixel format with alpha exposed but blend mode not setup
The DP blends the foreground over the background as
fg * alpha + bg * (1 - alpha), i.e. it consumes coverage alpha and has no
premultiplied mode. Planes that are not part of a DP flow have nothing to
blend against and ignore alpha entirely.
Create the property accordingly: PIXEL_NONE and COVERAGE for the DP
planes, PIXEL_NONE alone for the rest, and honour the resulting blend
mode when deciding between global and per-pixel alpha.
__drm_atomic_helper_plane_reset() defaults pixel_blend_mode to
PREMULTI unconditionally, so override it in the driver reset.
Fixes: e6245fc78b65 ("imx-drm: ipuv3-plane: allow local alpha in ipu_plane_mode_set()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
---
drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c | 43 +++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
index a0fd39eebbbc..bde5892264f4 100644
--- a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
@@ -291,8 +291,32 @@ void ipu_plane_disable_deferred(struct drm_plane *plane)
}
}
+static unsigned int ipu_plane_blend_modes(int dp_flow)
+{
+ if (dp_flow == IPU_DP_FLOW_SYNC_BG || dp_flow == IPU_DP_FLOW_SYNC_FG)
+ return BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+ BIT(DRM_MODE_BLEND_COVERAGE);
+
+ return BIT(DRM_MODE_BLEND_PIXEL_NONE);
+}
+
+static unsigned int ipu_plane_default_blend_mode(int dp_flow)
+{
+ if (dp_flow == IPU_DP_FLOW_SYNC_BG || dp_flow == IPU_DP_FLOW_SYNC_FG)
+ return DRM_MODE_BLEND_COVERAGE;
+
+ return DRM_MODE_BLEND_PIXEL_NONE;
+}
+
+static bool ipu_plane_use_pixel_alpha(struct drm_plane_state *state)
+{
+ return state->fb->format->has_alpha &&
+ state->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE;
+}
+
static void ipu_plane_state_reset(struct drm_plane *plane)
{
+ struct ipu_plane *ipu_plane = to_ipu_plane(plane);
struct ipu_plane_state *ipu_state;
if (plane->state) {
@@ -304,8 +328,12 @@ static void ipu_plane_state_reset(struct drm_plane *plane)
ipu_state = kzalloc_obj(*ipu_state);
- if (ipu_state)
+ if (ipu_state) {
__drm_atomic_helper_plane_reset(plane, &ipu_state->base);
+ /* the helper defaults to premultiplied, which the DP lacks */
+ ipu_state->base.pixel_blend_mode =
+ ipu_plane_default_blend_mode(ipu_plane->dp_flow);
+ }
}
static struct drm_plane_state *
@@ -593,8 +621,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
case IPU_DP_FLOW_SYNC_BG:
if (new_state->normalized_zpos == 1) {
ipu_dp_set_global_alpha(ipu_plane->dp,
- !fb->format->has_alpha, 0xff,
- true);
+ !ipu_plane_use_pixel_alpha(new_state),
+ 0xff, true);
} else {
ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
}
@@ -602,8 +630,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
case IPU_DP_FLOW_SYNC_FG:
if (new_state->normalized_zpos == 1) {
ipu_dp_set_global_alpha(ipu_plane->dp,
- !fb->format->has_alpha, 0xff,
- false);
+ !ipu_plane_use_pixel_alpha(new_state),
+ 0xff, false);
}
break;
}
@@ -930,6 +958,11 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
if (ret)
return ERR_PTR(ret);
+ ret = drm_plane_create_blend_mode_property(&ipu_plane->base,
+ ipu_plane_blend_modes(dp));
+ if (ret)
+ return ERR_PTR(ret);
+
ret = drm_plane_create_color_properties(&ipu_plane->base,
BIT(DRM_COLOR_YCBCR_BT601) |
BIT(DRM_COLOR_YCBCR_BT709),
--
2.47.3
More information about the linux-arm-kernel
mailing list