Received: by 2002:ab2:6857:0:b0:1ef:ffd0:ce49 with SMTP id l23csp556054lqp; Thu, 21 Mar 2024 08:47:36 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU4G4Xk/0ihsi7xZ44yGtHuXp52cHsJFoJkjQ9mAUHk2KAfaUQKIYMF+KOv6UCw4swrja+O7EETbA5OzoiMTHGRVmJaPUdCZc1GFQyTvg== X-Google-Smtp-Source: AGHT+IGTrNVduEi1Zq2eUQow806R0ZRQNX2RnNhkbT6Tei1rkbXdBh5MG+vpsKnnKWqOi2zw+oHD X-Received: by 2002:a17:90a:ee86:b0:29c:582d:bade with SMTP id i6-20020a17090aee8600b0029c582dbademr17156517pjz.2.1711036056646; Thu, 21 Mar 2024 08:47:36 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1711036056; cv=pass; d=google.com; s=arc-20160816; b=nLh4Pkt548KFCau4D5OBm/V13n5NmwuLJK+N02ix4dFPL/iUrdd/aNjEQWedkI7ZaY vTH6mOlrX9iBoIPQJ0ekgHKisqhxCZ4PjSDAr3couuDOHw3wjPljiPo6f0fclMMYB4tb OrNYFzyx2N7vmnYteiC5E4qSbCBeo3di+jNiVZ7cAMDeCn+CpPaLRg06DeRCYp05S7LS AxeD6l09295ptwETWVJ3JLN/ph+8yX+ESHTWaOCM7+THoVxSSVEff05g54PVGMfV0dX+ qf8BQ1Fa1QQt8f+SoQzWgjk/lxin2gfDr4XefcRFO0tQh4P76fZLj2Rnjcf+NVCmU3L3 pI0A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=V+DzHR+avy0/hcgSqyQF0I8YB6gKZ2rZCfw2AreyGxo=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=UG2KhkTxPZ66ioAnvWlQpkxy4bAB9sb7wfZGzKegvnyBnOyveM5qVduJe3wstZMHSS 2xnul2uSt8D8KUofwi1wq6+bRTjQ3HL9GmqTrCaVECBhXjeu6XIOqHich2Q2sSAtus4w p07+bAVgmi+jMksKTLdI9WjO0/iQvuJPBH459DbUcX81R7Medi/civq94DEVNiRiL7NN fnXx0XPwy1xZ9Ushj5SF5Y3V65o6imGEiG7+669GNxEFLBYLyaMXvFI0phH8jRfdQ3P9 7ke1CGy4pGYaPjd1a0jRICVsdxAaUAglxAo4DdXKFyVLr2DzRkoiTVz4cvgVhRxYNqPj Fg2Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rMMS4d0f; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-110232-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-110232-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id kk3-20020a17090b4a0300b002a02a175d5fsi841261pjb.59.2024.03.21.08.47.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 08:47:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-110232-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rMMS4d0f; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-110232-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-110232-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 67855B230F3 for ; Thu, 21 Mar 2024 15:32:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6DE9212836E; Thu, 21 Mar 2024 15:29:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rMMS4d0f" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35BFF12838A; Thu, 21 Mar 2024 15:29:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711034996; cv=none; b=Bye9Nf50Sc7tCMI0ajZ/SgKn2Ss17IQznQvzw6XmI+pSgxTwxuH2+VrNMjgsV58heMxgTD4kBA9VGWPNXhtGMPLayjv6Bl9v6h4uH2jHtRv/lY2iA5cBdYb14Iobc7nllVoR65Zj2Q/BnhwHlEm5ztv/+fcOPY6Kp6b4eq8DIMI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711034996; c=relaxed/simple; bh=xthfIST1lGc4FWyr+fzRu/DYjW9GlBYueqwGh9R+r8k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MmroyUpGPX6NP59kHfD8Fez7XFXsqC0iPUenvkBHa4014hKNMHR/xoWME+35zy6Pq/McPW1OdkqQS42k0pePHXdoFLmiYpRwkoPvzwItbXJFyuO6v0UzGTN0sxiAtCCoy+WQ/q2/VLAo72fWwIz/mbw1gagrqTEUCtwTsHq0C3E= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rMMS4d0f; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 788B4C43399; Thu, 21 Mar 2024 15:29:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711034995; bh=xthfIST1lGc4FWyr+fzRu/DYjW9GlBYueqwGh9R+r8k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rMMS4d0fxMKQm4SY3u2PPgYgbaqpEi+uRJDV7p/Fn04I2VQmBIQcagpDH+S6vTItJ CDcGEt/kIA+dRxd3Uh5UL5Ry5paFLNrXIdRghUkeC537kFZD6hQhLV5+soU62PmJTE d2cTx/0leEVYJ+FVZSuZQ6mpQHKwBB8cxJIyP6wY5oIISjVNG8KC4j6vdf0U2NxWlC k5WX6d3Y9iJXfx3h5Igkf2fmwOOhY7ieMekxdeJ94EcYRxMYGY3ITasWV2g9fSGv1h UhioDr9ZxWOEniHavXGztYQpXwVcgnfp7XOeVofvOCRVqRMzbfVBS1mQp7t7u+JZdA 9nznxM1rx7QDg== From: Maxime Ripard Date: Thu, 21 Mar 2024 16:29:06 +0100 Subject: [PATCH v10 10/27] drm/connector: hdmi: Calculate TMDS character rate Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20240321-kms-hdmi-connector-state-v10-10-e6c178361898@kernel.org> References: <20240321-kms-hdmi-connector-state-v10-0-e6c178361898@kernel.org> In-Reply-To: <20240321-kms-hdmi-connector-state-v10-0-e6c178361898@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?q?Ville_Syrj=C3=A4l=C3=A4?= , 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 , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5924; i=mripard@kernel.org; h=from:subject:message-id; bh=xthfIST1lGc4FWyr+fzRu/DYjW9GlBYueqwGh9R+r8k=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKl/gjx657C9vanDN/W6FO+CY8d8plSund0sE+1Qkb3gx m79jpcXO0pZGMS4GGTFFFlihM2XxJ2a9bqTjW8ezBxWJpAhDFycAjCRxECGf7pT1H6lHkg6F/75 lYNXnr3G762l+zJuJJb9/5A/f03OsmuMDCtrLzadenhbNU7519FVHpy6+udOHdy/alpTTcSmp1s fTmMEAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D 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 Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 66 ++++++++++++++++++++++ .../gpu/drm/tests/drm_atomic_state_helper_test.c | 3 + include/drm/drm_connector.h | 5 ++ 4 files changed, 75 insertions(+) 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/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 3a9ef45509e1..7258178bc385 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -638,10 +638,67 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, return 0; } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); +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_connector_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 * @@ -657,10 +714,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/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c index 1c3dd8a98fb0..f2acbd4c216c 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -68,10 +68,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 a859ad7ee04b..e3917ea93986 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1048,10 +1048,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.44.0