dri-devel Archive mirror
 help / color / mirror / Atom feed
From: Maxime Ripard <mripard@kernel.org>
To: "Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Sandy Huang" <hjc@rock-chips.com>,
	"Heiko Stübner" <heiko@sntech.de>, "Chen-Yu Tsai" <wens@csie.org>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Samuel Holland" <samuel@sholland.org>,
	"Andy Yan" <andy.yan@rock-chips.com>
Cc: "Hans Verkuil" <hverkuil@xs4all.nl>,
	"Sebastian Wick" <sebastian.wick@redhat.com>,
	"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
	dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
	linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev,
	"Maxime Ripard" <mripard@kernel.org>,
	"Dave Stevenson" <dave.stevenson@raspberrypi.com>
Subject: [PATCH v13 11/28] drm/connector: hdmi: Calculate TMDS character rate
Date: Tue, 07 May 2024 15:17:29 +0200	[thread overview]
Message-ID: <20240507-kms-hdmi-connector-state-v13-11-8fafc5efe8be@kernel.org> (raw)
In-Reply-To: <20240507-kms-hdmi-connector-state-v13-0-8fafc5efe8be@kernel.org>

Most HDMI drivers have some code to calculate the TMDS character rate,
usually to adjust an internal clock to match what the mode requires.

Since the TMDS character rates mostly depends on the resolution, whether
we need to repeat pixels or not, the bpc count and the format, we can
now derive it from the HDMI connector state that stores all those infos
and remove the duplication from drivers.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    | 67 ++++++++++++++++++++++
 drivers/gpu/drm/drm_atomic.c                       |  1 +
 drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c |  3 +
 include/drm/drm_connector.h                        |  5 ++
 4 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index f6cd0612ea2c..08630561d864 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -1,10 +1,11 @@
 // SPDX-License-Identifier: MIT
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_connector.h>
 
+#include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
 
 /**
  * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources
  * @connector: DRM connector
@@ -23,10 +24,67 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
 	new_conn_state->max_bpc = max_bpc;
 	new_conn_state->max_requested_bpc = max_bpc;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
 
+static const struct drm_display_mode *
+connector_state_get_mode(const struct drm_connector_state *conn_state)
+{
+	struct drm_atomic_state *state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+
+	state = conn_state->state;
+	if (!state)
+		return NULL;
+
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return NULL;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (!crtc_state)
+		return NULL;
+
+	return &crtc_state->mode;
+}
+
+static enum drm_mode_status
+hdmi_clock_valid(const struct drm_connector *connector,
+		 const struct drm_display_mode *mode,
+		 unsigned long long clock)
+{
+	const struct drm_display_info *info = &connector->display_info;
+
+	if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
+static int
+hdmi_compute_clock(const struct drm_connector *connector,
+		   struct drm_connector_state *conn_state,
+		   const struct drm_display_mode *mode,
+		   unsigned int bpc, enum hdmi_colorspace fmt)
+{
+	enum drm_mode_status status;
+	unsigned long long clock;
+
+	clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt);
+	if (!clock)
+		return -EINVAL;
+
+	status = hdmi_clock_valid(connector, mode, clock);
+	if (status != MODE_OK)
+		return -EINVAL;
+
+	conn_state->hdmi.tmds_char_rate = clock;
+
+	return 0;
+}
+
 /**
  * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
  * @connector: DRM Connector
  * @state: the DRM State object
  *
@@ -42,10 +100,19 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
 {
 	struct drm_connector_state *old_conn_state =
 		drm_atomic_get_old_connector_state(state, connector);
 	struct drm_connector_state *new_conn_state =
 		drm_atomic_get_new_connector_state(state, connector);
+	const struct drm_display_mode *mode =
+		connector_state_get_mode(new_conn_state);
+	int ret;
+
+	ret = hdmi_compute_clock(connector, new_conn_state, mode,
+				 new_conn_state->hdmi.output_bpc,
+				 new_conn_state->hdmi.output_format);
+	if (ret)
+		return ret;
 
 	if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc ||
 	    old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) {
 		struct drm_crtc *crtc = new_conn_state->crtc;
 		struct drm_crtc_state *crtc_state;
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8730137baa86..26f9e525c0a0 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1146,10 +1146,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 	if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
 		drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
 		drm_printf(p, "\toutput_format=%s\n",
 			   drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
+		drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate);
 	}
 
 	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 		if (state->writeback_job && state->writeback_job->fb)
 			drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
index 8bc1f9b0b12b..4f46a70a5017 100644
--- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -70,10 +70,13 @@ static int light_up_connector(struct kunit *test,
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
 
 	conn_state = drm_atomic_get_connector_state(state, connector);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
 
+	conn_state->hdmi.output_bpc = connector->max_bpc;
+	conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+
 	ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
 	KUNIT_EXPECT_EQ(test, ret, 0);
 
 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 29883e6f8e50..54899c030031 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1047,10 +1047,15 @@ struct drm_connector_state {
 
 		/**
 		 * @output_format: Pixel format to output in.
 		 */
 		enum hdmi_colorspace output_format;
+
+		/**
+		 * @tmds_char_rate: TMDS Character Rate, in Hz.
+		 */
+		unsigned long long tmds_char_rate;
 	} hdmi;
 };
 
 /**
  * struct drm_connector_funcs - control connectors on a given device

-- 
2.45.0


  parent reply	other threads:[~2024-05-07 13:18 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-07 13:17 [PATCH v13 00/28] drm/connector: Create HDMI Connector infrastructure Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 01/28] drm/connector: Introduce an HDMI connector initialization function Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 02/28] drm/mode_object: Export drm_mode_obj_find_prop_id for tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 03/28] drm/tests: connector: Add tests for drmm_connector_hdmi_init Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 04/28] drm/connector: hdmi: Create an HDMI sub-state Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 05/28] drm/connector: hdmi: Add output BPC to the connector state Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 06/28] drm/tests: Add output bpc tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 07/28] drm/connector: hdmi: Add support for output format Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 08/28] drm/tests: Add output formats tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 09/28] drm/display: hdmi: Add HDMI compute clock helper Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 10/28] drm/tests: Add HDMI TDMS character rate tests Maxime Ripard
2024-05-07 13:17 ` Maxime Ripard [this message]
2024-05-07 13:17 ` [PATCH v13 12/28] drm/tests: Add TDMS character rate connector state tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 13/28] drm/connector: hdmi: Add custom hook to filter TMDS character rate Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 14/28] drm/tests: Add HDMI connector rate filter hook tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 15/28] drm/connector: hdmi: Compute bpc and format automatically Maxime Ripard
2024-05-12  8:18   ` Andy Yan
2024-05-16  9:45     ` [PATCH " Maxime Ripard
2024-05-16 10:33       ` Andy Yan
2024-05-07 13:17 ` [PATCH v13 16/28] drm/tests: Add HDMI connector bpc and format tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 17/28] drm/connector: hdmi: Add Broadcast RGB property Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 18/28] drm/tests: Add tests for " Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 19/28] drm/connector: hdmi: Add RGB Quantization Range to the connector state Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 20/28] drm/tests: Add RGB Quantization tests Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 21/28] drm/connector: hdmi: Add Infoframes generation Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 22/28] drm/tests: Add infoframes test Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 23/28] drm/connector: hdmi: Create Infoframe DebugFS entries Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 24/28] drm/vc4: hdmi: Switch to HDMI connector Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 25/28] drm/vc4: tests: Remove vc4_dummy_plane structure Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 26/28] drm/vc4: tests: Convert to plane creation helper Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 27/28] drm/rockchip: inno_hdmi: Switch to HDMI connector Maxime Ripard
2024-05-12  8:29   ` Andy Yan
2024-05-16  9:36     ` [PATCH " Maxime Ripard
2024-05-07 13:17 ` [PATCH v13 28/28] drm/sun4i: hdmi: " Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240507-kms-hdmi-connector-state-v13-11-8fafc5efe8be@kernel.org \
    --to=mripard@kernel.org \
    --cc=airlied@gmail.com \
    --cc=andy.yan@rock-chips.com \
    --cc=corbet@lwn.net \
    --cc=daniel@ffwll.ch \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=hverkuil@xs4all.nl \
    --cc=jernej.skrabec@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=samuel@sholland.org \
    --cc=sebastian.wick@redhat.com \
    --cc=tzimmermann@suse.de \
    --cc=ville.syrjala@linux.intel.com \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).