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 04ECA3B19D4 for ; Sat, 8 Aug 2026 09:58:26 +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=1786183110; cv=none; b=pH5VTLep7y0H79eeiVNLd33ge6drhQD4Lza2lmnKRIXnZ2kDsjZBRlKvyMuYV3wgDKo32SC2PIFZXAhx74a/TAjkU+1jXOrX0v/aQtZtWMnt+pNEpt0kVDolgY7XEaL+0R4Fwq4i/TWMHGr261YKSzKb5dLWSDvjF40f76uheWM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786183110; c=relaxed/simple; bh=F29hNm/khAlsS3KtPOWxd7Sj1ngKO72eAoIKK4X03FI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OX9Xg3c/21QhwFELJFwh1rVfB9PCB5AxnzATrZHqPL+JaZfK/8gvUMbfhfwTWZ+6fua4iDVvJqUllt++Bj5UyvgByIkYPXHPRxwf566s7TQFprun8rh/olaTXiGZMiSwGQSXEL8uCiDwA3Ttjei2Rq3kRp0G/ycZLOe1i63pst8= 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=FBiG79BW; 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="FBiG79BW" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-47fe45db360so32586f8f.2 for ; Sat, 08 Aug 2026 02:58:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786183105; x=1786787905; 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=78pbQXQC7rS+xYT3KOYvmzHciozgKbUx+FycpcHfTyI=; b=FBiG79BWNPXo4Le7+BsLjNHJEIcdtS7WifTIza8oN0muJ8qerOqyoBOdMHRF6L5lLM okmV6Ukl7xVl8EXDt7KfwazppRDlCP3SeObvdfxzmaz73sdGGR4ULh6gbAa762f1hszr Xfj8Sk7Q2tBJiRMD9h5f95e4TejRdJryVAFRLiM3pq99Go2E0EdYg6qJzoF/2QrOTt+m ejQQhKxIokuW5i7H8PjJC7RaXNq25RuOYxum2VtLtDiH4W97B/NCTJnHuplSsBfvE81N 8aaT3B+3SJo6P8T/bDd/0CeBGy0xayPFX/8erxs7rtLUKkwvE15kYy/MqbWkkXM8c04k B06g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786183105; x=1786787905; 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=78pbQXQC7rS+xYT3KOYvmzHciozgKbUx+FycpcHfTyI=; b=CK6Jpe7gtlVWNF3v0zmbEXq7EhyN2YAbNAgYK2AUyr/rhw0mj7AI9cmVBEmXM57rU5 VHhLiMI8sNDclHc+biJSgs09/YbkNrtZmi99ClSWkYfT6R5oqn/gYK7WCHCt9GNM4F7Z Joa7Iep08fMgx7hiHWgsVDuR5CKaFp4+jxE/Pz1wIOS720FbfQ7zuWPo0Vz7klBIqeFu 2hY8ywPmKf4rJcUhEDIa6y2KK7L84szg7wnqXbxJZlugfjmtdDcRaEEoISTjtJ5Trz0f W5mUre20vg0Ux6VBaz0jKe0G7a6CKFLlb+WAEtbMDdxH3S0VvnWFdfFczBb+pXkM8cS6 7RtA== X-Forwarded-Encrypted: i=1; AHgh+RruarAJkSLgR+XH2nr/t27JaBVF0LPtxIbwtIjCIbO2AVik3stx3sOG1e8rWunHVd3tN+ctzuT/c+k0aEQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yw9j9lFoMoMt97omng4oOaamEYvlWws07nZYhqvTSv0q8B0JqvW 1Hcss1JvcO9zLeNttxEjJF5e6lhWsCS9LQQnzJGDxhn0bknWnRK5ryYO X-Gm-Gg: AR+sD11oYsiFLidOvbwqsIhaFrsOTnCEHIphfAfkJyoLrGJV6q+byJp400Q/lpEi4fs /wcGg2432hdLt0/kve4eDoKh8dB8fiQ/5kC+Ya4FirNdv7c56i1LBVpPZY5Vbbkk7abZoJfOg0I IHqhKwBBTK0xERw2J4mSJMh/GEqls7ESdLZLG4etFYbZlSyOacvWjcoziu9puPqxS4Oiw6yY4xr cam4DV1EGASON+NS1OLYXBALjFdRzXsGA0ojdBrPRanAF73R4SjZWslIOW7cKvmyfLtpfj2xTvy zJyyWW5h3HRi+ynB82rCjKdHrroQQgQoxx0r4fvrdoBuBDdLah+IOFFd3DEVxgCIkRVOyhsexvo jPbIaCi3HaD7VURkEdT1/TaFpPp6MCsVftVLP9w/bT3f8dZokSoFoQDtNrJJv0G52K/OnJCusgt CxV5BUck8F6FipQb0PYUQZPM8w1Rz9uVpDPhfnj24Ipwja/fT77r6OpvWY3TcM4g73ACHeHNDv7 /AfRvVzGo9PEeJKDJBLAcBZMIyAhPC0jDmxIV+6Wr867kVtll3HUlKcormvCZM5Yg906JmsjIEz Oo2S X-Received: by 2002:a05:6000:4211:b0:47f:96bc:e370 with SMTP id ffacd0b85a97d-47fec63bb0bmr22186473f8f.4.1786183105168; Sat, 08 Aug 2026 02:58:25 -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.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Aug 2026 02:58:24 -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 4/5] drm/bridge: synopsys: dw-dp: Add HDR static metadata support Date: Sat, 8 Aug 2026 11:57:23 +0200 Message-ID: <20260808095749.9428-5-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 Send an HDR Metadata InfoFrame SDP (DP 1.4a, Table 2-100 and Table 2-101) when the connector state carries HDR output metadata, and attach the HDR_OUTPUT_METADATA property in the Rockchip glue so userspace can set it. The infoframe is built with drm_hdmi_infoframe_set_hdr_metadata() and packed with drm_dp_hdr_metadata_infoframe_sdp_pack(), then written into a free slot of the SDP register bank with vertical interval transmission, so the controller resends it once per frame during the vertical blanking period. The SDP is sent at the end of dw_dp_video_enable(), next to the existing VSC SDP; the connector state is passed down from atomic_enable(), which already looks it up. The allocated slot is tracked in hdr_sdp_nr and released in atomic_disable(), following the VSC SDP pattern exactly: atomic_disable() only clears tracked slots, so an untracked slot would leak on every enable/disable cycle until dw_dp_send_sdp() runs out of free slots and fails with -EBUSY for every SDP, including VSC and audio. A metadata change on a live stream (HDR on/off toggle, different mastering display data) forces a full modeset: atomic_check() compares the old and new connector state with drm_connector_atomic_hdr_metadata_equal() and sets crtc_state->mode_changed, the same approach as dw-hdmi. The resulting disable/enable cycle then drops or (re)sends the SDP. Commits without HDR metadata are unaffected: with a NULL metadata blob in both old and new connector state, drm_connector_atomic_hdr_metadata_equal() treats them as equal, no modeset is forced, and dw_dp_video_enable() skips the SDP. This keeps plain SDR commits a no-op even for compositors that write a NULL blob on every atomic modeset once the property exists (KWin does). Signed-off-by: Igor Paunovic --- drivers/gpu/drm/bridge/synopsys/dw-dp.c | 44 +++++++++++++++++++++-- drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 2 ++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c index df149c52fce0..ca997ea53e66 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -369,6 +370,7 @@ struct dw_dp { struct drm_bridge *next_bridge; int vsc_sdp_nr; + int hdr_sdp_nr; DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE); }; @@ -1171,6 +1173,28 @@ static int dw_dp_send_vsc_sdp(struct dw_dp *dp) return dw_dp_send_sdp(dp, &sdp); } +static int dw_dp_send_hdr_metadata_sdp(struct dw_dp *dp, + const struct drm_connector_state *conn_state) +{ + struct hdmi_drm_infoframe frame; + struct dw_dp_sdp sdp = {}; + ssize_t len; + int ret; + + ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state); + if (ret) + return ret; + + len = drm_dp_hdr_metadata_infoframe_sdp_pack(dp->bridge.dev, &frame, + &sdp.base, sizeof(sdp.base)); + if (len < 0) + return len; + + sdp.flags = DW_DP_SDP_VERTICAL_INTERVAL; + + return dw_dp_send_sdp(dp, &sdp); +} + static int dw_dp_video_set_pixel_mode(struct dw_dp *dp) { switch (dp->pixel_mode) { @@ -1265,7 +1289,8 @@ static void dw_dp_video_disable(struct dw_dp *dp) FIELD_PREP(VIDEO_STREAM_ENABLE, 0)); } -static int dw_dp_video_enable(struct dw_dp *dp) +static int dw_dp_video_enable(struct dw_dp *dp, + const struct drm_connector_state *conn_state) { struct dw_dp_link *link = &dp->link; struct dw_dp_bridge_state *state; @@ -1440,6 +1465,9 @@ static int dw_dp_video_enable(struct dw_dp *dp) if (dw_dp_video_need_vsc_sdp(dp)) dp->vsc_sdp_nr = dw_dp_send_vsc_sdp(dp); + if (conn_state->hdr_output_metadata) + dp->hdr_sdp_nr = dw_dp_send_hdr_metadata_sdp(dp, conn_state); + return 0; } @@ -1597,6 +1625,7 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, struct dw_dp *dp = bridge_to_dp(bridge); struct dw_dp_bridge_state *state; const struct dw_dp_output_format *fmt; + struct drm_connector_state *old_conn_state; struct drm_display_mode *mode; int min_hbp = 16; int min_hsync = 9; @@ -1616,6 +1645,11 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, state->bpc = fmt->bpc; state->bpp = fmt->bpp; + 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)) + crtc_state->mode_changed = true; + if ((adjusted_mode->hsync_start - adjusted_mode->hdisplay) & 0x1) { adjusted_mode->hsync_start += 1; dev_warn(dp->dev, "hfp is not 2 pixeel aligned, fixup to aligned hfp\n"); @@ -2016,7 +2050,7 @@ static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge, return; } - ret = dw_dp_video_enable(dp); + ret = dw_dp_video_enable(dp, conn_state); if (ret < 0) { dev_err(dp->dev, "failed to enable video: %d\n", ret); return; @@ -2066,6 +2100,11 @@ static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge, dp->vsc_sdp_nr = -1; } + if (dp->hdr_sdp_nr >= 0) { + dw_dp_clear_sdp(dp, dp->hdr_sdp_nr); + dp->hdr_sdp_nr = -1; + } + dw_dp_reset(dp); pm_runtime_put_autosuspend(dp->dev); } @@ -2668,6 +2707,7 @@ int dw_dp_probe(struct dw_dp *dp) return ret; dp->vsc_sdp_nr = -1; + dp->hdr_sdp_nr = -1; dp->audio_interface = DW_DP_AUDIO_UNUSED; dp->audio_sdp_nr = -1; diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c index 4dc29963b5d8..c5bc178c0a50 100644 --- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c @@ -198,6 +198,8 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void * return ret; } + drm_connector_attach_hdr_output_metadata_property(connector); + return 0; } -- 2.43.0