From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D8302EA749 for ; Sat, 8 Aug 2026 09:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786183112; cv=none; b=SC1uxJyq273/ONS3PmDMHyoarXav3vptb5tu2BXokSJkWZkVS0rq2C/re72XDyW/P4i3qkgFvGDaPFizidru+QMHR8eaqvwGT6ER/2BoxcUZ79oZNvZZRHvh+tYw3E2Y94WgtWBTLDHO1D886IZXepRkxQBAM37BJNhdwVODQwY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786183112; c=relaxed/simple; bh=neOKnZeyhSU1ZqTloSCJaeMqY0+mXHUwjgndvrH98O0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HJ5LxXZaqE4n34sRHJIZK9DmDCqjZgfziCxsBjvl9Eii+7HedvbJLFVwHJR3InN1s3UZ+/XMMcSU2tXfxaYB9csQNTm5+50L4zyWyGISbsjZgIoBPFSBSGjYIsOWDvIb2RlX47Q7fGVhTL++2d2Eu/U6oQ2xH/hoeY5lz59oDG4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mA8UHM1c; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mA8UHM1c" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-47f611b3af9so39229f8f.3 for ; Sat, 08 Aug 2026 02:58:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786183107; x=1786787907; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=eukZ4Yw0lPupGVKUZsE6QR5EVi6K7EEsCGMJTKxA3Qg=; b=mA8UHM1cnWJYtrRrV7vv/Bx7Nrigk7+tgJDKBIH5PnYE5AkaNa1iO5CLgjgvzsNH8O MYVAiUJJ4J5c3EE4fUZQhe8BlpHPcdtYaDMLq9ov21Rjod3NUnpaq1fSSliFq+y3ZXhP 6cdJA07nfBX4zYOx+UCBhSq8caZOHeB+juh1PahYMN8C/8Die3N20Lbi0ozvWDSU2k23 Ff3Wu8/sSLaXQtY4qPwiW7SZ5xUtomQl74IPQnJ4uirfUtcRy6uNFLq7GE3/Jz5klB0Y ucea5SPEL8PBvRaDQNuDvGd3nU+VK8ki78NRH8Z9oOjrLb76bQl5KBjJmBbMvHiO0ceo ++Yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786183107; x=1786787907; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=eukZ4Yw0lPupGVKUZsE6QR5EVi6K7EEsCGMJTKxA3Qg=; b=gvhkiBfajnzep17ZgNk8t94/RVd6Ta039xaNR3mtAaSH5cGocd1sES7a2igVDc6YKi +ebSxYpT+njCtg0zqUCr6H2cLEArXS983RvAgrdKj2ybdZvE5Ry8SoPtsaSRF89iGM2Q +r/ET6FJ8BJoorHyvzCmFjoQz1U+HWFxZDM3M7XVrKsjYs5z0gRMgKfWC+GEgZxnMlPp MHBeT7OiOI3x3ZlNrW9TnjGaJOWiuc6QDEG4iGNzAIWpDejTVP07xgCGiwgksl1Blbl0 WnGhL1dku3LWIDp1yPo0WvECc+kt2b5+Q5zPPeFlgvnetKtBWtVSW68vdrzshvZow3Vo vU9Q== X-Forwarded-Encrypted: i=1; AHgh+RoTBHCCxtyujCDUIj9aX1UawOBLz+JpyCKBK7JGhSrE80rE0vq1ITxUCUUvRZ4WURqskkzMz0b7QR+QioM=@vger.kernel.org X-Gm-Message-State: AOJu0Yysn4itHcE2yAnQcLO6x/v8+Lp2Zs5tESAazUzdU78D/2sz1d2j j4ZoeAhxQ7d6eng84kW20iuwvCC+rpPVXSGcypS+s4QDUXGdHEAvKcJA X-Gm-Gg: AR+sD11JM1J4HiQB1l+Tu207fxNSnfcoj25x4k0TQhIcy8OXq8nYd29zpcHKrd6Yq3r X/U+Kdfn2nUuyTk2HHrE/9fS5hO+T1XjE8hzIVsZHx4nnmfc5hz4ne3S6pkbOF3luegK2aKpf8X YAJau8cmCD3NB/BT1/KhCxDgFKQ6l9CGM7qNxppuaq27+UfZkupoLKyiH1YKUgAO4JTWqs7NgdR 2/DAAAyeri3VFMJqYcFsILsNKZMrL11CLli4TV5GVCtYltcOLNBWz4Eor7BFoxK7fvwBrW+WDqT /eArx+OsPmXQuAAgus03j6QQ7DNpy+X8iFPA0LR9oNHeNM7iNlB94BOGhidQrGN6Qse0whWqLSi CKFpuaWZfCqrk9yFGk1eepRqnPSb9y1t1nbesLTU6wE3tcKBlsvsu0YUT2u3XrLAxdpfaSFlHZs EF4+tKg2Btr/Tl7NGLFQBvIiex7CLs8IpKyQ9mUGCxYL6QdY9MhjyQxu9bUnFYYpEsxCXj3x4R0 l2KT7OhVyJ3mSqLNvAsTrI2g47U0jOeczSmSrBfymb6OZnoInsI6gmn3rd6Tu/L1UGBD954Ands qv80VA== X-Received: by 2002:a5d:584c:0:b0:47f:959f:d5e with SMTP id ffacd0b85a97d-47fec487b60mr22022705f8f.0.1786183107204; Sat, 08 Aug 2026 02:58:27 -0700 (PDT) Received: from OrangePi5-Plus.BB-HOME (20014C4E1B8E20009911270F4BEC2300.dsl.pool.telekom.hu. [2001:4c4e:1b8e:2000:9911:270f:4bec:2300]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-480020be8f3sm13255725f8f.0.2026.08.08.02.58.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Aug 2026 02:58:26 -0700 (PDT) From: Igor Paunovic To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Sebastian Reichel , Cristian Ciocaltea , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Dmitry Baryshkov , Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Imre Deak , Ankit Nautiyal , Igor Paunovic Subject: [PATCH 5/5] drm/bridge: synopsys: dw-dp: Add BT.2020 colorimetry support Date: Sat, 8 Aug 2026 11:57:24 +0200 Message-ID: <20260808095749.9428-6-royalnet026@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260808095749.9428-1-royalnet026@gmail.com> References: <20260808095749.9428-1-royalnet026@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The VSC SDP colorimetry is hardcoded: DEFAULT for RGB output and BT709_YCC for YCbCr. HDR compositors render into a BT.2020 container and need a way to tell the sink. The legacy MSA MISC0 colorimetry bits cannot express BT.2020; DP 1.4a requires the VSC SDP revision 5 pixel encoding/colorimetry format indication, with MISC1 bit 6 set so the sink takes the format from the VSC SDP instead of MISC0. The driver already sets MISC1 bit 6 whenever it sends the VSC SDP, so only the trigger and the colorimetry values need extending: - store conn_state->colorspace in the bridge state during atomic_check(), next to the negotiated format; - send the VSC SDP also when the colorspace is BT2020_RGB or BT2020_YCC, not only for YCbCr 4:2:0 output; - map BT2020_RGB/BT2020_YCC to DP_COLORIMETRY_BT2020_RGB/ DP_COLORIMETRY_BT2020_YCC in the VSC SDP; every other colorspace value keeps today's values. The dynamic range stays VESA for RGB and CTA for YCbCr output. Sinks advertise VSC SDP colorimetry support in the DPCD (DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED). Without it BT.2020 cannot be signaled at all, so atomic_check() rejects such a request with -EINVAL and userspace's TEST_ONLY probe learns the configuration is impossible; i915 instead silently omits the VSC SDP and scans out BT.2020 pixels without signaling them. A colorspace change on a live stream forces a modeset, so the VSC SDP is regenerated with the new colorimetry. On the Rockchip side, create the DP Colorspace property with exactly the enum values the driver implements (Default, BT2020_RGB, BT2020_YCC). When the colorspace is BT.2020 and the negotiated bus format is YCbCr, program s->color_space = V4L2_COLORSPACE_BT2020 so the VOP2 uses its BT.2020 R'G'B' to Y'C'bC'r matrix for the CSC. For RGB output the pixels leave the VOP2 unconverted and the color space stays DEFAULT. Userspace that leaves the property at "Default" sees no change in behavior: the colorimetry mapping, the VSC SDP trigger and the VOP2 CSC selection all take the previous paths. Signed-off-by: Igor Paunovic --- drivers/gpu/drm/bridge/synopsys/dw-dp.c | 44 +++++++++++++++++++---- drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 38 +++++++++++++++++++- 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c index ca997ea53e66..8f0ee9628dcc 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c @@ -306,6 +306,7 @@ struct dw_dp_bridge_state { u8 color_format; u8 bpc; u8 bpp; + enum drm_colorspace colorspace; }; struct dw_dp_sdp { @@ -1125,6 +1126,12 @@ static void dw_dp_clear_sdp(struct dw_dp *dp, int nr) clear_bit(nr, dp->sdp_reg_bank); } +static bool dw_dp_colorspace_is_bt2020(enum drm_colorspace colorspace) +{ + return colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB || + colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC; +} + static int dw_dp_send_vsc_sdp(struct dw_dp *dp) { struct dw_dp_bridge_state *state; @@ -1160,13 +1167,25 @@ static int dw_dp_send_vsc_sdp(struct dw_dp *dp) break; } - if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444) { - vsc.colorimetry = DP_COLORIMETRY_DEFAULT; + switch (state->colorspace) { + case DRM_MODE_COLORIMETRY_BT2020_RGB: + vsc.colorimetry = DP_COLORIMETRY_BT2020_RGB; + break; + case DRM_MODE_COLORIMETRY_BT2020_YCC: + vsc.colorimetry = DP_COLORIMETRY_BT2020_YCC; + break; + default: + if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444) + vsc.colorimetry = DP_COLORIMETRY_DEFAULT; + else + vsc.colorimetry = DP_COLORIMETRY_BT709_YCC; + break; + } + + if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_RGB444) vsc.dynamic_range = DP_DYNAMIC_RANGE_VESA; - } else { - vsc.colorimetry = DP_COLORIMETRY_BT709_YCC; + else vsc.dynamic_range = DP_DYNAMIC_RANGE_CTA; - } drm_dp_vsc_sdp_pack(&vsc, &sdp.base); @@ -1227,7 +1246,7 @@ static bool dw_dp_video_need_vsc_sdp(struct dw_dp *dp) if (state->color_format == DRM_OUTPUT_COLOR_FORMAT_YCBCR420) return true; - return false; + return dw_dp_colorspace_is_bt2020(state->colorspace); } static int dw_dp_video_set_msa(struct dw_dp *dp, @@ -1644,10 +1663,21 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, state->color_format = fmt->color_format; state->bpc = fmt->bpc; state->bpp = fmt->bpp; + state->colorspace = conn_state->colorspace; + + /* + * BT.2020 cannot be signaled through the legacy MSA MISC0 + * colorimetry bits; it requires the VSC SDP colorimetry format + * indication, which the sink must support. + */ + if (dw_dp_colorspace_is_bt2020(conn_state->colorspace) && + !dp->link.vsc_sdp_supported) + return -EINVAL; old_conn_state = drm_atomic_get_old_connector_state(conn_state->state, conn_state->connector); - if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state)) + if (!drm_connector_atomic_hdr_metadata_equal(old_conn_state, conn_state) || + old_conn_state->colorspace != conn_state->colorspace) crtc_state->mode_changed = true; if ((adjusted_mode->hsync_start - adjusted_mode->hdisplay) & 0x1) { diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c index c5bc178c0a50..798d82893f98 100644 --- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c @@ -69,6 +69,21 @@ static void dw_dp_rockchip_hpd_sw_cfg(void *data, bool hpd) FIELD_PREP_WM16(ROCKCHIP_VO_GRF_DP_SINK_HPD_CFG, hpd)); } +static bool dw_dp_yuv_bus_format(u32 bus_format) +{ + switch (bus_format) { + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUV10_1X30: + case MEDIA_BUS_FMT_YUV8_1X24: + return true; + default: + return false; + } +} + static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -102,7 +117,17 @@ static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder, s->output_type = DRM_MODE_CONNECTOR_DisplayPort; s->bus_format = bus_format; s->bus_flags = di->bus_flags; - s->color_space = V4L2_COLORSPACE_DEFAULT; + + /* + * For BT.2020 YCbCr output the VOP2 must use its BT.2020 R'G'B' to + * Y'C'bC'r matrix; BT.2020 RGB is passed through unconverted. + */ + if ((conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB || + conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC) && + dw_dp_yuv_bus_format(bus_format)) + s->color_space = V4L2_COLORSPACE_BT2020; + else + s->color_space = V4L2_COLORSPACE_DEFAULT; return 0; } @@ -200,6 +225,17 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void * drm_connector_attach_hdr_output_metadata_property(connector); + ret = drm_mode_create_dp_colorspace_property(connector, + BIT(DRM_MODE_COLORIMETRY_DEFAULT) | + BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | + BIT(DRM_MODE_COLORIMETRY_BT2020_YCC)); + if (ret) { + dw_dp_unbind(dp->base); + return ret; + } + + drm_connector_attach_colorspace_property(connector); + return 0; } -- 2.43.0