From patchwork Thu Feb 22 18:14:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204959 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127216dyb; Thu, 22 Feb 2024 10:24:42 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXhcs67DsgB539WT3MKHWLGpyJ7RIOT1eigiq6Df/upFrXCr75Dyn6bK90yrRG4yUNb0Gst/WS1TGyqNTd5YP5GWc6xcw== X-Google-Smtp-Source: AGHT+IEans0Dl3kDsZ6oPRIvFRoAR0dH7uNfvTENy9DXtQ8JxAPYBsrzVdSm9Wdl2Jm0H8rkdNr0 X-Received: by 2002:a17:90b:3104:b0:299:4a62:548a with SMTP id gc4-20020a17090b310400b002994a62548amr17230095pjb.34.1708626281957; Thu, 22 Feb 2024 10:24:41 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626281; cv=pass; d=google.com; s=arc-20160816; b=LK9kJYFNtgoO8y0yYLOuD8x+KVUTS8r4tMspW/yF/NCbahBVJwszaFOOEbT0xl2xmK pfXqWoCb+8eHuYQE960QGbxZlcRC69mj9NkjV4M00SvbMPBhKeUgG/w4JHQbyWl8Efo3 UZKRP7FZ3Nv+iicb4gJvmHEMeAzB/ahcWHTB/Lt5ZCNjGKaW66mWX0kZPVkwr/gO92dp fNhQQw0kE6gl6rAKVpKsV4DJybVc/xA5dpehi8+1UmwhGnevNk0bwwHHUNnjk9W2nkAE /EODOIvqX1TXZ2sdablLKt0Vkuvou74EyRNblkGMr3AynBXcr519zY6FjtdxW12DtF0V KxZg== 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=mgAnGd78OFonJQM5iGQmupvozSUtdkNpzXztua2jqBU=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=ZnqPOQm5pbn/Muik2sPg6qE4WhFEMExle5CxG+W9hxYLk+GtY4qGtJbxOgAxdsgDrH LOvjmW2kurKp8h6FmcWkanlgzrAyzdvNU+quGEJVGqY49io5u39u4kx5CI9V7xOP8O40 d2IzPRCavynexZLSSf3bjjGWEgorR2PFrAJRfT9QNLb+7sn32vtvACvMYDgS20V3sZJS 8T/sQyTOxP+fkuL4BR8jTOy1dkDgHxDMhQayGgNgvyGIBl7TI1WwdJ/GXJyg/XQQpTgw F52lxFhkx6wMEJ2Y1QECY/7uLqCEagYHlFy+JIVsh8qvuJumuSoDsx3OS1wFdMhO9vs6 +PdQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=J6fngq1A; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id gq23-20020a17090b105700b0029589234aa5si10646125pjb.150.2024.02.22.10.24.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:24:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=J6fngq1A; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77093-ouuuleilei=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 sv.mirrors.kernel.org (Postfix) with ESMTPS id B7DEF285037 for ; Thu, 22 Feb 2024 18:24:41 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B8F36E5EA; Thu, 22 Feb 2024 18:15:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J6fngq1A" 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 CEECA13BACA; Thu, 22 Feb 2024 18:15:10 +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=1708625710; cv=none; b=gJ4Z/i1Xs/rcvRos6GcK2XjhmgMSOTuvC9yGfr5FPSn5PKF1dz31a8I2SHZQ9KYMfAo0+fGhzv2rhcJKmPxKlbqndhVpjcTRTxfiwuytBofYjUmHj+hMKKUjjxZGmbqeoDoBVafyTD4BWXczxxg7bVRqkzg9crcfarcKFki2tnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625710; c=relaxed/simple; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dtogYjzDIRsx/kCZ4LpyKlfoZ9rkvOv0cvTpCLB+/n+O4kHx6C8yEa5XEAdqsCiQIFJs5cCwv9mZJm0gmA6ZcsagTNqb45ahyL3XCSAOfh361c5Dow5/FkAqv7mAlcsJZ5rk4clQWTAv6mJIZOGf7uhRp8JxnowzwXZzYGk6CZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J6fngq1A; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 524A2C433F1; Thu, 22 Feb 2024 18:15:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625710; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=J6fngq1AbjSrcpH0KSddtC11tu8hWtlXwsgy7la4yxHKjSEW7SBGDGYfUbc8ZdzsD VixyiJ/+DLrcPPfZwU4wVHjJf4RbsigYHXtzBxqOCKrL28zEROL4UqbjtIney0EJ5V 4IUYvBgQbvX3MOtdTR/bR7JYxzyDS3E7sjF1LadvaGAyNlvds1COBBpDU+phe/Ge6v ueT5iDm0sldCDjsKXTB6LAYEDj4ic7nazR2voKDG3JnpX5Bd9asFIDLTRUjwQkQxjv yh8PQuySNfICttg/30j4mNSfUhroSvlZlYZC2HwwJsBS70SMMcTgJ7xi2kR/T57Bqp onJX00DCAB0ug== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:01 +0100 Subject: [PATCH v7 15/36] 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 Message-Id: <20240222-kms-hdmi-connector-state-v7-15-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@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?b?VmlsbGUgU3lyasOkbMOk?= , 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=5168; i=mripard@kernel.org; h=from:subject:message-id; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z4d1eW3m3RkpZiDT0QHL9tbX+dmzt96LOaXzyze1 5PoyRXaUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIk8WsfIcOCEWPSajxeZdj33 n3TC4+hOh7TDS253PVlw3llnmfGthOMMf6XZyv3m9vFtNflnlJK3/+FyhzVFLQLz5YUSU4z1BBU 5+QA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624511725033800 X-GMAIL-MSGID: 1791624511725033800 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 @@ -1148,6 +1148,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, 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) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index ae99765c45de..63a96c691460 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -640,6 +640,63 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, } 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 *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; + + state->hdmi.tmds_char_rate = clock; + + return 0; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -659,6 +716,15 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, drm_atomic_get_old_connector_state(state, connector); struct drm_connector_state *new_state = drm_atomic_get_new_connector_state(state, connector); + const struct drm_display_mode *mode = + connector_state_get_mode(new_state); + int ret; + + ret = hdmi_compute_clock(connector, new_state, mode, + new_state->hdmi.output_bpc, + new_state->hdmi.output_format); + if (ret) + return ret; if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc || old_state->hdmi.output_format != new_state->hdmi.output_format) { 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 @@ -70,6 +70,9 @@ static int light_up_connector(struct kunit *test, 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); 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 @@ -1050,6 +1050,11 @@ 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; };