From patchwork Thu Jan 27 14:10:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726832 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25401C433F5 for ; Thu, 27 Jan 2022 14:10:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4EE3810EEDD; Thu, 27 Jan 2022 14:10:29 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3A87B10EEDE for ; Thu, 27 Jan 2022 14:10:26 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 98441580644; Thu, 27 Jan 2022 09:10:25 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 27 Jan 2022 09:10:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=VusnnL++oQUSGwpOjUjdL4XYB8Ps4k thpOZUIiblgnA=; b=kJKiiTE5lWRhHQqixxeOTS/I+m01cXhyFQia8eUfmRKGDr 1I3cnPZU1KUs5JJ7sbaDZkPhpi/AdjSTUaYaI2gfB4uTtFPGdC1aH1QVsgizosuA 8Na5/XW3uPGqR6/IO0v3VRqtmDmsfw774iOzPnhJg1v278mL0PE76EyKGk1OD9mt ULXG1ePwO3IiW1ML+Se27Oauz5z04lycVT+9cLzh70Cqae9rx8IGjs2cZ3jG4Qh4 4l4MdSk5NSKRJOaqWsBBM5TmbGIYsSYRj1bi8xttFIfFNCEDV5vKLn41+DJzwqDi cUsgmZF49WHWsRyLaJ4b4537OQWOYAzhjCrosx0A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=VusnnL ++oQUSGwpOjUjdL4XYB8Ps4kthpOZUIiblgnA=; b=ZYvg6xEKZbSyZbVMoW/bvq fOQdilVEiA+LvOldFcwxMU++IpDbomOAZsD4YYC8AItrVFNsdMsG1GcqFr1aFWF2 YouCuM9nWeg90KsqHNVwqTO/srUQyJCcht3coumOd02tkq+d8vEvGls2sO0PUeKW ZjCXn4sls8Nf+4peL2/AWsiOu5pnaEbMBOG/timqhbR/FvD+j7w+RgGtoQFWPVyM 83UaqeiyRl4RRxJY1f0/+mNnH3bQBInYVimlzDcgb/BUOj3KkZUM24bMi/6z3keV LgGG65n/SQ1aP2I5zuTuh9VMvUOrlnjTTrxJT+kuZ27rnn/3GxXVIB+nfBa6BD9A == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeiudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:25 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 1/6] drm/vc4: hdmi: Move clock validation to its own function Date: Thu, 27 Jan 2022 15:10:16 +0100 Message-Id: <20220127141021.302482-2-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Our code is doing the same clock rate validation in multiple instances. Let's create a helper to share the rate validation. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index e3121eb5f605..105911644b02 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1261,6 +1261,19 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, mutex_unlock(&vc4_hdmi->mutex); } +static enum drm_mode_status +vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, + unsigned long long clock) +{ + if (clock > vc4_hdmi->variant->max_pixel_clock) + return MODE_CLOCK_HIGH; + + if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL @@ -1304,10 +1317,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, if (mode->flags & DRM_MODE_FLAG_DBLCLK) pixel_rate = pixel_rate * 2; - if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) - return -EINVAL; - - if (vc4_hdmi->disable_4kp60 && (pixel_rate > HDMI_14_MAX_TMDS_CLK)) + if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, pixel_rate) != MODE_OK) return -EINVAL; vc4_state->pixel_rate = pixel_rate; @@ -1326,13 +1336,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, (mode->hsync_end % 2) || (mode->htotal % 2))) return MODE_H_ILLEGAL; - if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) - return MODE_CLOCK_HIGH; - - if (vc4_hdmi->disable_4kp60 && vc4_hdmi_mode_needs_scrambling(mode)) - return MODE_CLOCK_HIGH; - - return MODE_OK; + return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000); } static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { From patchwork Thu Jan 27 14:10:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726833 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8D82DC433F5 for ; Thu, 27 Jan 2022 14:10:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3E06C10EEE3; Thu, 27 Jan 2022 14:10:30 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id 55B2A10EEDD for ; Thu, 27 Jan 2022 14:10:28 +0000 (UTC) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailnew.nyi.internal (Postfix) with ESMTP id B35BA580689; Thu, 27 Jan 2022 09:10:27 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Thu, 27 Jan 2022 09:10:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=i3ujLd3aGINAUREHUY3+W9KX+lHJsQ VGxv6DCB3uNe4=; b=g3A2SFBDkI9CrWD3P1Rv7MuDCpR2m6r5ToqSNUAD7Srq1C m6eUqRl1UEMZM1rMGo+mveMyhiJPE4EGjD5weHkkTBO/t+sBjswIeuw0q5asZbYq QON9rkkLXNQQP9XaSbdajveb5991B0R6xhwcZY67BQjdx+POyJ52i3ZRg6iX0uPC FYXsCRwQ+YqVXdO8gcBC4KDhqHoNxJbb3VFlaJnAu9gXyJA8zx4rIkcKkoDgjV8z Yp6g9Oy66QwJQj+GwyFYnYDKfQr3ITPy/HxykIqh1IUE6cN1E0Yj9sNpxXN063Bx 0dNvYJsavEMgUF12y0Y+hviYPdPKkB+YevDPLTPA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=i3ujLd 3aGINAUREHUY3+W9KX+lHJsQVGxv6DCB3uNe4=; b=Yb4/uvbZMtAp32W3JUk1ka uXtmM+ne7GLjOWuq4viJvh30PKGhteMaSaolh0LbzucIckz9SReWjFbvBzD0LK2A saY1fXRx2Q60mle4zRqDZQWCCFoWAqt5qoJMNtIoUHMPN7elNWjw3U6hZX92CTOW mt9dBQvljrH1Og7e4c47sd74kiA4n7fT0Gkl0Gc7y/D6oLrA20pPdZbl86NxZNkR kz5rTFkcnqptYnuaB3hU9FVCzJrHTG6w1i1YWlg3YB/6EWIyee52ekXPJzoLIhfO fJmzILf4iDUPIsrdsn/6e2wmxVyfb1iQd3q0k8t3jrkj+rpZPe2TfJ0zgC5sCJfg == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeiudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:27 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 2/6] drm/vc4: hdmi: Move clock calculation into its own function Date: Thu, 27 Jan 2022 15:10:17 +0100 Message-Id: <20220127141021.302482-3-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The code to compute our clock rate for a given setup will be called in multiple places in the next patches, so let's create a separate function for it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 49 +++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 105911644b02..a1fa37ad350d 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1274,6 +1274,35 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, return MODE_OK; } +static unsigned long long +vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc) +{ + unsigned long long clock = mode->clock * 1000; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + clock = clock * 2; + + return clock * bpc / 8; +} + +static int +vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, + struct vc4_hdmi_connector_state *vc4_state, + const struct drm_display_mode *mode, + unsigned int bpc) +{ + unsigned long long clock; + + clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); + if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK) + return -EINVAL; + + vc4_state->pixel_rate = clock; + + return 0; +} + #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL @@ -1286,6 +1315,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); unsigned long long pixel_rate = mode->clock * 1000; unsigned long long tmds_rate; + int ret; if (vc4_hdmi->variant->unsupported_odd_h_timings && ((mode->hdisplay % 2) || (mode->hsync_start % 2) || @@ -1306,21 +1336,10 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, pixel_rate = mode->clock * 1000; } - if (conn_state->max_bpc == 12) { - pixel_rate = pixel_rate * 150; - do_div(pixel_rate, 100); - } else if (conn_state->max_bpc == 10) { - pixel_rate = pixel_rate * 125; - do_div(pixel_rate, 100); - } - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - pixel_rate = pixel_rate * 2; - - if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, pixel_rate) != MODE_OK) - return -EINVAL; - - vc4_state->pixel_rate = pixel_rate; + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, mode, + conn_state->max_bpc); + if (ret) + return ret; return 0; } From patchwork Thu Jan 27 14:10:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726836 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DF4CFC433F5 for ; Thu, 27 Jan 2022 14:10:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 03F7C10EEF4; Thu, 27 Jan 2022 14:10:45 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id C314D10EEE5 for ; Thu, 27 Jan 2022 14:10:30 +0000 (UTC) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 2D9035805AF; Thu, 27 Jan 2022 09:10:30 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Thu, 27 Jan 2022 09:10:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=9mbUfQ1GEQHnSAUGIKRKIKh820kKx3 t6FdGLkje7Ekg=; b=lQahqLs9uHNt+iwOExLzZp70XNFZBjg8RWliDzjtiZ1IFJ sEDtq8i6MB+OyQRmYVHXvciBjsPGkvfj4V4FbJRAlYrqr4q7Jq3rLxmQqyo6FNz1 VAsNo+iBFGAsWmqXzvuY83QB6N3ONLW9edPt5KjhRD7ajgZ+RhW7IKLTZhIeqL1r 6VQy2SoByPcvCsZgjmUwPgnLg1Q7rQZdF/1OqxCqnzb91h2wlYdEP5S0J65cS1W9 Jl9YGYWclm0DsV/qeAZ6nCTPz7E8mHvPUQq8kwhiyzRQ+/4B2baMWoTD6s/JYjeV jWJESVsswqsBFyYnD3k+LxDdO6Uf3P/Z2AhIpkVQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=9mbUfQ 1GEQHnSAUGIKRKIKh820kKx3t6FdGLkje7Ekg=; b=JhkA78TWo+ZJbDR1rvki2s Cmd+wYZ6wwqrdAoK9Bck88t6DjbamoiaTZLk3F8TNZf/sS8nBkWbiHk+UNkqs7ne 7pUefAZtmnN0T+H6mxHNlfsC8MHhRTy9MighJtxG5O784i33YIZAVtAsK8nyCi6m szSYaC9zO7NFdXrHUiPlsBXeRE1JsSE3uA9Tt1TtEzHtMOoRZQjb0/1Srb+2flXx e6vLFGPig97P47aS5gfM8RtZuVsLQsBp8GJ9mEW1C9qmsmTOttDjo+TrbAoxmmfX xTaOXWbunC5rxum6DDLRkV2H0RAvRd9JUAQktFVEqx9cyzYgwOCkRTmgPHsau8mQ == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeivdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:29 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 3/6] drm/vc4: hdmi: Take the sink maximum TMDS clock into account Date: Thu, 27 Jan 2022 15:10:18 +0100 Message-Id: <20220127141021.302482-4-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" In the function that validates that the clock isn't too high, we've only taken our controller limitations into account so far. However, the sink can have a limit on the maximum TMDS clock it can deal with too which is exposed through the EDID and the drm_display_info. Make sure we check it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index a1fa37ad350d..4c3a5959c7f5 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1265,12 +1265,18 @@ static enum drm_mode_status vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, unsigned long long clock) { + const struct drm_connector *connector = &vc4_hdmi->connector; + const struct drm_display_info *info = &connector->display_info; + if (clock > vc4_hdmi->variant->max_pixel_clock) return MODE_CLOCK_HIGH; if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK) return MODE_CLOCK_HIGH; + if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000)) + return MODE_CLOCK_HIGH; + return MODE_OK; } From patchwork Thu Jan 27 14:10:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726835 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E2342C433FE for ; Thu, 27 Jan 2022 14:10:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7329A10EEE6; Thu, 27 Jan 2022 14:10:36 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id C5A7510EEE5 for ; Thu, 27 Jan 2022 14:10:32 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 2D9365805AF; Thu, 27 Jan 2022 09:10:32 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 27 Jan 2022 09:10:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=r+wDKEsDBVZTL2Sut88WjF/DMZjQQV /17QsoK6DM1Dc=; b=p9r95XTGbgxHOA9CkDNvNJi+7HRK6jWv4dzWd2qDQ/JNls Kg2ZXQ+dZaQ/dHrzBXOQjid54MkAypymCvjDjE7KiqI26WmBARivJQN7zFJadKAn AXylJorZ3/aDeaOyDMpTLoC/JM0MsrAEeSpX3toXTKEthZlk6Xd00gOdK0zJAd4c 5BfsX5qEWgl8tGRdgqFh4MyifKkihY+C/ro17f4KR7nE9Gj2+HqMVv9EgZ/HD+Ys r7ohiG9x5B1yyOsG7d5RwvtPG2fZy1hkF9CZGIbpipwoieo8MCezToetzfGuL6f6 YUAsAIX90VpxWc8sXfw3MdAwbgERTWoZ71jwFV9g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=r+wDKE sDBVZTL2Sut88WjF/DMZjQQV/17QsoK6DM1Dc=; b=k1ZSdoFWPoMYTwK1MLoXrG N/Ey7+XnWbdi+aiZGHMesOfyOrVJm1rt8bHBDEwSP/YFgje6FjoWEKF2u4o5icbG iVcgdcRBIwI92huYUPrq9znouMw5ziLkzVnTniEn939Qc+SPmrFwdwsYq5B2PR6J tb6wlRkfwqrbIrl0C6ImmsXLu2toyGU0Ji3d9qBxklDps5k6afnLnGutmHvBC/w4 iXO3U5YpThRwwEYiYrWpQeXmZbc2EFtXJ5kuYCRfd2tAFgSN5eH2DBeYa29FPXEZ xf1IkuqihbXIe+CG69yn2UPTw/OAvImVozV+eNoWdyiWpmiEJ71/VPZxaLSL3tYQ == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeiudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:31 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 4/6] drm/vc4: hdmi: Take bpp into account for the scrambler Date: Thu, 27 Jan 2022 15:10:19 +0100 Message-Id: <20220127141021.302482-5-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The current code only base its decision for whether the scrambler must be enabled or not on the pixel clock of the mode, but doesn't take the bits per color into account. Let's leverage the new function to compute the clock rate in the scrambler setup code. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 17 +++++++++++++---- drivers/gpu/drm/vc4/vc4_hdmi.h | 5 +++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 4c3a5959c7f5..03d0813992a7 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -99,9 +99,17 @@ #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) -static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode) + +static unsigned long long +vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc); + +static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, + unsigned int bpc) { - return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK; + unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); + + return clock > HDMI_14_MAX_TMDS_CLK; } static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi, @@ -272,7 +280,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) struct drm_display_mode *mode; list_for_each_entry(mode, &connector->probed_modes, head) { - if (vc4_hdmi_mode_needs_scrambling(mode)) { + if (vc4_hdmi_mode_needs_scrambling(mode, 8)) { drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz."); drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60."); } @@ -613,7 +621,7 @@ static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder) if (!vc4_hdmi_supports_scrambling(encoder, mode)) return; - if (!vc4_hdmi_mode_needs_scrambling(mode)) + if (!vc4_hdmi_mode_needs_scrambling(mode, vc4_hdmi->output_bpc)) return; drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); @@ -1255,6 +1263,7 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); mutex_lock(&vc4_hdmi->mutex); + vc4_hdmi->output_bpc = conn_state->max_bpc; memcpy(&vc4_hdmi->saved_adjusted_mode, &crtc_state->adjusted_mode, sizeof(vc4_hdmi->saved_adjusted_mode)); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 2b6aaafc020a..31b7d27deb8e 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -216,6 +216,11 @@ struct vc4_hdmi { * the scrambler on? Protected by @mutex. */ bool scdc_enabled; + + /** + * @output_bpc: BPC currently being used. Protected by @mutex. + */ + unsigned int output_bpc; }; static inline struct vc4_hdmi * From patchwork Thu Jan 27 14:10:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726834 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A9ECFC433F5 for ; Thu, 27 Jan 2022 14:10:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8AE9D10EEE8; Thu, 27 Jan 2022 14:10:36 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id 477D710EEE8 for ; Thu, 27 Jan 2022 14:10:35 +0000 (UTC) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailnew.nyi.internal (Postfix) with ESMTP id A52CD5805AF; Thu, 27 Jan 2022 09:10:34 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Thu, 27 Jan 2022 09:10:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=LFTDmmV59cFD9Wz3z2ovMw18FDf0Tk WPfWRkawn6fKM=; b=FXDfH/OdHDCvW0mIVcD9U7fTUTJYFRdqOHGSfLYGDERWia 4mOwyLzCEDJa7xGbErd4fsCl8TXPEs+MqgHpNnlO1tzx+J9VpX7BcqIh0Z4/8SGg h1+9aDTlhgLRFaA9cVSTzfgUUXJX8MMt6Mss0M5fieeVDf12+QYLQIoqQT18lGE+ SXtwBKbTy+Txfqh+O23u9c6bblzeniIeBx7w8rp9CSHO8iUfBXJk5+rpamuEJfRR LkiMcmgWpPP/A7W1rS6JDZ4awKMCQszdwvyO8vMsoB+ydGF+/g4DLBK6pcQHwpZV zvrSeXxGi+wHdSn325VeUtCtopsemQs/GmqqWFcA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=LFTDmm V59cFD9Wz3z2ovMw18FDf0TkWPfWRkawn6fKM=; b=Re2t1yUirFjL3/pQKNUtml DCa69l0eT9H2ZyijBObioQ4NYKqWSrLG3aOrs+Wegq/nGWgvssFoqRwR2TFvaloC 1bYrYr/4h0hWP96xSyxkEb5gq/f9UCzJex5s14DQT+XrymWbsNRE50o8XxCO3cU+ Di/pbvst2rDbAbLc9YtjfcdR057ZVQhwF7SuyWb9T+JzZgFYzhB/hlOo16QKznhb FTWO44Vyz8oRCwSMFyvRxYrKrWSbDvSrha0RzAlAhjhCwmjxBaXgFCb2SEygbO+j 7ARts+Xh8yOGOZvbt5hVvVd6Zd2tZxrN8AUy6Z/qMSC5DlcVpInoxvce8yh1z3sA == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeivdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:33 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 5/6] drm/vc4: hdmi: Always try to have the highest bpc Date: Thu, 27 Jan 2022 15:10:20 +0100 Message-Id: <20220127141021.302482-6-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Currently we take the max_bpc property as the bpc value and do not try anything else. However, what the other drivers seem to be doing is that they would try with the highest bpc allowed by the max_bpc property and the hardware capabilities, test if it results in an acceptable configuration, and if not decrease the bpc and try again. Let's use the same logic. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 44 ++++++++++++++++++++++++++++++---- drivers/gpu/drm/vc4/vc4_hdmi.h | 4 +++- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 03d0813992a7..3ce002e485ce 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -352,6 +352,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector) return NULL; new_state->pixel_rate = vc4_state->pixel_rate; + new_state->output_bpc = vc4_state->output_bpc; __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); return &new_state->base; @@ -906,6 +907,8 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, struct drm_connector_state *state, struct drm_display_mode *mode) { + const struct vc4_hdmi_connector_state *vc4_state = + conn_state_to_vc4_hdmi_conn_state(state); bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; @@ -953,7 +956,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, HDMI_WRITE(HDMI_VERTB0, vertb_even); HDMI_WRITE(HDMI_VERTB1, vertb); - switch (state->max_bpc) { + switch (vc4_state->output_bpc) { case 12: gcp = 6; gcp_en = true; @@ -1261,9 +1264,11 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + struct vc4_hdmi_connector_state *vc4_state = + conn_state_to_vc4_hdmi_conn_state(conn_state); mutex_lock(&vc4_hdmi->mutex); - vc4_hdmi->output_bpc = conn_state->max_bpc; + vc4_hdmi->output_bpc = vc4_state->output_bpc; memcpy(&vc4_hdmi->saved_adjusted_mode, &crtc_state->adjusted_mode, sizeof(vc4_hdmi->saved_adjusted_mode)); @@ -1318,6 +1323,38 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, return 0; } +static int +vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi, + struct vc4_hdmi_connector_state *vc4_state, + const struct drm_display_mode *mode) +{ + struct drm_connector_state *conn_state = &vc4_state->base; + unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12); + unsigned int bpc; + int ret; + + for (bpc = max_bpc; bpc >= 8; bpc -= 2) { + drm_dbg(dev, "Trying with a %d bpc output\n", bpc); + + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, + mode, bpc); + if (ret) + continue; + + vc4_state->output_bpc = bpc; + + drm_dbg(dev, + "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n", + mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), + vc4_state->output_bpc, + vc4_state->pixel_rate); + + break; + } + + return ret; +} + #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL @@ -1351,8 +1388,7 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, pixel_rate = mode->clock * 1000; } - ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, mode, - conn_state->max_bpc); + ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode); if (ret) return ret; diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 31b7d27deb8e..05d2b0eeaa9b 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -218,7 +218,8 @@ struct vc4_hdmi { bool scdc_enabled; /** - * @output_bpc: BPC currently being used. Protected by @mutex. + * @output_bpc: Copy of @vc4_connector_state.output_bpc for use + * outside of KMS hooks. Protected by @mutex. */ unsigned int output_bpc; }; @@ -240,6 +241,7 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder) struct vc4_hdmi_connector_state { struct drm_connector_state base; unsigned long long pixel_rate; + unsigned int output_bpc; }; static inline struct vc4_hdmi_connector_state * From patchwork Thu Jan 27 14:10:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12726837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 89506C433EF for ; Thu, 27 Jan 2022 14:10:47 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DA15E10EEF7; Thu, 27 Jan 2022 14:10:45 +0000 (UTC) Received: from new1-smtp.messagingengine.com (new1-smtp.messagingengine.com [66.111.4.221]) by gabe.freedesktop.org (Postfix) with ESMTPS id 479A410EEF0 for ; Thu, 27 Jan 2022 14:10:37 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id A17C85805AF; Thu, 27 Jan 2022 09:10:36 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 27 Jan 2022 09:10:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm2; bh=c6ZI4zhtK6z4WsaGAX0xmBAGjwYLaA 1iMstdxov7iUU=; b=ee55b/yAuEIA9CPk4nh50AWVEt7IhOgMFJDqJebeim+4zf bbBQZtO9A+RNFkptPCcVYUmJ31eaWubhVBoiiVbTxdSZK8ACkiA/1q0ZVoGVzLRk 4AEBaRQpH/DTmavtAJLhWY3NLCMB8wRJoLj0TSfFJw3aS+2ejHOMExCoL5aUGlUV 7NOBvJcV6GykoE3HC76D8MDBcu56k0xvhXTe6lfeZjnpGU598P+dtiFBsEB9tcHM k14cLD3xvUDypFwJ/q6GPOUcs9JjG/NSR/KnI/S7HH74qiIcjSRvgf6RPsgkdU99 0cLKzDpZ9yNrynxnckZq8RqbO5tUTXRxSZ/ba5xg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=c6ZI4z htK6z4WsaGAX0xmBAGjwYLaA1iMstdxov7iUU=; b=GoXy9p1prwwvwzTKhWCdiP /upEiAQhy+tPZmg35nKpdIx1zi8WH5eCRURc5Zjrr3YVLvsZnKbwhfDZ0O/t2lFV olHyRafVw7b6i5NDKT9+N4LZycjJt+jme0sFT9UGmtAzEUNbQGavFx0J8YrVZI2y fFTHxi6Uz3+j6vG55RvoYXbCD5GPTOB/fmsxN49gHxq5uQQvKkGvd3fdEfS7CTiL zEulwfRB30smYLR+HZqVZ5t/CtI9/uxM8rT/T09zTF3FautAjbVBl67IuTdiG6yI N1uXpcS89hNgMEaaklCqvcfglSojyytVVmlZOV4jHQk9rtqUb8diMhALTK3V9PrQ == X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrfeefgdeiudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrgihimhgv ucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrghtth gvrhhnpedvkeelveefffekjefhffeuleetleefudeifeehuddugffghffhffehveevheeh vdenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrg igihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 27 Jan 2022 09:10:36 -0500 (EST) From: Maxime Ripard To: Maarten Lankhorst , Thomas Zimmermann , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 6/6] drm/vc4: hdmi: Support HDMI YUV output Date: Thu, 27 Jan 2022 15:10:21 +0100 Message-Id: <20220127141021.302482-7-maxime@cerno.tech> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220127141021.302482-1-maxime@cerno.tech> References: <20220127141021.302482-1-maxime@cerno.tech> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Tim Gover , Dave Stevenson , Werner Sembach , dri-devel@lists.freedesktop.org, Phil Elwell Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" In addition to the RGB444 output, the BCM2711 HDMI controller supports the YUV444 and YUV422 output formats. Let's add support for them in the driver, but still use RGB as the preferred format. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 289 ++++++++++++++++++++++++++-- drivers/gpu/drm/vc4/vc4_hdmi.h | 14 ++ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 6 + drivers/gpu/drm/vc4/vc4_regs.h | 16 ++ 4 files changed, 309 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 3ce002e485ce..787ddc5ba7d7 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -99,15 +99,30 @@ #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) +static const char * const output_format_str[] = { + [VC4_HDMI_OUTPUT_RGB] = "RGB", + [VC4_HDMI_OUTPUT_YUV420] = "YUV 4:2:0", + [VC4_HDMI_OUTPUT_YUV422] = "YUV 4:2:2", + [VC4_HDMI_OUTPUT_YUV444] = "YUV 4:4:4", +}; + +static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt) +{ + if (fmt >= ARRAY_SIZE(output_format_str)) + return "invalid"; + + return output_format_str[fmt]; +} static unsigned long long vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, - unsigned int bpc); + unsigned int bpc, enum vc4_hdmi_output_format fmt); static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, - unsigned int bpc) + unsigned int bpc, + enum vc4_hdmi_output_format fmt) { - unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); + unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); return clock > HDMI_14_MAX_TMDS_CLK; } @@ -280,7 +295,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) struct drm_display_mode *mode; list_for_each_entry(mode, &connector->probed_modes, head) { - if (vc4_hdmi_mode_needs_scrambling(mode, 8)) { + if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) { drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz."); drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60."); } @@ -337,6 +352,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector) new_state->base.max_bpc = 8; new_state->base.max_requested_bpc = 8; + new_state->output_format = VC4_HDMI_OUTPUT_RGB; drm_atomic_helper_connector_tv_reset(connector); } @@ -353,6 +369,7 @@ vc4_hdmi_connector_duplicate_state(struct drm_connector *connector) new_state->pixel_rate = vc4_state->pixel_rate; new_state->output_bpc = vc4_state->output_bpc; + new_state->output_format = vc4_state->output_format; __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); return &new_state->base; @@ -496,11 +513,38 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret); } +static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame, + enum vc4_hdmi_output_format fmt) +{ + switch (fmt) { + case VC4_HDMI_OUTPUT_RGB: + frame->colorspace = HDMI_COLORSPACE_RGB; + break; + + case VC4_HDMI_OUTPUT_YUV420: + frame->colorspace = HDMI_COLORSPACE_YUV420; + break; + + case VC4_HDMI_OUTPUT_YUV422: + frame->colorspace = HDMI_COLORSPACE_YUV422; + break; + + case VC4_HDMI_OUTPUT_YUV444: + frame->colorspace = HDMI_COLORSPACE_YUV444; + break; + + default: + break; + } +} + static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); struct drm_connector *connector = &vc4_hdmi->connector; struct drm_connector_state *cstate = connector->state; + struct vc4_hdmi_connector_state *vc4_state = + conn_state_to_vc4_hdmi_conn_state(cstate); const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; union hdmi_infoframe frame; int ret; @@ -520,6 +564,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) HDMI_QUANTIZATION_RANGE_FULL : HDMI_QUANTIZATION_RANGE_LIMITED); drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate); + vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format); drm_hdmi_avi_infoframe_bars(&frame.avi, cstate); vc4_hdmi_write_infoframe(encoder, &frame); @@ -622,7 +667,9 @@ static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder) if (!vc4_hdmi_supports_scrambling(encoder, mode)) return; - if (!vc4_hdmi_mode_needs_scrambling(mode, vc4_hdmi->output_bpc)) + if (!vc4_hdmi_mode_needs_scrambling(mode, + vc4_hdmi->output_bpc, + vc4_hdmi->output_format)) return; drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); @@ -817,6 +864,38 @@ static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = { { 0x0000, 0x0000, 0x1b80, 0x0400 }, }; +/* + * Conversion between Full Range RGB and Full Range YUV422 using the + * BT.709 Colorspace + * + * [ 0.212639 0.715169 0.072192 0 ] + * [ -0.117208 -0.394207 0.511416 128 ] + * [ 0.511416 -0.464524 -0.046891 128 ] + * + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets + */ +static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709[3][4] = { + { 0x06ce, 0x16e3, 0x024f, 0x0000 }, + { 0xfc41, 0xf364, 0x105e, 0x2000 }, + { 0x105e, 0xf124, 0xfe81, 0x2000 }, +}; + +/* + * Conversion between Full Range RGB and Full Range YUV444 using the + * BT.709 Colorspace + * + * [ -0.117208 -0.394207 0.511416 128 ] + * [ 0.511416 -0.464524 -0.046891 128 ] + * [ 0.212639 0.715169 0.072192 0 ] + * + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets + */ +static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709[3][4] = { + { 0xfc41, 0xf364, 0x105e, 0x2000 }, + { 0x105e, 0xf124, 0xfe81, 0x2000 }, + { 0x06ce, 0x16e3, 0x024f, 0x0000 }, +}; + static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi, const u16 coeffs[3][4]) { @@ -834,19 +913,53 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, struct drm_connector_state *state, const struct drm_display_mode *mode) { + struct vc4_hdmi_connector_state *vc4_state = + conn_state_to_vc4_hdmi_conn_state(state); unsigned long flags; + u32 if_cfg = 0; + u32 if_xbar = 0x543210; + u32 csc_chan_ctl = 0; u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM, VC5_MT_CP_CSC_CTL_MODE); spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); + switch (vc4_state->output_format) { + case VC4_HDMI_OUTPUT_YUV444: + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709); + break; - if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb); - else - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity); + case VC4_HDMI_OUTPUT_YUV422: + csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD, + VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) | + VC5_MT_CP_CSC_CTL_USE_444_TO_422 | + VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION; + csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE, + VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP); + + if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY, + VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422); + + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709); + break; + + case VC4_HDMI_OUTPUT_RGB: + if_xbar = 0x354021; + + if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb); + else + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity); + break; + + default: + break; + } + + HDMI_WRITE(HDMI_VEC_INTERFACE_CFG, if_cfg); + HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, if_xbar); + HDMI_WRITE(HDMI_CSC_CHANNEL_CTL, csc_chan_ctl); HDMI_WRITE(HDMI_CSC_CTL, csc_ctl); spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); @@ -972,6 +1085,15 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, break; } + /* + * YCC422 is always 36-bit and not considered deep colour so + * doesn't signal in GCP. + */ + if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) { + gcp = 4; + gcp_en = false; + } + reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1); reg &= ~(VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_MASK | VC5_HDMI_DEEP_COLOR_CONFIG_1_COLOR_DEPTH_MASK); @@ -1269,12 +1391,97 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, mutex_lock(&vc4_hdmi->mutex); vc4_hdmi->output_bpc = vc4_state->output_bpc; + vc4_hdmi->output_format = vc4_state->output_format; memcpy(&vc4_hdmi->saved_adjusted_mode, &crtc_state->adjusted_mode, sizeof(vc4_hdmi->saved_adjusted_mode)); mutex_unlock(&vc4_hdmi->mutex); } +static bool +vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi, + const struct drm_display_info *info, + const struct drm_display_mode *mode, + unsigned int format, unsigned int bpc) +{ + struct drm_device *dev = vc4_hdmi->connector.dev; + u8 vic = drm_match_cea_mode(mode); + + if (vic == 1 && bpc != 8) { + drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc); + return false; + } + + if (!info->is_hdmi && + (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) { + drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n"); + return false; + } + + switch (format) { + case VC4_HDMI_OUTPUT_RGB: + drm_dbg(dev, "RGB Format, checking the constraints.\n"); + + if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444)) + return false; + + if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) { + drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n"); + return false; + } + + if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) { + drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n"); + return false; + } + + drm_dbg(dev, "RGB format supported in that configuration.\n"); + + return true; + + case VC4_HDMI_OUTPUT_YUV422: + drm_dbg(dev, "YUV422 format, checking the constraints.\n"); + + if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) { + drm_dbg(dev, "Sink doesn't support YUV422.\n"); + return false; + } + + if (bpc != 12) { + drm_dbg(dev, "YUV422 only supports 12 bpc.\n"); + return false; + } + + drm_dbg(dev, "YUV422 format supported in that configuration.\n"); + + return true; + + case VC4_HDMI_OUTPUT_YUV444: + drm_dbg(dev, "YUV444 format, checking the constraints.\n"); + + if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) { + drm_dbg(dev, "Sink doesn't support YUV444.\n"); + return false; + } + + if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) { + drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n"); + return false; + } + + if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) { + drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n"); + return false; + } + + drm_dbg(dev, "YUV444 format supported in that configuration.\n"); + + return true; + } + + return false; +} + static enum drm_mode_status vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, unsigned long long clock) @@ -1296,13 +1503,17 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, static unsigned long long vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, - unsigned int bpc) + unsigned int bpc, + enum vc4_hdmi_output_format fmt) { unsigned long long clock = mode->clock * 1000; if (mode->flags & DRM_MODE_FLAG_DBLCLK) clock = clock * 2; + if (fmt == VC4_HDMI_OUTPUT_YUV422) + bpc = 8; + return clock * bpc / 8; } @@ -1310,11 +1521,11 @@ static int vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, struct vc4_hdmi_connector_state *vc4_state, const struct drm_display_mode *mode, - unsigned int bpc) + unsigned int bpc, unsigned int fmt) { unsigned long long clock; - clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); + clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK) return -EINVAL; @@ -1323,11 +1534,56 @@ vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, return 0; } +static int +vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi, + struct vc4_hdmi_connector_state *vc4_state, + const struct drm_display_mode *mode, + unsigned int bpc) +{ + struct drm_device *dev = vc4_hdmi->connector.dev; + const struct drm_connector *connector = &vc4_hdmi->connector; + const struct drm_display_info *info = &connector->display_info; + unsigned int format; + + drm_dbg(dev, "Trying with an RGB output\n"); + + format = VC4_HDMI_OUTPUT_RGB; + if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) { + int ret; + + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, + mode, bpc, format); + if (!ret) { + vc4_state->output_format = format; + return 0; + } + } + + drm_dbg(dev, "Failed, Trying with an YUV422 output\n"); + + format = VC4_HDMI_OUTPUT_YUV422; + if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) { + int ret; + + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, + mode, bpc, format); + if (!ret) { + vc4_state->output_format = format; + return 0; + } + } + + drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n"); + + return -EINVAL; +} + static int vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi, struct vc4_hdmi_connector_state *vc4_state, const struct drm_display_mode *mode) { + struct drm_device *dev = vc4_hdmi->connector.dev; struct drm_connector_state *conn_state = &vc4_state->base; unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12); unsigned int bpc; @@ -1336,17 +1592,18 @@ vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi, for (bpc = max_bpc; bpc >= 8; bpc -= 2) { drm_dbg(dev, "Trying with a %d bpc output\n", bpc); - ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, - mode, bpc); + ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state, + mode, bpc); if (ret) continue; vc4_state->output_bpc = bpc; drm_dbg(dev, - "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n", + "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n", mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), vc4_state->output_bpc, + vc4_hdmi_output_fmt_str(vc4_state->output_format), vc4_state->pixel_rate); break; diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 05d2b0eeaa9b..f015ae80c5d4 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -117,6 +117,13 @@ struct vc4_hdmi_audio { bool streaming; }; +enum vc4_hdmi_output_format { + VC4_HDMI_OUTPUT_RGB, + VC4_HDMI_OUTPUT_YUV422, + VC4_HDMI_OUTPUT_YUV444, + VC4_HDMI_OUTPUT_YUV420, +}; + /* General HDMI hardware state. */ struct vc4_hdmi { struct vc4_hdmi_audio audio; @@ -222,6 +229,12 @@ struct vc4_hdmi { * outside of KMS hooks. Protected by @mutex. */ unsigned int output_bpc; + + /** + * @output_format: Copy of @vc4_connector_state.output_format + * for use outside of KMS hooks. Protected by @mutex. + */ + enum vc4_hdmi_output_format output_format; }; static inline struct vc4_hdmi * @@ -242,6 +255,7 @@ struct vc4_hdmi_connector_state { struct drm_connector_state base; unsigned long long pixel_rate; unsigned int output_bpc; + enum vc4_hdmi_output_format output_format; }; static inline struct vc4_hdmi_connector_state * diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h index fc971506bd4f..a040356b6bdc 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h @@ -54,6 +54,7 @@ enum vc4_hdmi_field { HDMI_CSC_24_23, HDMI_CSC_32_31, HDMI_CSC_34_33, + HDMI_CSC_CHANNEL_CTL, HDMI_CSC_CTL, /* @@ -119,6 +120,7 @@ enum vc4_hdmi_field { HDMI_TX_PHY_POWERDOWN_CTL, HDMI_TX_PHY_RESET_CTL, HDMI_TX_PHY_TMDS_CLK_WORD_SEL, + HDMI_VEC_INTERFACE_CFG, HDMI_VEC_INTERFACE_XBAR, HDMI_VERTA0, HDMI_VERTA1, @@ -244,6 +246,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = { VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4), VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc), + VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec), VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0), VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000), @@ -289,6 +292,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = { VC5_CSC_REG(HDMI_CSC_24_23, 0x010), VC5_CSC_REG(HDMI_CSC_32_31, 0x014), VC5_CSC_REG(HDMI_CSC_34_33, 0x018), + VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c), }; static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = { @@ -324,6 +328,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = { VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4), VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc), + VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec), VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0), VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000), @@ -369,6 +374,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = { VC5_CSC_REG(HDMI_CSC_24_23, 0x010), VC5_CSC_REG(HDMI_CSC_32_31, 0x014), VC5_CSC_REG(HDMI_CSC_34_33, 0x018), + VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c), }; static inline diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 33410718089e..c8210247cf24 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -774,11 +774,27 @@ enum { # define VC4_HD_CSC_CTL_RGB2YCC BIT(1) # define VC4_HD_CSC_CTL_ENABLE BIT(0) +# define VC5_MT_CP_CSC_CTL_USE_444_TO_422 BIT(6) +# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_MASK \ + VC4_MASK(5, 4) +# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD \ + 3 +# define VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION BIT(3) # define VC5_MT_CP_CSC_CTL_ENABLE BIT(2) # define VC5_MT_CP_CSC_CTL_MODE_MASK VC4_MASK(1, 0) +# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_MASK \ + VC4_MASK(7, 6) +# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE \ + 2 + # define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1) +# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_MASK \ + VC4_MASK(3, 2) +# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY \ + 2 + /* HVS display list information. */ #define HVS_BOOTLOADER_DLIST_END 32