From patchwork Mon Feb 12 13:12:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199745 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2417811dyd; Mon, 12 Feb 2024 05:14:37 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX2RsiNRuACCtNQuvGs4+7ajdxBp8WISj9dNJ6HWFx6Zf9S/8/Bt/IXsxm1UhIw3wg2kzGZ6qmjeUsR+iO46RFAxwGcLA== X-Google-Smtp-Source: AGHT+IGjNVordeQxcoT7yOgjsCMf41dXVGp93lNsN+oFDe6AhI/AuQDuAkELqNrzPZWdawtUN+nK X-Received: by 2002:aa7:cd45:0:b0:561:1f4:cb5e with SMTP id v5-20020aa7cd45000000b0056101f4cb5emr5184822edw.7.1707743677266; Mon, 12 Feb 2024 05:14:37 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743677; cv=pass; d=google.com; s=arc-20160816; b=IWTE15TQQPXDvPT/LKGuoA5oRu0FGNBAPnyIxw+41yb9w95aJwxICuuK12HRqAuOeg ltthHJwe9mxrldt8ZXlRltHhVybmZtyV/SMyw1K8+RTdoZqxuZxjxwSc9nDg4O0Jxxe5 v6r2r/wyO+rx83yBBRAmwO+rCF/Z8npN9/QxVHNRXQKBVd1aP+/BGO5hW1DeueOtTsyW SI6u8c9OOddvr07sapBi8kdShtgJYoGPSJkTMpuIeUg0As1x0w7RJnOtxwF80Z4VVDF9 2vipgN/mg4IddrTd9Rs0n0jF+8gT4iVu1RnNGS8MCrNz3qYv5ttmdrdG1JBIeCEO0r3d MaPw== 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=YY6jqH0GE/prsNq6RALQ2aHBNl6p7Ysf96x0HPnfJ1E=; fh=+uKav86NSGE6U/bZ9UN2mu7sk/E5SdTAEjbVMxnX+b0=; b=EAL89eaf/JnsgOakcyxWPw3xg+xQfjdAGmqVG9sO3VlVoAKq9bTtSLU3bKwQCdqDT2 9wMCleoTu1Gc1nEaGalW3OIZzYXJh3a0iLMlkQSXGfH9L/veKOOpXJzEH9dv8XvfKe0c EVcgSOeDgTHJ3+046ZkM9Al4CPRq5nqQdw0fNcTCAttwCZq+IIsGOW7uQa9az6PZMmIH W5xaSiG6ycoOCnXG851bgGBDqiWIANcoEheyYuJ++LWz0Ej1LepPSRfcntSA+rBGwDYt ZE7OPONVtEYMcEUPZKUjuGJvrqOaiwTIS54DZBWkKGp2EG0AUGkDMwY8wI5mpuE0MrXh q7RQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=agMK6zpv; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61615-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61615-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWyvMb4GqofOi+Neyz30+laz+ahfZT7gxIOYfH5Clse+QhkswpYOp7F6eZaVFOnUexYwFCQ95OR8cLrAfS3+9EDKpvbvw== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id dj17-20020a05640231b100b0055fcf35fb3fsi2632731edb.265.2024.02.12.05.14.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:14:37 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61615-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=agMK6zpv; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61615-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61615-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 am.mirrors.kernel.org (Postfix) with ESMTPS id DA1131F21754 for ; Mon, 12 Feb 2024 13:14:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0DD463B78D; Mon, 12 Feb 2024 13:13:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="agMK6zpv" 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 4D0223AC1A; Mon, 12 Feb 2024 13:13:31 +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=1707743613; cv=none; b=X1DX2Ci5fA0N/uz2A5QMLVYiXxS3jNnSwVlUDQGfGdYht8ruas5ZkS/4uclWdnORfUNB8tF47bu7ViuZQfegaC+KsM49c4NLHbMyV5obpl2RJnpx/O2ET8voaWiv3JgqszizYaweTjGE49naVA3Y3G3mWqOdGHforcYvy7GsfQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743613; c=relaxed/simple; bh=81lEe31K2YU0V4EnFq3xxesUJy/t9LyYJwWTzno5+Rg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=prttT1JfYoyfYAedA2SvHqieJamueWHayyh+mjjjAY9HM/WKI6YTis065IucKK8taOrOUCc/TtmIFJuiCMWJq3PFgDoHFOB/v6B0IeS1Bd4M+KfpQeDYr/e35j+L5dTCRTJcTONUsJFmReuJYoDkPkj13+Q3ltXPxtyIklGJfnM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=agMK6zpv; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 56B5EC43399; Mon, 12 Feb 2024 13:13:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743611; bh=81lEe31K2YU0V4EnFq3xxesUJy/t9LyYJwWTzno5+Rg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=agMK6zpvNkiF/exIgCw6MWEwPTwthUWbp7r55Qi9e+QM6MF82pxE8GXReInl+uxkt UPWPI2UPVwJcvRL6hcKHnuiwe6Y+Jpn/I2OcLbGU7AwRCgF7I7fzwp4uitSHUGp++B w3xGCk7/verBbLy5tcOGxTqnUbzKS195N15pPsSVHCsjMgpmDkilLn3p/77QjXaGkr CCF4AZ+czm+PdhZ6fMmv1A2OgWRmLC5ew1XN+SJMi5bk20J43QtnZqe3PjjtnRN2mb vduSytTdtFAhd1qL95znRl0o40rcMk0BbNhr3K+n7m3vgEK4f2dYKr3AklojLCZaLM GiHMhmb9msFog== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:44 +0100 Subject: [PATCH v6 01/36] drm/tests: helpers: Include missing drm_drv header Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-1-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=857; i=mripard@kernel.org; h=from:subject:message-id; bh=81lEe31K2YU0V4EnFq3xxesUJy/t9LyYJwWTzno5+Rg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJONyhB9FcElXrd69yPRXoObCkusKM1a2Hv5oaXJ4z +Hk8hCXjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEykKonhv0fno5pP9Vc7D/+Z d1Fy4WvWJZy9e/cde6KwQjduwbKZhYGMDGdOfGx44vFtk85ti+fdSxJK35UELNHaWctYFPVA8UI PFzcA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699033933429760 X-GMAIL-MSGID: 1790699033933429760 We have a few functions declared in our kunit helpers header, some of them dereferencing the struct drm_driver. However, we don't include the drm_drv.h header file defining that structure, leading to compilation errors if we don't include both headers. Fixes: d98780310719 ("drm/tests: helpers: Allow to pass a custom drm_driver") Signed-off-by: Maxime Ripard --- include/drm/drm_kunit_helpers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h index ba483c87f0e7..3ae19892229d 100644 --- a/include/drm/drm_kunit_helpers.h +++ b/include/drm/drm_kunit_helpers.h @@ -3,6 +3,8 @@ #ifndef DRM_KUNIT_HELPERS_H_ #define DRM_KUNIT_HELPERS_H_ +#include + #include #include From patchwork Mon Feb 12 13:12:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199780 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425909dyd; Mon, 12 Feb 2024 05:28:25 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU/Q+pVQ+YZt8xsIAlzP0IvY/kPrTyjWwc+iVD/Zcp2eO5sL4xEYQZTzIZXHtG54hKebXdoyoG7KHAlLxQjUwaJkLl2lg== X-Google-Smtp-Source: AGHT+IF7BYp94GLcMDFWE2JhQ6PnKTFl8bLKZXTnYIjtfafcS39KXHwxNXkFMYGmJmA4u0JOgxZq X-Received: by 2002:a17:903:2448:b0:1d7:5943:21b8 with SMTP id l8-20020a170903244800b001d7594321b8mr7968554pls.16.1707744505468; Mon, 12 Feb 2024 05:28:25 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744505; cv=pass; d=google.com; s=arc-20160816; b=vPaU4jh7c1ORHN9sFrLbdS8MtCH8IBrgsePyZHF/Wfu40AAycE2qD+lU2GcgV4daGj ERW3rbG+PAIqPj4ivHATdS1ciq+7nXbwLvWE0lh2OuNfJibtSbz40gk48hHW/IEJSfrs 4Sn45U6f43LI+7aZ2QjLp3iAwerdiRVSnOyLcziTSvTDQJ/2S5Da8V2T2nTmXjOtHjKK SP6qrwtqoM9so0afC4yMBrtUt/4fiNEcCNHZ6jSqsTudKKFbdhXsnXlletd+UEqVwkjw hooAMdeKwC2A/PDInoZwyrXMNL0+G6WdbhiUy2uZh6VQ7on7V/Pee6UMpCSI6R3J22RC +PzA== 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=KaZDzbh/RnR+FHcH2Ga6aFpETudP2lhcIzurRUqpQR0=; fh=zxymFzcjEWPzZ6g9cCRnMWS8AFdvcRl+V4Z95cYXXd8=; b=If0AOrg5tYWenAE6xPtl7dZ6qctF0ZQ9NDC/kWXZuumWSdStQHxD3y2UZE0enKLcpX A5WfgnbcsWN8agTCr+Yq9h+y0lux566SzHNlldkXA8wcGBUUK0zh5KPTzHng2KhvO3ps 48W0g7//YS0Ml8Iqihpg+T5sx9lZtNyXLiYpg83tTkKseOE9/CCoUpUdthx5WbT9y581 dWgq0zcuK3jz3qj+U1vU5pCmUQn80p6qbYc20KSRr9F/3TfmrMo/vO13Rn2GJRwvb4s4 9KW92SuqorIWQYqmY6J1h3Ukxa19Oo8fHFbusP3wHXI5+fVQg6YQD7SC2guppLxgx3rA mdPg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="HnWjb3/T"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61616-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61616-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWWnL932Fgg5Tb++wu+rIWFeauOXJln2umiVhhVQKx8cyDKtXXsIaKeZq629Y5s3WhTbKVOUXIn2J0U93pDn9aSRuKwBw== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id c11-20020a170902c1cb00b001d9b3ef8311si250098plc.354.2024.02.12.05.28.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:28:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61616-ouuuleilei=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="HnWjb3/T"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61616-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61616-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 65697B224DF for ; Mon, 12 Feb 2024 13:14:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4B1243BB20; Mon, 12 Feb 2024 13:13:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HnWjb3/T" 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 7F6243B194; Mon, 12 Feb 2024 13:13:34 +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=1707743614; cv=none; b=mNgM8qsGjRqJO3U8NrNHPLpTpiVKGxHh2jfvEpQyAmNc3PfpM6qeeBwk3DVclRxVMYpetHvAWhXZR3BY5h966qXGjcB9uk6URxcm2oIoXpPzr0nGYh/tl9mC+g6D9zDAVTbdY63tAslhpnMw8ni71QbJx9RvoxU33LHJTkpGrwU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743614; c=relaxed/simple; bh=FmMsFeXhutf6tMibK52IysTNfOw//ufgAXxQlMPss38=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bvYFQIHmtcdRSNMGpi0PZ1WO6OXi0d07QP3BNPRZsGZ19doolOx5gLFOkPqDH+Ird291l+WdkFyB7X7fEF2msYAEyRHNqOAwmtu9px4nnbkUfM7aAXXX4M+jp1KXeiX+DHPdctGiMfFF+ePx5wq042Vo3MDI7gvu2BeWsQKpBPw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HnWjb3/T; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03E52C433F1; Mon, 12 Feb 2024 13:13:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743614; bh=FmMsFeXhutf6tMibK52IysTNfOw//ufgAXxQlMPss38=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HnWjb3/TpoD5LsTLuSpJEczOHDyGGzoRzrosplO5/gP+842/Wupq9xSmxNvb1X+Bk KxfKZaxXyPEuXUr/OW87NXXBXtNH9M8R+Fd407emglF3hDAi2qeFrA+CbabjGt88AB NLBSrsrrnhSnJcW2heCyYQrI9apD3TV/sHAgp19Dh59lSGCuHtR+YLSDZ6TD2u/Vkh BF1ImkqsXBCwXMIIu2fOixiupsXFeY137HMl93YRpQgIPYX0lY7fipNBsI2cpqDAl7 jDvqCjQLpj36mgSmAVNHrZ5uJiQOlXmm9UwZKxoI/ljZes9lDGH+/u11gOhc5vuGtJ +vWRroeZ4argg== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:45 +0100 Subject: [PATCH v6 02/36] drm/tests: helpers: Add atomic helpers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-2-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1086; i=mripard@kernel.org; h=from:subject:message-id; bh=FmMsFeXhutf6tMibK52IysTNfOw//ufgAXxQlMPss38=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJOM9l5jtVJtx9t9V/6R5VxWmRbNefFPn/TB67pOGF 1nzV7X4dZSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAivdWMDH85cgOzrlTdUZI+ rqLhNmWh7bdbm+79VTFm2FrGyrehUpvhv2syS8bcveE/KjhfGlYoGrrMkPgl/rN1b4HxnnkSb9Z xcAEA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699902627546979 X-GMAIL-MSGID: 1790699902627546979 The mock device we were creating was missing any of the driver-wide helpers. That was fine before since we weren't testing the atomic state path, but we're going to start, so let's use the default implementations. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c index ca4f8e4c5d5d..4fb11b938bc1 100644 --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -14,6 +15,8 @@ #define KUNIT_DEVICE_NAME "drm-kunit-mock-device" static const struct drm_mode_config_funcs drm_mode_config_funcs = { + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, }; /** From patchwork Mon Feb 12 13:12:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199746 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2418165dyd; Mon, 12 Feb 2024 05:15:07 -0800 (PST) X-Google-Smtp-Source: AGHT+IHMMbA7CRlj1E/VASP/XtZJI2NY3llotIJSU0Wt1j6z+objqup/y6DT8IARRSY3606OGkcO X-Received: by 2002:a05:6808:200f:b0:3bf:f34f:ee3b with SMTP id q15-20020a056808200f00b003bff34fee3bmr8096810oiw.54.1707743707039; Mon, 12 Feb 2024 05:15:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743707; cv=pass; d=google.com; s=arc-20160816; b=IiNGq9lykcI7a8W6YjvjSVa6T5VWvgTKtW+EKnNIZ4YX0WidPbwXZZPcye0Mg1h8YT DmpuqHWypogXNDdNQgn1+xwez52DIBsTFhVZR2fRkshcwtCluIL1mNpJt8wo1r0AstUq LjapzESDfdvL5EIH6rF1tb/bZtIlfjebmtpJbmEkDwxgfLggYcejvMdyQxLODgJuEL9g rn3QwL2r9u73o+5/HdbkCjzUjRJqeH2wRVg7GfkRhULo9vYW4F09XlJfhATUg1cuitvu tfpH5NjyWqyPhSOyoJNBhItC/9I3eEXe6PjDGkios5P353q4JeON77RcF3TarU0q/JJB AXSg== 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=0gV+jP6leWaWc+XhZzAtpYCDDzH/l7RayXml18sQqZc=; fh=qxNhjtzPeuKpaJMSl1k9D9vZzsZ4vCexYQsTTlJ5yxk=; b=vQN5OL0HZnYFl6ImBKzymAT3VPKiXZToQaBJa79fVX2jGT8QGjabCQvDkkxyifuwq2 MZh+QLgkWThE78Y9PAwR+iI0zr8ORvXT1E/yUrkKcfggX+uChcT8wvgYzp6PRLpVjwXD Hy6JMYOi4brrBSjjBcjkvrkJXUf7empLGSQGrC38UKvdTFP2acXTjsKM4NJ1fbho0L+O 1MrlWEgTb5RUZGYKpIYvMgn39lw7BMYGB0fRXQIyuXT4AsL6Yiuvm3lCjGi84d7tpWXH Z7Axrl8+MPXvZ4mUn7jtlBjSUrgalqptiQtOCCE6uSmWdC0DjlNIbM7Q1WgCEsMCzfkw qAdA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=OaehGzDH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61617-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61617-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWxSJ3S1Mz6vw9e6mBWtzWqwUdS8uc5mCIa6OZEP/UA+6bs3D6tHZDAoxPqCS+3noUGnwEeKSzxOiMfFMcqgaIfgAs5MQ== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id i6-20020a05620a0a0600b0078715367700si304233qka.64.2024.02.12.05.15.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:15:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61617-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=OaehGzDH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61617-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61617-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id BEA591C21D12 for ; Mon, 12 Feb 2024 13:15:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B855E3BB4D; Mon, 12 Feb 2024 13:13:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OaehGzDH" 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 941063BB27; Mon, 12 Feb 2024 13:13:37 +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=1707743617; cv=none; b=r0QqQYcMdEgA0Fm6lAM4PlI4BcoizRR7VbaKvyUz0ARWMAvhnWKps9o8GN10e5nQVCDtbhPJKOKbO4n3URXubyWqwRF6jz4K2cCb0sdCoLd7Rhg/r81dnzBbkG6lYVrJ84MoqXNt+y0jXvYsgX6Ign8s20IvD7+AkwkpL5t0v/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743617; c=relaxed/simple; bh=BT0Fi2BfGOtTeKlub/+OMF8A+xXJm9y8g7PRHJ/dxN4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Sr/WZbJDcjOPl8J5J3ejjNCyUN8annX3VXVzFi8VuKsillqlUIju+qVLqqgA+Fswprppc2nO1ha+xsKggZPshduKAqCNDlsGeRwIl9MAjcEn+5awV5MUsdlREFZDoSaERhaA2Cq1kxqiLVD1iu/JU2dFrjXo0T0kMhXxnpo9PHA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OaehGzDH; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id C074BC433F1; Mon, 12 Feb 2024 13:13:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743617; bh=BT0Fi2BfGOtTeKlub/+OMF8A+xXJm9y8g7PRHJ/dxN4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OaehGzDHObdd9hcC4BKvXyoxEk0UIpTOUWVu3luHU53yYOHIsHos9jxbQ9T5VAasN Yvw9bw5QANAjlkT+O6fKYoy86TotkEJaJOf1/shounD/fhGdg//LMarFks+OZY9cyh QhNl4R5/9ASMdCAwxYLMqrDU9vvoNS46TgA90DxdHeE9joSRzU2KKtArLrAxsrEZw8 xOancEyUJqNNZ8kN2T8oXWAwH7eHYYd1sH/mf35lsSXjZzWgdEVMJI6V3+oo5p5Mhs PjxLOjcTYTFZE44Q7CUDvLFsQskE/9/+9CZn0UBRDxZUlDvNgtfrmL8O8CJQ5mH8NF c40MMccOEPgDQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:46 +0100 Subject: [PATCH v6 03/36] drm/tests: Add helper to create mock plane Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-3-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4849; i=mripard@kernel.org; h=from:subject:message-id; bh=BT0Fi2BfGOtTeKlub/+OMF8A+xXJm9y8g7PRHJ/dxN4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJOMzC3cc3bXjevlzmwoR6wT5h7psCVG7jqql6SnUx a76lVPSUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgImYTmT4K6u5qHehZ6Go6+nL M9YsZniwztNxtd0cm47CfVujmCN3vmdkaN81aaPbE61nvZNTHQUbT3dWfrwes3D6lQgvle4VPd3 zWQA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699065186052791 X-GMAIL-MSGID: 1790699065186052791 We're going to need a full-blown, functional, KMS device to test more components of the atomic modesetting infrastructure. Let's add a new helper to create a dumb, mocked, primary plane. By default, it will create a linear XRGB8888 plane, using the default helpers. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_kunit_helpers.c | 85 +++++++++++++++++++++++++++++++ include/drm/drm_kunit_helpers.h | 11 ++++ 2 files changed, 96 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c index 4fb11b938bc1..32dc8354641a 100644 --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -164,5 +165,89 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test, } EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc); +static const uint32_t default_plane_formats[] = { + DRM_FORMAT_XRGB8888, +}; + +static const uint64_t default_plane_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + +static const struct drm_plane_helper_funcs default_plane_helper_funcs = { +}; + +static const struct drm_plane_funcs default_plane_funcs = { + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .reset = drm_atomic_helper_plane_reset, +}; + +/** + * drm_kunit_helper_create_primary_plane - Creates a mock primary plane for a KUnit test + * @test: The test context object + * @drm: The device to alloc the plane for + * @funcs: Callbacks for the new plane. Optional. + * @helper_funcs: Helpers callbacks for the new plane. Optional. + * @formats: array of supported formats (DRM_FORMAT\_\*). Optional. + * @num_formats: number of elements in @formats + * @modifiers: array of struct drm_format modifiers terminated by + * DRM_FORMAT_MOD_INVALID. Optional. + * + * This allocates and initializes a mock struct &drm_plane meant to be + * part of a mock device for a KUnit test. + * + * Resources will be cleaned up automatically. + * + * @funcs will default to the default helpers implementations. + * @helper_funcs will default to an empty implementation. @formats will + * default to XRGB8888 only. @modifiers will default to a linear + * modifier only. + * + * Returns: + * A pointer to the new plane, or an ERR_PTR() otherwise. + */ +struct drm_plane * +drm_kunit_helper_create_primary_plane(struct kunit *test, + struct drm_device *drm, + const struct drm_plane_funcs *funcs, + const struct drm_plane_helper_funcs *helper_funcs, + const uint32_t *formats, + unsigned int num_formats, + const uint64_t *modifiers) +{ + struct drm_plane *plane; + + if (!funcs) + funcs = &default_plane_funcs; + + if (!helper_funcs) + helper_funcs = &default_plane_helper_funcs; + + if (!formats || !num_formats) { + formats = default_plane_formats; + num_formats = ARRAY_SIZE(default_plane_formats); + } + + if (!modifiers) + modifiers = default_plane_modifiers; + + plane = __drmm_universal_plane_alloc(drm, + sizeof(struct drm_plane), 0, + 0, + funcs, + formats, + num_formats, + default_plane_modifiers, + DRM_PLANE_TYPE_PRIMARY, + NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane); + + drm_plane_helper_add(plane, helper_funcs); + + return plane; +} +EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane); + MODULE_AUTHOR("Maxime Ripard "); MODULE_LICENSE("GPL"); diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h index 3ae19892229d..38667d624aa8 100644 --- a/include/drm/drm_kunit_helpers.h +++ b/include/drm/drm_kunit_helpers.h @@ -10,6 +10,8 @@ #include struct drm_device; +struct drm_plane_funcs; +struct drm_plane_helper_funcs; struct kunit; struct device *drm_kunit_helper_alloc_device(struct kunit *test); @@ -99,4 +101,13 @@ drm_kunit_helper_atomic_state_alloc(struct kunit *test, struct drm_device *drm, struct drm_modeset_acquire_ctx *ctx); +struct drm_plane * +drm_kunit_helper_create_primary_plane(struct kunit *test, + struct drm_device *drm, + const struct drm_plane_funcs *funcs, + const struct drm_plane_helper_funcs *helper_funcs, + const uint32_t *formats, + unsigned int num_formats, + const uint64_t *modifiers); + #endif // DRM_KUNIT_HELPERS_H_ From patchwork Mon Feb 12 13:12:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199747 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2418490dyd; Mon, 12 Feb 2024 05:15:31 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX4jz29yDKaNfFddrkliabdqrFxfvvTV1CQ0Cz3Je2X5y4S9n6ga0WTMm0GGkYAlsJvstfwbUpTYW3g4t/72r0HR+1uaA== X-Google-Smtp-Source: AGHT+IG0/CtBXBV5/HVRoCcZJyQWYNLcpb82/Rj+gR1AKVV3CnB9yEk724h2J5S7YIu7HMWzbLXZ X-Received: by 2002:a05:6870:63a5:b0:21a:1267:30d3 with SMTP id t37-20020a05687063a500b0021a126730d3mr9620152oap.9.1707743731611; Mon, 12 Feb 2024 05:15:31 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743731; cv=pass; d=google.com; s=arc-20160816; b=Pt+Q8nJF+9OYXiSiDepXFgYMBDXPQlxOP/EXiNMI+DvXpjCdKKUMAp6u1uK9UKLCDh An8aKEdNnA8U4ZjTjSKOKrgsUFuZw2rB7jpjRJrghe0eHb8Qgw6OMstfvOHK8gLz/drl 0adHZbjgyZhstidVEed0/JrU8K3MkdIPDK8/QiAChEGVgOvpyTdZKopcShdLMQfzGCoc Wzvrqf3DN6wy7tL3EocuaA/omUDe8nNHXw/0rJ23RAG7wG9bj61mvwHFISL9Sw56CDvW cp4peJiPcjix7UFMNI4xqhQXCegzJNx/CKFDhJqDX2/69K5vTMtz2w5TYmc8RgOTZ9DL MahQ== 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=5jCNCEZkijY2gMgX5ESwXw5ZJ07xCb9uOO8R5C+MiiI=; fh=Cw1lQQmdjSAofWP4cACV94mLBHq7G7kmdi/9SG3NqpM=; b=mtXUBHs3I5YLyVFcebibMpNdzky0cQqmJ+27W5x4cXJY4Y1cKcSLcg6uuqIe0PvK6G l3/BSe0DgguZhfpZe2Bxk9BiiTNypslohY/EEVWKHxIkmowWESdQ3KXv1gkKHNZ/wHvR Bd2cBIj/jD3f32twSW3bDyTxLoZA0WTIrjcJ7uyvo14CV6n9dZFEx4Wq4l4Hz/yv38/4 c52sz+2Ut25mEN+lcckM7vxTObsuXnH5sxrXQW1ALXs0CC7F86dLRC9zRGi98lmJQXmF hQoJf3yZwMQRSsUWccwoY6QEsqYLz4gfBg3zDJ9sJLUXY+UtWLxwsK8ssVPGphHdPjq/ 3Vbg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Sp7HV+bv; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61618-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61618-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCUXZMToOxyFmUyIjz6Erft8k8sHwmgoPt0P9LvzR2OHDoF8HVS0NyUovmnS7N+fakYlyc7Hp858MloutXlUik9pMdtLTA== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id b4-20020ac84f04000000b0042c4aa6aa46si329631qte.186.2024.02.12.05.15.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:15:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61618-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Sp7HV+bv; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61618-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61618-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 0FA9D1C22C59 for ; Mon, 12 Feb 2024 13:15:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 328B93C470; Mon, 12 Feb 2024 13:13:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Sp7HV+bv" 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 4AE763BB3A; Mon, 12 Feb 2024 13:13:40 +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=1707743620; cv=none; b=M0le4P+0wEpDVzsuE/YByMpQYRcXmIhNqlY2rRiSxcNm2uV1c0AzI64OUJl0s11IWL14o1PwFPcwRUGOtzC20WnCldjp1J1oI+Tl69SgRuZ7KM+ZMUH++lmZqKr42RiRW4J9p0OG+l5lbwQTb7bx9Po0utcMaKoh5SNlww5ynMo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743620; c=relaxed/simple; bh=EhwkazNlZ1kcicF1NryTZowdCh8r1uFd2Irf8ktLv6M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mxXiaaTkE5ibCXN2l+K6shI7sBjFBTedn91SsrVr5FPIJnXGUS4mxdbVvlbE0mV2XZqjWFyglgtGfSycBhDYOu/QVO2ODPSky/fq2AyJPgA6t0l/xJfDkA1VeKV8betTXplBZq4F5HLWqee3Va3YFcMF57xwbFoetBn/EQvbyzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Sp7HV+bv; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3DC8C433C7; Mon, 12 Feb 2024 13:13:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743620; bh=EhwkazNlZ1kcicF1NryTZowdCh8r1uFd2Irf8ktLv6M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Sp7HV+bvdO68KCasoWvCWIRZsfKu8CHLwDit+uwjxPAAsxomz7i/dPxYsFTuY80nQ J0GRGAphZ7bLnRvmxBP5b8MfTpb18FODs4d8MZM1vakrVnJrWkBUgZ4G3sGmeJN6Uz lkJWvbekUOwBiGBOqx7aqOfuqc8vcv8oldVupj6eQv3mIf6tr66B14OT2QANuZ28Ub EQ9Kbk7zMEieijS8lKU0ljW01AjlSCMKLobOyqo+kRIGsjkV5qFUQpEqrjb7ck1J6v cQbU37KQy8VV1i0rgJinn8JnsSI/v+azOA3mZAwtK5Stq1KuuvRnYNJwWnYTYNCuxb 4hbxHrj8Wlhjw== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:47 +0100 Subject: [PATCH v6 04/36] drm/tests: Add helper to create mock crtc Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-4-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3793; i=mripard@kernel.org; h=from:subject:message-id; bh=EhwkazNlZ1kcicF1NryTZowdCh8r1uFd2Irf8ktLv6M=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJBMe/uKeEc4pk5Hb8HD+pX8nM06eDFrFMPdNZ+rp4 D9X5B90dZSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAibrcYGX4dPOTvOvGzbaqf oIzHvvaT86Q1vJbr9Kyxae/VFw9uWcPwV851KVMRC5u+yLIy1bnyPfXff5fKVnC+M+u5XWr1/4g xMwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699090844451106 X-GMAIL-MSGID: 1790699090844451106 We're going to need a full-blown, functional, KMS device to test more components of the atomic modesetting infrastructure. Let's add a new helper to create a dumb, mocked, CRTC. By default it will create a CRTC relying only on the default helpers, but drivers are free to deviate from that. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_kunit_helpers.c | 62 +++++++++++++++++++++++++++++++ include/drm/drm_kunit_helpers.h | 10 +++++ 2 files changed, 72 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c index 32dc8354641a..d5317d13d3fc 100644 --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c @@ -249,5 +249,67 @@ drm_kunit_helper_create_primary_plane(struct kunit *test, } EXPORT_SYMBOL_GPL(drm_kunit_helper_create_primary_plane); +static const struct drm_crtc_helper_funcs default_crtc_helper_funcs = { +}; + +static const struct drm_crtc_funcs default_crtc_funcs = { + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .reset = drm_atomic_helper_crtc_reset, +}; + +/** + * drm_kunit_helper_create_crtc - Creates a mock CRTC for a KUnit test + * @test: The test context object + * @drm: The device to alloc the plane for + * @primary: Primary plane for CRTC + * @cursor: Cursor plane for CRTC. Optional. + * @funcs: Callbacks for the new plane. Optional. + * @helper_funcs: Helpers callbacks for the new plane. Optional. + * + * This allocates and initializes a mock struct &drm_crtc meant to be + * part of a mock device for a KUnit test. + * + * Resources will be cleaned up automatically. + * + * @funcs will default to the default helpers implementations. + * @helper_funcs will default to an empty implementation. + * + * Returns: + * A pointer to the new CRTC, or an ERR_PTR() otherwise. + */ +struct drm_crtc * +drm_kunit_helper_create_crtc(struct kunit *test, + struct drm_device *drm, + struct drm_plane *primary, + struct drm_plane *cursor, + const struct drm_crtc_funcs *funcs, + const struct drm_crtc_helper_funcs *helper_funcs) +{ + struct drm_crtc *crtc; + int ret; + + if (!funcs) + funcs = &default_crtc_funcs; + + if (!helper_funcs) + helper_funcs = &default_crtc_helper_funcs; + + crtc = drmm_kzalloc(drm, sizeof(*crtc), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, crtc); + + ret = drmm_crtc_init_with_planes(drm, crtc, + primary, + cursor, + funcs, + NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_crtc_helper_add(crtc, helper_funcs); + + return crtc; +} +EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc); + MODULE_AUTHOR("Maxime Ripard "); MODULE_LICENSE("GPL"); diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h index 38667d624aa8..6e99627edf45 100644 --- a/include/drm/drm_kunit_helpers.h +++ b/include/drm/drm_kunit_helpers.h @@ -9,6 +9,8 @@ #include +struct drm_crtc_funcs; +struct drm_crtc_helper_funcs; struct drm_device; struct drm_plane_funcs; struct drm_plane_helper_funcs; @@ -110,4 +112,12 @@ drm_kunit_helper_create_primary_plane(struct kunit *test, unsigned int num_formats, const uint64_t *modifiers); +struct drm_crtc * +drm_kunit_helper_create_crtc(struct kunit *test, + struct drm_device *drm, + struct drm_plane *primary, + struct drm_plane *cursor, + const struct drm_crtc_funcs *funcs, + const struct drm_crtc_helper_funcs *helper_funcs); + #endif // DRM_KUNIT_HELPERS_H_ From patchwork Mon Feb 12 13:12:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199748 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2418989dyd; Mon, 12 Feb 2024 05:16:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVkXJ/ubOnP18bgr3lp64PomuzmcTcjrqrZUR3aDKu/ajJeNa4W5RVbIBMTDgWFLOC89vuE6jqFH9kaaWTDJgXYzmEfbw== X-Google-Smtp-Source: AGHT+IGeuJrvgnHfcLpz18s2hiOs3amdePVsDOplP8EpThVxHRJ1dkkM8XAqxoo21AGYUxTvH+oo X-Received: by 2002:a62:cdcf:0:b0:6e0:6c0d:f55a with SMTP id o198-20020a62cdcf000000b006e06c0df55amr6513990pfg.8.1707743777938; Mon, 12 Feb 2024 05:16:17 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743777; cv=pass; d=google.com; s=arc-20160816; b=YKDI0R4lZrakGeIbIX6seiwQgSWOMOfL2zcOu5ehMW6kRHVv5dsS6Bf51LnNrLm6b4 BnLW3hTTRBC9856UGy1Ar70KQpfMFFoYYEvJTeW6R9mzigklWmoGaf1HeAim8BJWKTXO aHisbHiGiRJZGJ/U+HgX+oQIS89yc58J4UW+CAuPhRbBmyw0ht7D4huK10gdmoXcb282 Aqv8gPlEX5kt2hLKez0FV4+L3yTDRtmx/VKHg7BkvNco9patpcpQUt4EIMzHrou1EMEw mw93dEmZTNkSIBKdUHVDg9mJKIdH3iy+CIilIfkJ/Ew6FOy7DNmDLKJXjoLUpMQpy1OO Ty6A== 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=gHEHDs3/j+I9x4krmgD32TZAAh5qtVO8rFVxVogs1uw=; fh=HcoY0L8bB3OBhlJR0j43dSjvOgofqbipTRkfQy2dXT4=; b=ZkM7oghK/+cVDPW2SyzdDzYnJV2Mshgoo7zmjniRZb4heEg20L0VSmvbFebjWW/Il5 rvMituYVv1eAOIVqADsygescjbzJA+DUK5Kp7/q9/zgofYw5fia7xspNw5f8XvPihrC+ oRhMaqNbfQ3veoQYgevsZTz4sJg1seJcTgG50bNdHUX4XWYuyPrbs6oHxUaoUoXB/S4z KcpP3QdcLV2WZqTe8reEp3V/QYigrj7qxXo6L6gBhvAW7LPr8K0ErvOrqqNiuyFq95me Dx5Qj+cEEHT5TB/5EChvlVbzjPYS3ZRq6v983c0ami+l3UyIX6zTjBU5S74Ai7mvOHTI rycw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qK0vOj6H; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61619-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61619-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCUULhy9uE/5IkUDMRhoiAqBABdOKsO296aZUHuuDuw9xUUf9qU8Qrn4Q7OyqysdbpaU+clQrqWlXr+4WhfXBa/qNHGKqw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id u18-20020a62d452000000b006e07d6e2dabsi4867235pfl.167.2024.02.12.05.16.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:16:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61619-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qK0vOj6H; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61619-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61619-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 C48BE285C30 for ; Mon, 12 Feb 2024 13:15:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A11CE3C68E; Mon, 12 Feb 2024 13:13:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qK0vOj6H" 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 6CFE43C473; Mon, 12 Feb 2024 13:13:43 +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=1707743623; cv=none; b=BgpC6WADXwWQ8pQmqcdJjPw1LZZe5iPzax908Re16GXCSpDaNVIKVwC3tT++7F7H7ovFN8Zah024g+rEf6WRFEt68XA2jYEN/M1I1fR0pNL1jKxNydlz/kNQdhR/paEnCSN9QgYudD3BAdr2MRuHQS2wXDVmL+HHtoniHwFwpJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743623; c=relaxed/simple; bh=xJnMCtf3ntBpekt5KmTcAothtAUv0sGGZE7OhCZRHUo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s//UCKhNKhB2Mc229OM7kbRifq+nC1PZmm7GKJtxlNr93HvDOEDHMWQm8Lw2VTuzXHbyEXeMvJBy/6/GqiqYllOqQfeX2PV6o4ChlgIOuKSS3gVg98bEiXceDkupEH4rHnFh06T1QhDgwkWSe96WE58xJ2MV9FFJEOJjR96ZQJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qK0vOj6H; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8AF7EC433C7; Mon, 12 Feb 2024 13:13:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743622; bh=xJnMCtf3ntBpekt5KmTcAothtAUv0sGGZE7OhCZRHUo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qK0vOj6H3ojylIBcL02RVplpwufSMrsbNouYM5O+6aecu/Ku0Zw6wFkmVb+AHx+i9 uY47zBNCRksyDyuyliF2VnFJoCaUYFGV5GaGIVcjs7/DBGCL+6Q3dmkt8DcNnV0br5 Ong+FM57+FDF48O7K1r7L0tPx3deP4yQFnNx0kgBHdGyd3zhQ8X0IFyPcuhTFBMThN D25JzqOVHWPAT9QPnuIwyyZQQDD/LIEk7OKlKvWJg9+W18VOUvNKMby8InAZ/Yu8oC Vfd+teJjyWwZm00Vq8kYH0kGB/qHt3xuiQ+J/z8rqlnDbDY1ze4V8YI7tYh0vfUO/Y i3MDJSwuktVCA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:48 +0100 Subject: [PATCH v6 05/36] drm/tests: connector: Add tests for drmm_connector_init Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-5-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5901; i=mripard@kernel.org; h=from:subject:message-id; bh=xJnMCtf3ntBpekt5KmTcAothtAUv0sGGZE7OhCZRHUo=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJBMFVPz2FosckRdR9V67wYYtPPDtBmPnxMDy2WGX3 lR9anrTUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgInc5mL4Z64o8fvevrqwTWIP eHLuKCcYf3x2OXnJFdMJE3bfNLv2+jkjw4kLa9IDvs6wf/FCjKFPvy+IfznXkrbp2QZmdt+KRUX TmAA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699139723703145 X-GMAIL-MSGID: 1790699139723703145 drmm_connector_init is the preferred function to initialize a drm_connector structure. Let's add a bunch of unit tests for it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_connector_test.c | 170 ++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index c66aa2dc8d9d..a268847be8d1 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -3,10 +3,175 @@ * Kunit test for drm_modes functions */ +#include + +#include #include +#include +#include #include +struct drm_connector_init_priv { + struct drm_device drm; + struct drm_connector connector; + struct i2c_adapter ddc; +}; + +static const struct drm_connector_funcs dummy_funcs = { + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .reset = drm_atomic_helper_connector_reset, +}; + +static int dummy_ddc_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, int num) +{ + return num; +} + +static u32 dummy_ddc_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm dummy_ddc_algorithm = { + .master_xfer = dummy_ddc_xfer, + .functionality = dummy_ddc_func, +}; + +static void i2c_del_adapter_wrapper(void *ptr) +{ + struct i2c_adapter *adap = ptr; + + i2c_del_adapter(adap); +} + +static int drm_test_connector_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv; + struct device *dev; + int ret; + + dev = drm_kunit_helper_alloc_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + priv = drm_kunit_helper_alloc_drm_device(test, dev, + struct drm_connector_init_priv, drm, + DRIVER_MODESET | DRIVER_ATOMIC); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name)); + priv->ddc.owner = THIS_MODULE; + priv->ddc.algo = &dummy_ddc_algorithm; + priv->ddc.dev.parent = dev; + + ret = i2c_add_adapter(&priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + test->priv = priv; + return 0; +} + +/* + * Test that the registration of a bog standard connector works as + * expected and doesn't report any error. + */ +static void drm_test_drmm_connector_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +/* + * Test that the registration of a connector without a DDC adapter + * doesn't report any error. + */ +static void drm_test_drmm_connector_init_null_ddc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + NULL); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +/* + * Test that the registration of a connector succeeds for all possible + * connector types. + */ +static void drm_test_drmm_connector_init_type_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + unsigned int connector_type = *(unsigned int *)test->param_value; + int ret; + + ret = drmm_connector_init(&priv->drm, &priv->connector, + &dummy_funcs, + connector_type, + &priv->ddc); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +static const unsigned int drm_connector_init_type_valid_tests[] = { + DRM_MODE_CONNECTOR_Unknown, + DRM_MODE_CONNECTOR_VGA, + DRM_MODE_CONNECTOR_DVII, + DRM_MODE_CONNECTOR_DVID, + DRM_MODE_CONNECTOR_DVIA, + DRM_MODE_CONNECTOR_Composite, + DRM_MODE_CONNECTOR_SVIDEO, + DRM_MODE_CONNECTOR_LVDS, + DRM_MODE_CONNECTOR_Component, + DRM_MODE_CONNECTOR_9PinDIN, + DRM_MODE_CONNECTOR_DisplayPort, + DRM_MODE_CONNECTOR_HDMIA, + DRM_MODE_CONNECTOR_HDMIB, + DRM_MODE_CONNECTOR_TV, + DRM_MODE_CONNECTOR_eDP, + DRM_MODE_CONNECTOR_VIRTUAL, + DRM_MODE_CONNECTOR_DSI, + DRM_MODE_CONNECTOR_DPI, + DRM_MODE_CONNECTOR_WRITEBACK, + DRM_MODE_CONNECTOR_SPI, + DRM_MODE_CONNECTOR_USB, +}; + +static void drm_connector_init_type_desc(const unsigned int *type, char *desc) +{ + sprintf(desc, "%s", drm_get_connector_type_name(*type)); +} + +KUNIT_ARRAY_PARAM(drm_connector_init_type_valid, + drm_connector_init_type_valid_tests, + drm_connector_init_type_desc); + +static struct kunit_case drmm_connector_init_tests[] = { + KUNIT_CASE(drm_test_drmm_connector_init), + KUNIT_CASE(drm_test_drmm_connector_init_null_ddc), + KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid, + drm_connector_init_type_valid_gen_params), + { } +}; + +static struct kunit_suite drmm_connector_init_test_suite = { + .name = "drmm_connector_init", + .init = drm_test_connector_init, + .test_cases = drmm_connector_init_tests, +}; + struct drm_get_tv_mode_from_name_test { const char *name; enum drm_connector_tv_mode expected_mode; @@ -70,7 +235,10 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { .test_cases = drm_get_tv_mode_from_name_tests, }; -kunit_test_suite(drm_get_tv_mode_from_name_test_suite); +kunit_test_suites( + &drmm_connector_init_test_suite, + &drm_get_tv_mode_from_name_test_suite +); MODULE_AUTHOR("Maxime Ripard "); MODULE_LICENSE("GPL"); From patchwork Mon Feb 12 13:12:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199749 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2419122dyd; Mon, 12 Feb 2024 05:16:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IHBGIqO8FTU0Hd8gG2NkLK4/Xnade85TXR1rem/vSdkJV+iHuTBQFcNAe4gf5sXPHnQAtWo X-Received: by 2002:a17:903:187:b0:1da:933:fb15 with SMTP id z7-20020a170903018700b001da0933fb15mr9034114plg.0.1707743788805; Mon, 12 Feb 2024 05:16:28 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743788; cv=pass; d=google.com; s=arc-20160816; b=o5PAOnSPO90pJ48RWCQuZyjjpyOvLVq8+hRnNCRGg7tto5cuJy2O9NM+4OcR7S+s/H 4ET+VXVDxLx3RhMq8952lR5sZXcjhZgffXw6QmjO9sOpTk718wNsUBSbnBkAVuhzlZXf AjHE1Mul//aL03fM6OQ+dblbHf690c28V2Bb3lzuS8jWGNqidpFmTHqnkwy6p6LEXBa5 0+cEA2RBsFFkS3gqvSqVU/Cx1VuSOahAxuRvgn79P2KfMOh/q+4WXv1SRawpCMnzcgvf gKJTZAXlztEvooX0mi44SUCIi1lBRr/aKlZP7TkwD5kl0WAR2zQi9FSEwwf10RDSk3D3 pjaw== 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=KV6yGSAJzyzAhKoiN+q1w2n6yC3jSToLAxSG+Q0+3SA=; fh=QRMVPxq+gWYQqJFhViuOQOceymh2pV4M4/9Z5ynaGtI=; b=E4pVnKUtqckI/HauJf7nR6oHXFdEALNwDjNCtD8L29qS7dVHWbOrAaeFuhnJQ07l/k BnmEkwyc2uMqNTyx98J8R88YiTW7at2I/V/Jq/7Kq8xvbW2kcSDg24dspF3mRyF5M7iJ fAI7mK60FBFjS5Xk8I4kxLpUehWyB01eJmNrnoX+UTOfr0dlNlJLBEsp4pbyYF+4RVn6 GJVkPVECIJZNnjhBqOJ7WY5HTWYIrrzMEjKwYQejvzQAD/bsV+s8kxfm7kY931C0pmKw lCbkvNP2ZlyhrO2vKc3UnksgVtG8Z2xYmlvt1IR9wbPDO76XS26XhLTn4Z9jiC6Wrbk5 R7ig==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=XXNn7xfi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61620-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61620-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWXfBVDA/CdSunPs62zZRPVbueO9FjcmIsyJT9g4ANhJGvnUPu6QnCu00SCzKRzyoVbd8OcPBAFTt3lsUAf2xEfYZTllQ== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h9-20020a170902680900b001da1dc5fc05si234175plk.29.2024.02.12.05.16.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:16:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61620-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=XXNn7xfi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61620-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61620-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 C9889287208 for ; Mon, 12 Feb 2024 13:15:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0BE1A3CF61; Mon, 12 Feb 2024 13:13:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XXNn7xfi" 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 2D4E53C47D; Mon, 12 Feb 2024 13:13:45 +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=1707743626; cv=none; b=qforG/PJZnCoz5SzyzkPpjT4DK84dkNMpo3LvevTQsQCiqfJzjpKSfHoMjq9yjHp/7eOTFHZq4vieGpDWQbpVT0FVwtbdotThAnWG3Lght1h2b/JaYGFPUdUbeYJUrgFvUydeYNkhTQaU1e8RcmxGkQKZhXtflXSVZVCMZUXvbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743626; c=relaxed/simple; bh=0u5x3Bm9z3fvcYrHOnOZJKukvzBne3+qdXlM1owrzgk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oRXqaksGqpKlLcRKsmk1YTwYuC0ItkAtDlV2C0Z18cZlzGaBwCQR7x+pQr2n8Khg1q4WYND/fw+OIDGX8EvlF+hlwbT+bqUWaltBmwVghFzpoxVn1hLF0q1M0P0y6pdhWpUpCIG0fFh+jTQjQunL+40Hsi2Xo/1rqg+Aw4RsSv8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XXNn7xfi; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4B496C433C7; Mon, 12 Feb 2024 13:13:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743625; bh=0u5x3Bm9z3fvcYrHOnOZJKukvzBne3+qdXlM1owrzgk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XXNn7xfi/rOc+qn5d558ZyxFMN16YJJrQnPTntYcvrUovPTz2i6i/9dWSVYI5UDMX SWkjSo0Usim/8z38ftwzwn6fx49RLacaR/bkqFaMQOA3n3BWb0ayvN9NhS+aO7hOt1 lUuLxIeqv2Ejd0l7a+tHzqbFzNd2D8aN5ru/ey/OICpEEiJ4Vp3wSPuU4BDzHM1xtz qliGfGkvYpVQMJVt/giIKX2VUjssExhntwl1eGJPuLcWrbXQfrBnDc8Dj9zU9jxqX0 nw7krWE9Mjv/cPMqnAvOKtW4sGfPA4O2pvTkRsB0M/10W3WYoSQE3Jsw3HIDl5MVzt 0Y0vtVDjKP3PQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:49 +0100 Subject: [PATCH v6 06/36] drm/connector: Introduce an HDMI connector initialization function Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-6-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=3492; i=mripard@kernel.org; h=from:subject:message-id; bh=0u5x3Bm9z3fvcYrHOnOZJKukvzBne3+qdXlM1owrzgk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJJO690yIi+juXXGwerVyC9fa7CqWuQ+nfXjmX3y2N oVHmndlRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACaS85uR4cCd9A8GD9Xz3i6R TWk+btu+vYQ5hsXnYILPgX/XRNbFFzIyLDy+9no629NY9axp0pvrds+u4bvY8i9G7su9EweebGb 4zQcA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699150891899391 X-GMAIL-MSGID: 1790699150891899391 A lot of the various HDMI drivers duplicate some logic that depends on the HDMI spec itself and not really a particular hardware implementation. Output BPC or format selection, infoframe generation are good examples of such areas. This creates a lot of boilerplate, with a lot of variations, which makes it hard for userspace to rely on, and makes it difficult to get it right for drivers. In the next patches, we'll add a lot of infrastructure around the drm_connector and drm_connector_state structures, which will allow to abstract away the duplicated logic. This infrastructure comes with a few requirements though, and thus we need a new initialization function. Hopefully, this will make drivers simpler to handle, and their behaviour more consistent. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 39 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 5 +++++ 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index b0516505f7ae..d9961cce8245 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -452,6 +452,45 @@ int drmm_connector_init(struct drm_device *dev, } EXPORT_SYMBOL(drmm_connector_init); +/** + * drmm_connector_hdmi_init - Init a preallocated HDMI connector + * @dev: DRM device + * @connector: A pointer to the HDMI connector to init + * @funcs: callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: optional pointer to the associated ddc adapter + * + * Initialises a preallocated HDMI connector. Connectors can be + * subclassed as part of driver connector objects. + * + * Cleanup is automatically handled with a call to + * drm_connector_cleanup() in a DRM-managed action. + * + * The connector structure should be allocated with drmm_kzalloc(). + * + * Returns: + * Zero on success, error code on failure. + */ +int drmm_connector_hdmi_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) +{ + int ret; + + if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector_type == DRM_MODE_CONNECTOR_HDMIB)) + return -EINVAL; + + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(drmm_connector_hdmi_init); + /** * drm_connector_attach_edid_property - attach edid property. * @connector: the connector diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index fe88d7fc6b8f..4491c4c2fb6e 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1904,6 +1904,11 @@ int drmm_connector_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc); +int drmm_connector_hdmi_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); From patchwork Mon Feb 12 13:12:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199752 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2419562dyd; Mon, 12 Feb 2024 05:17:13 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW+z360bVYqhqqMDKU2UG25WpL5khex1K7Tz+Ro7Vrz37fQo1HSjlzl0Vbkzv/XY/8+ZK91U04oUEWMa33/5SlfrVMUMA== X-Google-Smtp-Source: AGHT+IGhIG1e6+49p1/GX7T/Xnn5D5MfCTZcpzkyujpzTC1ixYWCeFGvYTeuNSUcYOlzV8KGppYX X-Received: by 2002:a17:906:b886:b0:a3c:c11b:e260 with SMTP id hb6-20020a170906b88600b00a3cc11be260mr1039384ejb.68.1707743833616; Mon, 12 Feb 2024 05:17:13 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743833; cv=pass; d=google.com; s=arc-20160816; b=VKHe6lCFsVcRd3QkIj/INasUFGYdfwBU3XJtXr3QqRxPGO384LGGrMv7TuAgiVo+nF pEXW2rqH6zxbs/IZlpj9V5KEfiDxtU8T9Q/u1g+1MkZJgDkcfxRemTXurD6oUZCzXhtP y66jl4k2XXPTWMNxvULRk5iW27Df62yMzpgSHcULd4VpfZgUqxItlbushKwkuw3jANJo NP3IUCDE0NJ0yy2Y8+CnFut6IIEj4kcBJ5Z2riSfbhn6k87amJ7tP2qUw70VuFLqEY0T JPzA7I2EqfsEp+8SRS9z3rY5uPuAtJlcD+Bh/+2HfpHr8TY0GoP/nY2pCnSwj3+Rvqxr B3bg== 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=p0bW7ZwanmFTwDwXAsjQz6qJQPKdkJ6zgOpk8C2cnEw=; fh=+Ahs4iZjnHD5QRxuS/wv32IbaTtNYQ/EUcR5+JfnMqM=; b=0+uCSCdMEm8bpc8o7ajG7wloELNCsTTrXnzP/r+EUGVIEELYbC6RNtek9htIu/kqfE g7mTnXe7kqQc66o/0QjCupRPIDYnv+6ikzspQ97sNomDVaMh0WmtdzNCtoMSQt/T7hnK umptNxyoD/CB0sdbXRfi6ny4BwfQu6HBme4NEqsPc0trYKnFrZt8fLNTYluB6CF4gJXl JDyFXqgVXvp580O8zWufWLimtKhJ3ooEZGa2kebNwru7XDkLEgG79SgWsrm7HBjhgqLR I8hUSxv0A/dKwQ2/VmdKx7+IRguRwOXbdZ1tnBq/7BF2RC4Go5Ng/+GO+OLK5o1T2ooh iqwA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=JYmLt1Ez; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61621-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61621-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCW8ZSE0Fm4aG6p5c4vS9iasLckW8TYX9gLvuPDFPxK4Q3QUMzcg9ChYESC/rjh/OcZycvgQuIcuInv7/tR+QGE/gL0UpQ== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id o6-20020a170906358600b00a3cd5c45089si190569ejb.606.2024.02.12.05.17.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:17:13 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61621-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=JYmLt1Ez; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61621-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61621-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 9A90E1F22D6B for ; Mon, 12 Feb 2024 13:16:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 040123D0BB; Mon, 12 Feb 2024 13:13:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JYmLt1Ez" 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 DC59E3CF5C; Mon, 12 Feb 2024 13:13:48 +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=1707743629; cv=none; b=oT/pUKFV2ktREVk1bc3yruWB106kXHVDdi+9wzxMz4etOieYCKZwQK9U9WSUC+NDWhyk5uf2diL8rlcBdshtAcJeaUjwL5gneSkPh2MSDq0quUUI2+Kp2EMm4QaJIMDHtWSTSIHfVbDpRzImr51d615MCD/UZ9dua3YNcBWxqpU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743629; c=relaxed/simple; bh=ekRYwIKWq6y5QbBEMB/WwN89jVENEHbv42HIP/z5kwU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZTh1dusNWFXYkogipvwdFsKDV94S/LevxZY4EVj/ZwHASUWOtj+3WM6IPOJSdbzORNWV9ROTevBBWuMc9e8aSG7usTKAxsLS/8XE62n/FiyT//0bUXVGJdzvFlXsvuSCKDPzNoJF6aEQVWdcF337UdMDbfSkepnL0eF+wZ5TMN8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JYmLt1Ez; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0AC7AC43390; Mon, 12 Feb 2024 13:13:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743628; bh=ekRYwIKWq6y5QbBEMB/WwN89jVENEHbv42HIP/z5kwU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JYmLt1EzYcG9A5rQgBbKIx30t/IxdRkjOtxg3QWg3aFQ22a0Q8jNRdGlsIy+CPlvI iAD4T0H3lBi+r9xAgKn7UdCCIBbq5WNf5KWLcyymUP5td5bRDsMHNteBhdolP16MZI RTr9+Vi2inq7GaSskpstFtwkK0yrcsvW+Ch09LNjcZ23kggNH4bHaBP3BYxnlmiTo4 ZlE6NbKbQttIh8av1baMAemxmCZfjkfpi15n/0wxFD2ALtiWDY2iL7gjzGSpE1nyCt dTVLwwiePQEWr4WpWq8/Hz91L9VWh/N5toZqKemJvBwGo5GyT+XjCAUp3Bl3xuPrYq 8rJPnwYDpg4bA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:50 +0100 Subject: [PATCH v6 07/36] drm/tests: connector: Add tests for drmm_connector_hdmi_init Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-7-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4892; i=mripard@kernel.org; h=from:subject:message-id; bh=ekRYwIKWq6y5QbBEMB/WwN89jVENEHbv42HIP/z5kwU=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJJM+mT1bl/73zvFjyXL5y8OShVcvvX5ohebSlUwrp NdP+2Zq1lHKwiDGxSArpsgSI2y+JO7UrNedbHzzYOawMoEMYeDiFICJhNxgZNibe/TUnedOYpfb Hvw+Y9LIIrhL26ZkqUyRz82Tee/qLusz/A95f+7RUuXEm6l+/4V3q2z4Nify5qLOVCWT8CmTeh1 n8zADAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699198491855221 X-GMAIL-MSGID: 1790699198491855221 We just introduced a new initialization function for our connectors, so let's build a kunit test suite for it as well. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_connector_test.c | 123 +++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index a268847be8d1..8f070cacab3b 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -172,6 +172,128 @@ static struct kunit_suite drmm_connector_init_test_suite = { .test_cases = drmm_connector_init_tests, }; +/* + * Test that the registration of a bog standard connector works as + * expected and doesn't report any error. + */ +static void drm_test_connector_hdmi_init_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +/* + * Test that the registration of a connector without a DDC adapter + * doesn't report any error. + */ +static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + NULL); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +/* + * Test that the registration of an HDMI connector with an HDMI + * connector type succeeds. + */ +static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + unsigned int connector_type = *(unsigned int *)test->param_value; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + connector_type, + &priv->ddc); + KUNIT_EXPECT_EQ(test, ret, 0); +} + +static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = { + DRM_MODE_CONNECTOR_HDMIA, + DRM_MODE_CONNECTOR_HDMIB, +}; + +static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc) +{ + sprintf(desc, "%s", drm_get_connector_type_name(*type)); +} + +KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid, + drm_connector_hdmi_init_type_valid_tests, + drm_connector_hdmi_init_type_desc); + +/* + * Test that the registration of an HDMI connector with an !HDMI + * connector type fails. + */ +static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + unsigned int connector_type = *(unsigned int *)test->param_value; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + connector_type, + &priv->ddc); + KUNIT_EXPECT_LT(test, ret, 0); +} + +static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = { + DRM_MODE_CONNECTOR_Unknown, + DRM_MODE_CONNECTOR_VGA, + DRM_MODE_CONNECTOR_DVII, + DRM_MODE_CONNECTOR_DVID, + DRM_MODE_CONNECTOR_DVIA, + DRM_MODE_CONNECTOR_Composite, + DRM_MODE_CONNECTOR_SVIDEO, + DRM_MODE_CONNECTOR_LVDS, + DRM_MODE_CONNECTOR_Component, + DRM_MODE_CONNECTOR_9PinDIN, + DRM_MODE_CONNECTOR_DisplayPort, + DRM_MODE_CONNECTOR_TV, + DRM_MODE_CONNECTOR_eDP, + DRM_MODE_CONNECTOR_VIRTUAL, + DRM_MODE_CONNECTOR_DSI, + DRM_MODE_CONNECTOR_DPI, + DRM_MODE_CONNECTOR_WRITEBACK, + DRM_MODE_CONNECTOR_SPI, + DRM_MODE_CONNECTOR_USB, +}; + +KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, + drm_connector_hdmi_init_type_invalid_tests, + drm_connector_hdmi_init_type_desc); + +static struct kunit_case drmm_connector_hdmi_init_tests[] = { + KUNIT_CASE(drm_test_connector_hdmi_init_valid), + KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), + KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, + drm_connector_hdmi_init_type_valid_gen_params), + KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, + drm_connector_hdmi_init_type_invalid_gen_params), + { } +}; + +static struct kunit_suite drmm_connector_hdmi_init_test_suite = { + .name = "drmm_connector_hdmi_init", + .init = drm_test_connector_init, + .test_cases = drmm_connector_hdmi_init_tests, +}; + struct drm_get_tv_mode_from_name_test { const char *name; enum drm_connector_tv_mode expected_mode; @@ -236,6 +358,7 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { }; kunit_test_suites( + &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, &drm_get_tv_mode_from_name_test_suite ); From patchwork Mon Feb 12 13:12:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199785 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2427078dyd; Mon, 12 Feb 2024 05:30:38 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWDaGl3rdlHVVzvcbxkZ17Fx0HxeClvr3UZFKSL8ycucuq2QLT+yclFXDR9aD0xSp8bKSjI7g/lf/48eZOHTjvC7L7zRw== X-Google-Smtp-Source: AGHT+IE7JL6xWYyBZJWiGDmp/0WM92uWvRsQ6HnbhK8Q3KyqvFHrDViOw9MACREncsCfjtE9Ocac X-Received: by 2002:a17:902:e986:b0:1d8:d5b0:aadb with SMTP id f6-20020a170902e98600b001d8d5b0aadbmr6896653plb.66.1707744637873; Mon, 12 Feb 2024 05:30:37 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744637; cv=pass; d=google.com; s=arc-20160816; b=cl9HFW5Q7VNWVmwjwlUNTDpglLcIOI/Q+N/i88FeJJogFipP+0eNN41fSHwl+msB3O TgX2OYEJHwfUnBr0D+84/FhR82bObCFuUGlmlG8Drmqh93x8ACwRDiW/f34FSQkH8zrA j5fDTM8eaa0X4UcmRPmgQ/YKdq++37chdAz7Mv599KPTrmLaar4TCUBBqIS6NfGaoZGq 3wVv/lDwZmkD4WA/RdrTO3Ou2h89OlT0RFlnZ+Z9D9qm0zbVLf7qHFghu6GD4Cgb5daN PzRxnPdmbCLOxiMGk9iglG+J/ewXYciIeyCiKRVVwvvrLzE9ZKpnmTXO59KO7Iwy2Ilf Utgw== 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=m39o+y1OkMI5xlKi5wO+ngeZH8SJLKDaYOOwxas2OUM=; fh=G5BmICS6n9Dum/bD86I9WC2Ci0cEzXcaEYhOOtH5JYg=; b=A7RpQ02xebK0xo+oHM8o0Y9AjZiQpYaPkm/tFT/AC5PEDHtTTpOE+S6PwaOMLTucvl /5Nyl2WDtpitr0dfS23Zx52KA0LsKF3tVfLr9Y2lfNmShxPxrPGY05W6nAWlCwhEAf5q 3N+AzRs3YZbv/uEK+dBGv6c2MsNRxypM/e9qhdt/ljXnlZChE+BnTS7CMzblV2ZWQEjR H7s/BbRqlTxCRp5PdQTbvZwk2PxJa2SGddy45fUd3YBvNGNwcPS6QRB2s0st3PhRa2z+ j6hLkOdjK3XBExgO6QZrDQSw4cltq2iuT014Tjq/tYp/JsNGsVmggn3ez9MraXzE5MvU MMRw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ImAOc+rc; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61622-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61622-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVD1bw4Xml4rrV25xxas9eNHtjWwHBqCtvEE/xWgUH2jHBgtLpKMO65zBUMe/HY4wyk7kjrXvWAx+5rFr8dO/MveToVQQ== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id 5-20020a170902c10500b001d9c37d7173si239490pli.249.2024.02.12.05.30.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:30:37 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61622-ouuuleilei=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=ImAOc+rc; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61622-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61622-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id D36E0B256F8 for ; Mon, 12 Feb 2024 13:16:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 908513D0DD; Mon, 12 Feb 2024 13:13:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ImAOc+rc" 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 90F673D0AB; Mon, 12 Feb 2024 13:13:51 +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=1707743631; cv=none; b=k5XsdidmjRnSoVgeumYOsDVnkdgRD2Gqn5d95vmdqSPF9jPVObX2hFT7qI6A0bOHl81SaizlCtUhhPgSHQwpPTOaEYh1Ump1XPtOwXTFOQMGf9hM4ERwZApqjKFhoTvxk2KGhHW/wxrITHmF/iDSWp3ckXQ/88kFQz0TIsPFOoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743631; c=relaxed/simple; bh=8Uhb2KzwX3/U09GDquBi0hwfsEDMupY/ff4+NCVLmCk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EPam1ibVQjvN6V63/eG+16e9YiNR4Goa7eHX4j05/9foeHG5CGZy8BdCTel4NvPnVd42yIbCTjq7Uzt7ZuxAztEgnK+26KHl5H/CRs0n6pfy2qyGOyQek3DNqwksPERUNMx+bZJ5UJ7/O1U9DkPYy1imWc5MzVhSUQzEthsBuhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ImAOc+rc; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id C05C1C43390; Mon, 12 Feb 2024 13:13:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743631; bh=8Uhb2KzwX3/U09GDquBi0hwfsEDMupY/ff4+NCVLmCk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ImAOc+rcP1RQrNXrz28WyzznQ34Fosvo3DgqgoRYkulR6ZeMrLp3aE8eEY8zRkQ7s FdI0QvphVRnuh9D8EaR40F5tdInvdGqYw7iuQcl7GeAt+GRpTUTwwcpLtPTKWBTQRn T9RRqHnCRyecEvMsLRAjmrM6l1l4T/CnX32WZmjcvBxAbTgyIPuIYS+Qn2MOsRM1Oz hvs7KLsqGTDEyTxu6oyMU1+Jk4AroygUeH1QF/qReuolU5PbK2HsLg0l5tJd9dS+W1 cZusvDG2uhd80iBWkQOTtNHUsGqk8miD31OcoVrZnwq5w8Rv3WAxwWV/wmuranQP2x QLBvoAqjArKLQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:51 +0100 Subject: [PATCH v6 08/36] drm/connector: hdmi: Create an HDMI sub-state Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-8-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4256; i=mripard@kernel.org; h=from:subject:message-id; bh=8Uhb2KzwX3/U09GDquBi0hwfsEDMupY/ff4+NCVLmCk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJJNlrDyWbOZmCuHr2Vmn8X7qWt67yV/fPxI4oOKqp mwtutK0o5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABM5oszIsKfr+7F0Xnf+vrlf dodubfZT/7W/dDdH5a3HxoKO0QZ9vowMfdXryhQYlzFw8az7vFLLxGu1GhPHBi82ZsYIH6f3Vhf 4AQ== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700041089663314 X-GMAIL-MSGID: 1790700041089663314 The next features we will need to share across drivers will need to store some parameters for drivers to use, such as the selected output format. Let's create a new connector sub-state dedicated to HDMI controllers, that will eventually store everything we need. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 35 +++++++++++++++++++++++++++++++ include/drm/drm_atomic_state_helper.h | 4 ++++ include/drm/drm_connector.h | 7 +++++++ 3 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 519228eb1095..7ad1dffe66d9 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -571,6 +571,22 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); +/** + * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources + * @connector: DRM connector + * @new_state: connector state to reset + * + * Initializes all HDMI resources from a @drm_connector_state without + * actually allocating it. This is useful for HDMI drivers, in + * combination with __drm_atomic_helper_connector_reset() or + * drm_atomic_helper_connector_reset(). + */ +void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, + struct drm_connector_state *new_state) +{ +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); + /** * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state * @connector: DRM Connector @@ -620,6 +636,25 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); +/** + * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state + * @connector: DRM Connector + * @state: the DRM State object + * + * Provides a default connector state check handler for HDMI connectors. + * Checks that a desired connector update is valid, and updates various + * fields of derived state. + * + * RETURNS: + * Zero on success, or an errno code otherwise. + */ +int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); + /** * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state * @connector: connector object diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index b9740edb2658..d59d2b3aef9a 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -71,7 +71,11 @@ void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_ void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state); void drm_atomic_helper_connector_reset(struct drm_connector *connector); +void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, + struct drm_connector_state *new_state); void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector); +int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, + struct drm_atomic_state *state); int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, struct drm_atomic_state *state); void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 4491c4c2fb6e..000a2a156619 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1031,6 +1031,13 @@ struct drm_connector_state { * DRM blob property for HDR output metadata */ struct drm_property_blob *hdr_output_metadata; + + /** + * @hdmi: HDMI-related variable and properties. Filled by + * @drm_atomic_helper_connector_hdmi_check(). + */ + struct { + } hdmi; }; /** From patchwork Mon Feb 12 13:12:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199786 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2427449dyd; Mon, 12 Feb 2024 05:31:11 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW1DW4bxbRrSJF7pkFRzg7ZoEFOwMn6T7QLEjb5mtnzYeLEcCaOe3C1EdbjJNMN1u+zJIS4gaylYtelxaJke7hkurf83Q== X-Google-Smtp-Source: AGHT+IGiKRw6+d8zkMfefammwzBmtGXwRVLzyeg61VNGL46T1WWMDSf8coED3yIzbrjm7isH8l5l X-Received: by 2002:a05:6a20:d707:b0:19e:3c4e:d0f8 with SMTP id iz7-20020a056a20d70700b0019e3c4ed0f8mr5433475pzb.32.1707744671400; Mon, 12 Feb 2024 05:31:11 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744671; cv=pass; d=google.com; s=arc-20160816; b=eKNUQnO0OWT4hb83nyJ2lfiayVC7RrCTlpYMaBGf+x5uEUjDD7FxiKG7KNbLdpz4c7 /gz34VID3qCJPnHFdUSPaI0KUQOaMUlIyIdJPMxy6Xf8tPbrgy5wL9PwHmoecWvI7VkV FS33vRfH0xnWez320B3drw4MUq2DnYrdVqjnNt7YxIJGPFwLA0GZ4utmneBLovNLd3fb F2RxicyFLEVyod8V7cijxh95SjFy4ew4GBSs9j/eEALDZncnralhMXMPhgOX+bm6K21R dm3mb6ZvQVp63nJ/niiYv5EMM19Rby+w01hiAfmHPBoJWWBK0ljyYUdgKvNQUQOgGyFt E3+A== 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=CXOVBqn+OqfKdfOaSZdVPuiojaxJPR6W2nT3OG26u30=; fh=q4RhGK95KvTeqaSCv0trMx0cdpExgsCgMIrJ3So0s30=; b=0oUR5khlfxMeZeMBPu5gaQDnR1D1tObBBsWEUIGF3DDEO1TJMqy9KxpjCJVBGASsQh JxM+/CpWIdxZcP24tTpRrvCZNsMT5WjeTDeHGIOXYTADcsdZqi1jRTskGMTPj1zGqaim vkRKpuVYcy7rcBx4MTTzaz2cU7JpINK5Eof1Ng9WuiTLP/FjXgm5wJFdkH6xqJOPQQvT XKE+R/VM3Hqk+FeTYUgXOW9DjUle6LjOFBk9/N0q7k9FaNazjp/5VhEV7OZ1WSOAq7dn 3kCp9I+RtEHzrHgMvTjWHErvRYDjtFIMknx5LmNHcmcpYMpC2n3mmfPLz37kVywxpHox oHkA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=T6FJUdNp; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61623-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61623-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVmBDKye5E1cTnuURbUgpOcH/m1Jz4B3C5AjWLl38Pjo95dLi89ZnkHmelEJnQx2DPVZMCsO11mOzqlQIsM8xveXLmDFA== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id cm5-20020a056a020a0500b005dc35645164si251146pgb.292.2024.02.12.05.31.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:31:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61623-ouuuleilei=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=T6FJUdNp; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61623-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61623-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 565A2B25B83 for ; Mon, 12 Feb 2024 13:17:01 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D9B493D55E; Mon, 12 Feb 2024 13:13:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="T6FJUdNp" 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 7248C3A1CB; Mon, 12 Feb 2024 13:13:54 +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=1707743634; cv=none; b=sGRoRErLzT22/eJ2pRB34N/wI3xP3Wmn9vDBZ7OR8rIaaBWgA79Rz17ei06wj6LQ0Ihs5rBqEDHQ4PM/2ZKYWKk/YUXX+6uQMGWz51zAGZXHYuvuDB/j+6NyK1l6/2dUqyp5crlN6T/cRLKL8fCe/lM07VUWM5OLZAVzqTQj6h8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743634; c=relaxed/simple; bh=YqHSxVxIl0Xk2E1KAi6ngsUqlW2QyXHW3UepbjKNKjg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oMqhYmQOrjwXOUGoagqqxXbmgjKbXZfKrqPimujAz9P12dnj+iKCgtYcxvQfj/IX+aF4hTg6Ek4MerrsHPfXn5lCn3LkjRT2vSVVRIyoBaxtjkpvjr1VSdRk693f7XEZS/icA0G5ndAjzgC6OLGR/rF0Q8Kkai3aqMhk0rYC5g4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=T6FJUdNp; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88A0DC43390; Mon, 12 Feb 2024 13:13:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743633; bh=YqHSxVxIl0Xk2E1KAi6ngsUqlW2QyXHW3UepbjKNKjg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=T6FJUdNpIQxt28Y5MzOuJCn/ddh0OnYGQ5ef6Mf0LXCUmlLaeHusxJ9IJCszMfuUq dXWFtFZXjCmNeNchQxMLCgtu3K8WIq+CUbrNZhxtMr50Orw1YUxDJ5zJdu2EH6xIgP EE8UCA9IJlgHYUSdSu/PgyjzJvja1lZgvuTBzDEdGZ6yCXVVQgrpkCoCT/TePawxnK 5fk9YyYyV4mQR/Bc+rSYwY+mGIHPLlVjfxXj+GxjIttaOxpTaI05I2ECdh5lSQldwV vo8hV2oK/KeMhD8PvDH8nhzXCyaUG95gfafI+3jKWX4mRDacZwXL+wcD4mDM807BM7 iD8iVWvYk0JLg== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:52 +0100 Subject: [PATCH v6 09/36] drm/connector: hdmi: Add Broadcast RGB property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-9-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=12127; i=mripard@kernel.org; h=from:subject:message-id; bh=YqHSxVxIl0Xk2E1KAi6ngsUqlW2QyXHW3UepbjKNKjg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJJO5dlf0ZGTGnpkneND649d1K0L9DW5Y1Ubkz3+tX rggYvrfjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAExE8gLDX0H9X8tVm/bH1Trq akxcuc/ZQ5lh9fXKq1P/3z7TldrwpJCRYecqTXEVFbkvVicY9zAIHJCTP7LT9sPPXwV/uY8F7Hp hygIA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700076508886748 X-GMAIL-MSGID: 1790700076508886748 The i915 driver has a property to force the RGB range of an HDMI output. The vc4 driver then implemented the same property with the same semantics. KWin has support for it, and a PR for mutter is also there to support it. Both drivers implementing the same property with the same semantics, plus the userspace having support for it, is proof enough that it's pretty much a de-facto standard now and we can provide helpers for it. Let's plumb it into the newly created HDMI connector. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- Documentation/gpu/kms-properties.csv | 1 - drivers/gpu/drm/drm_atomic.c | 5 ++ drivers/gpu/drm/drm_atomic_state_helper.c | 17 +++++++ drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 85 +++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 36 +++++++++++++ 6 files changed, 147 insertions(+), 1 deletion(-) diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv index 0f9590834829..caef14c532d4 100644 --- a/Documentation/gpu/kms-properties.csv +++ b/Documentation/gpu/kms-properties.csv @@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De ,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector ,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB -i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normally in the range 0..1.0 are remapped to the range 16/255..235/255." ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a91737adf8e7..93831850ffcd 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1143,6 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace)); + if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) + drm_printf(p, "\tbroadcast_rgb=%s\n", + drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); + 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 7ad1dffe66d9..d93bc7f5faee 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -584,6 +584,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, struct drm_connector_state *new_state) { + new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO; } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); @@ -651,6 +652,22 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_atomic_state *state) { + struct drm_connector_state *old_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_state = + drm_atomic_get_new_connector_state(state, connector); + + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) { + struct drm_crtc *crtc = new_state->crtc; + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + crtc_state->mode_changed = true; + } + return 0; } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 29d4940188d4..2b415b4ed506 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, state->max_requested_bpc = val; } else if (property == connector->privacy_screen_sw_state_property) { state->privacy_screen_sw_state = val; + } else if (property == connector->broadcast_rgb_property) { + state->hdmi.broadcast_rgb = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -859,6 +861,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->max_requested_bpc; } else if (property == connector->privacy_screen_sw_state_property) { *val = state->privacy_screen_sw_state; + } else if (property == connector->broadcast_rgb_property) { + *val = state->hdmi.broadcast_rgb; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index d9961cce8245..53abf213a045 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1183,6 +1183,29 @@ static const u32 dp_colorspaces = BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); +static const struct drm_prop_enum_list broadcast_rgb_names[] = { + { DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" }, + { DRM_HDMI_BROADCAST_RGB_FULL, "Full" }, + { DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" }, +}; + +/* + * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection + * @broadcast_rgb: Broadcast RGB selection to compute name of + * + * Returns: the name of the Broadcast RGB selection, or NULL if the type + * is not valid. + */ +const char * +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb) +{ + if (broadcast_rgb > DRM_HDMI_BROADCAST_RGB_LIMITED) + return NULL; + + return broadcast_rgb_names[broadcast_rgb].name; +} +EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name); + /** * DOC: standard connector properties * @@ -1655,6 +1678,35 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); /** * DOC: HDMI connector properties * + * Broadcast RGB (HDMI specific) + * Indicates the Quantization Range (Full vs Limited) used. The color + * processing pipeline will be adjusted to match the value of the + * property, and the Infoframes will be generated and sent accordingly. + * + * The CRTC attached to the connector must be configured by user-space to + * always produce full-range pixels. + * + * The value of this property can be one of the following: + * + * Automatic: + * The quantization range is selected automatically based on the + * mode according to the HDMI specifications (HDMI 1.4b - Section + * 6.6 - Video Quantization Ranges). + * + * Full: + * Full quantization range is forced. + * + * Limited 16:235: + * Limited quantization range is forced. Unlike the name suggests, + * this works for any number of bits-per-component. + * + * Property values other than Automatic can result in colors being off (if + * limited is selected but the display expects full), or a black screen + * (if full is selected but the display expects limited). + * + * Drivers can set up this property by calling + * drm_connector_attach_broadcast_rgb_property(). + * * content type (HDMI specific): * Indicates content type setting to be used in HDMI infoframes to indicate * content type for the external device, so that it adjusts its display @@ -2517,6 +2569,39 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn } EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property); +/** + * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property + * @connector: connector to attach the property on. + * + * This is used to add support for forcing the RGB range on a connector + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = connector->broadcast_rgb_property; + if (!prop) { + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, + "Broadcast RGB", + broadcast_rgb_names, + ARRAY_SIZE(broadcast_rgb_names)); + if (!prop) + return -EINVAL; + + connector->broadcast_rgb_property = prop; + } + + drm_object_attach_property(&connector->base, prop, + DRM_HDMI_BROADCAST_RGB_AUTO); + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property); + /** * drm_connector_attach_colorspace_property - attach "Colorspace" property * @connector: connector to attach the property on. diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 000a2a156619..3867a4c01b78 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -368,6 +368,30 @@ enum drm_panel_orientation { DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +/** + * enum drm_hdmi_broadcast_rgb - Broadcast RGB Selection for an HDMI @drm_connector + */ +enum drm_hdmi_broadcast_rgb { + /** + * @DRM_HDMI_BROADCAST_RGB_AUTO: The RGB range is selected + * automatically based on the mode. + */ + DRM_HDMI_BROADCAST_RGB_AUTO, + + /** + * @DRM_HDMI_BROADCAST_RGB_FULL: Full range RGB is forced. + */ + DRM_HDMI_BROADCAST_RGB_FULL, + + /** + * @DRM_HDMI_BROADCAST_RGB_LIMITED: Limited range RGB is forced. + */ + DRM_HDMI_BROADCAST_RGB_LIMITED, +}; + +const char * +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb); + /** * struct drm_monitor_range_info - Panel's Monitor range in EDID for * &drm_display_info @@ -1037,6 +1061,11 @@ struct drm_connector_state { * @drm_atomic_helper_connector_hdmi_check(). */ struct { + /** + * @broadcast_rgb: Connector property to pass the + * Broadcast RGB selection value. + */ + enum drm_hdmi_broadcast_rgb broadcast_rgb; } hdmi; }; @@ -1706,6 +1735,12 @@ struct drm_connector { */ struct drm_property *privacy_screen_hw_state_property; + /** + * @broadcast_rgb_property: Connector property to set the + * Broadcast RGB selection to output with. + */ + struct drm_property *broadcast_rgb_property; + #define DRM_CONNECTOR_POLL_HPD (1 << 0) #define DRM_CONNECTOR_POLL_CONNECT (1 << 1) #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) @@ -2026,6 +2061,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); +int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector); int drm_connector_attach_colorspace_property(struct drm_connector *connector); int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector); bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state, From patchwork Mon Feb 12 13:12:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199754 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2419809dyd; Mon, 12 Feb 2024 05:17:36 -0800 (PST) X-Google-Smtp-Source: AGHT+IEqjV9LMqtWviLBSUvizPnvq2HjEI91cGKhaPDwYipLW5QopVzrwtilPVNWhTutpgIoQCJR X-Received: by 2002:a17:906:194d:b0:a3c:2fcb:97e1 with SMTP id b13-20020a170906194d00b00a3c2fcb97e1mr5868366eje.13.1707743856148; Mon, 12 Feb 2024 05:17:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743856; cv=pass; d=google.com; s=arc-20160816; b=Jy6FRaw7ZyYiHoaEH1N0gJ3sFczcMwwRs3iXor8QEJV1rVE3CAuxpa0C18xozYEUft oILEYGeiFamHT6I1uIZGkWDZbIClHSPcd4gWmVu/ucitwa3DdPCGgryCkWAh4Rt7v48g MyuPOdKLg6Dkk94fVKPsNNt1bOxe761gzzRQXbGTNZRYx2gefGR8YbCojLModF6ePUSt i+2+O/r2x4rz0P4QdGGWBZ9dhGzvN94fdzvRIvxC9uS8CwMyjfzz9cHR/tnbmdkrxSnH ZM4WfE02o+VggjFeAP4griBL1ZC9RvejoHoirokmhOk8sMsD36Trt9XEQf9isaJv/wxw 38aw== 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=t+iFqsPxuodJAWEuldgDTwQAkLOTKdR1Y26ppur4KpQ=; fh=jqCrhSrpntDY9vFe+k9/7rMx1eABGHx364SK0bhm66Q=; b=cLKJfQK95MYDLc5ChFHaAxEtTCGx+TiClyhtfBUTDLNz86MweFZ5gnlOL1bTCYT17j DYjfax1vDmvSP7skr5+111NEy5FbA6ne4yE+aWrVQlaoR9y0bzRo4C5yDGjFS1WTEWrN h2iKA6GFGe1uiROA5FLdAoIJXsg0OM20dFkzAeZLIixz62bf7LoEECYIV6hNLKrM+1Ll 44i4jQlKa89ujsL7FqN9fqiYThg7fb+Oz0sH5qLQyG0IjV3X4d0yMbIyIWO2rNspWywb DVye0xXOEkpHrypKKL/tN+5PhLhhd0+BEYWCWH8dlgHBUMyPCj+H/YUryWERHXPGLvi1 IzYA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Xv58wiIC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61624-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61624-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXpHUmmZWkcxoYvZSRMCrMBVpUv6PrYXnLH23mSdjin9cAJ0qFyg2jjjv9mtdA3Y5SXGYREqIsZrxR+XckOm1FYVIouUQ== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a20-20020a1709066d5400b00a381793e309si182242ejt.292.2024.02.12.05.17.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:17:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61624-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Xv58wiIC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61624-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61624-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 910B01F21E8E for ; Mon, 12 Feb 2024 13:17:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 68FAC3D982; Mon, 12 Feb 2024 13:14:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Xv58wiIC" 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 BB9FF3D3B4; Mon, 12 Feb 2024 13:13:56 +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=1707743636; cv=none; b=ZbYXlJOMUOgpVeeJMkje8Z9aZej51jH5G9DZxBm5vYRGsZW0YLBhn4di+FZZz4ilIPTuL9YK+4+f806y+NdyUHobNUV9t7P9bnorVVIXrw3ccCmx7ohDGHoUkuJ1g/WVuIKI95sU/yZQHkCyYANdmuPKYpZHdHTuGVTyFnb+SCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743636; c=relaxed/simple; bh=xWnV9/UX8vxWEg4yXiNnml4FxowIP+SBSIm6eU6WKNc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Rj0PydDe8ElhURGyueEbHlwRVH5hdBqXNfnsFeEpI1vqF6kZXmeiYvn/E0YmX1wEFOELyYHInl86M4yJ+QbvgNJSl9ZPAfE/d6CKEIpKIiCTu7N1E1jmFJzoJVUgYSiILtGdLEM3WbQy5g93wjD1Vu845xVIqaoekrJD9sPjAMY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Xv58wiIC; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 41D8EC43390; Mon, 12 Feb 2024 13:13:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743636; bh=xWnV9/UX8vxWEg4yXiNnml4FxowIP+SBSIm6eU6WKNc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Xv58wiICTGOb529zSB+m45eFPFFaAqZK/tZAiXOFaASPVk/PkhFnsUhmnB92BUSTi Ce3GsAQ99VBghPCMab5C4c89WOfouLB4QB9NL450ehWA/2dKL385ICMbV3TcoCemgU W1VYZh1gCkNhjSd2XF8a6xJzLZl3z+92bYvkTjUXDDDZ/eNdkDyJRK6/J0sXqmcM1+ I3dlMPApfgEHtI2UYI249VwT/iykgurLLE6xkr9KRgNQF93oIKs/CjTtqqn2Do9trz VBvPYo5R9GgJS5uiBpNWtpP+40AjmkrNVQ311fMwCRc9yB6aqOZEUz/Ce6hPzPvWKw 6tGVwGJKeJUwg== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:53 +0100 Subject: [PATCH v6 10/36] drm/tests: Add tests for Broadcast RGB property Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-10-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=23249; i=mripard@kernel.org; h=from:subject:message-id; bh=xWnV9/UX8vxWEg4yXiNnml4FxowIP+SBSIm6eU6WKNc=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJFMcGZcl27be53uqvW+90ZtcRqv7u58t7I0Lfqy3P /3xK8ZXHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE8gQBi5OAZhI+jNGhoWBz9csZ/tiaxuo aXCsSJpt0s79K4plTv66WqL0/5psYzvDP+XehkWTeTeX//BfP0kt9irDhAyONVu/n1q6KsykhqN tPx8A X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699221876902691 X-GMAIL-MSGID: 1790699221876902691 This had a bunch of kunit tests to make sure our code to handle the Broadcast RGB property behaves properly. This requires bringing a bit of infrastructure to create mock HDMI connectors, with custom EDIDs. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/Makefile | 1 + .../gpu/drm/tests/drm_atomic_state_helper_test.c | 376 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_connector_test.c | 117 ++++++- drivers/gpu/drm/tests/drm_kunit_edid.h | 106 ++++++ 4 files changed, 599 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index d6183b3d7688..b29ddfd90596 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \ drm_kunit_helpers.o obj-$(CONFIG_DRM_KUNIT_TEST) += \ + drm_atomic_state_helper_test.o \ drm_buddy_test.o \ drm_cmdline_parser_test.o \ drm_connector_test.o \ diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c new file mode 100644 index 000000000000..21e6f796ee13 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Kunit test for drm_atomic_state_helper functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../drm_crtc_internal.h" + +#include + +#include "drm_kunit_edid.h" + +struct drm_atomic_helper_connector_hdmi_priv { + struct drm_device drm; + struct drm_plane *plane; + struct drm_crtc *crtc; + struct drm_encoder encoder; + struct drm_connector connector; + + const char *current_edid; + size_t current_edid_len; +}; + +#define connector_to_priv(c) \ + container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector) + +static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector) +{ + struct drm_device *drm = connector->dev; + struct drm_display_mode *mode, *preferred; + + mutex_lock(&drm->mode_config.mutex); + preferred = list_first_entry(&connector->modes, struct drm_display_mode, head); + list_for_each_entry(mode, &connector->modes, head) + if (mode->type & DRM_MODE_TYPE_PREFERRED) + preferred = mode; + mutex_unlock(&drm->mode_config.mutex); + + return preferred; +} + +static int light_up_connector(struct kunit *test, + struct drm_device *drm, + struct drm_crtc *crtc, + struct drm_connector *connector, + struct drm_display_mode *mode, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_atomic_state *state; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + int ret; + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + 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); + + 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); + + ret = drm_atomic_set_mode_for_crtc(crtc_state, mode); + KUNIT_EXPECT_EQ(test, ret, 0); + + crtc_state->enable = true; + crtc_state->active = true; + + ret = drm_atomic_commit(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + return 0; +} + +static int set_connector_edid(struct kunit *test, struct drm_connector *connector, + const char *edid, size_t edid_len) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv = + connector_to_priv(connector); + struct drm_device *drm = connector->dev; + int ret; + + priv->current_edid = edid; + priv->current_edid_len = edid_len; + + mutex_lock(&drm->mode_config.mutex); + ret = connector->funcs->fill_modes(connector, 4096, 4096); + mutex_unlock(&drm->mode_config.mutex); + KUNIT_ASSERT_GT(test, ret, 0); + + return 0; +} + +static int dummy_connector_get_modes(struct drm_connector *connector) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv = + connector_to_priv(connector); + const struct drm_edid *edid; + unsigned int num_modes; + + edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len); + if (!edid) + return -EINVAL; + + drm_edid_connector_update(connector, edid); + num_modes = drm_edid_connector_add_modes(connector); + + drm_edid_free(edid); + + return num_modes; +} + +static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = { + .atomic_check = drm_atomic_helper_connector_hdmi_check, + .get_modes = dummy_connector_get_modes, +}; + +static void dummy_hdmi_connector_reset(struct drm_connector *connector) +{ + drm_atomic_helper_connector_reset(connector); + __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); +} + +static const struct drm_connector_funcs dummy_connector_funcs = { + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .fill_modes = drm_helper_probe_single_connector_modes, + .reset = dummy_hdmi_connector_reset, +}; + +static +struct drm_atomic_helper_connector_hdmi_priv * +drm_atomic_helper_connector_hdmi_init(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector *conn; + struct drm_encoder *enc; + struct drm_device *drm; + struct device *dev; + int ret; + + dev = drm_kunit_helper_alloc_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + + priv = drm_kunit_helper_alloc_drm_device(test, dev, + struct drm_atomic_helper_connector_hdmi_priv, drm, + DRIVER_MODESET | DRIVER_ATOMIC); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + test->priv = priv; + + drm = &priv->drm; + priv->plane = drm_kunit_helper_create_primary_plane(test, drm, + NULL, + NULL, + NULL, 0, + NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane); + + priv->crtc = drm_kunit_helper_create_crtc(test, drm, + priv->plane, NULL, + NULL, + NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc); + + enc = &priv->encoder; + ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + + enc->possible_crtcs = drm_crtc_mask(priv->crtc); + + conn = &priv->connector; + ret = drmm_connector_hdmi_init(drm, conn, + &dummy_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + NULL); + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_connector_helper_add(conn, &dummy_connector_helper_funcs); + drm_connector_attach_encoder(conn, enc); + + drm_mode_config_reset(drm); + + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + return priv; +} + +/* + * Test that if we change the RGB quantization property to a different + * value, we trigger a mode change on the connector's CRTC, which will + * in turn disable/enable the connector. + */ +static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *old_conn_state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + new_conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; + + KUNIT_ASSERT_NE(test, + old_conn_state->hdmi.broadcast_rgb, + new_conn_state->hdmi.broadcast_rgb); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + new_conn_state = drm_atomic_get_new_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL); + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); +} + +/* + * Test that if we set the RGB quantization property to the same value, + * we don't trigger a mode change on the connector's CRTC and leave the + * connector unaffected. + */ +static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *old_conn_state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + new_conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb; + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state = drm_atomic_get_new_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + KUNIT_EXPECT_EQ(test, + old_conn_state->hdmi.broadcast_rgb, + new_conn_state->hdmi.broadcast_rgb); + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); +} + +static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { + KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), + KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), + { } +}; + +static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = { + .name = "drm_atomic_helper_connector_hdmi_check", + .test_cases = drm_atomic_helper_connector_hdmi_check_tests, +}; + +/* + * Test that the value of the Broadcast RGB property out of reset is set + * to auto. + */ +static void drm_test_check_broadcast_rgb_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO); +} + +static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = { + KUNIT_CASE(drm_test_check_broadcast_rgb_value), + { } +}; + +static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = { + .name = "drm_atomic_helper_connector_hdmi_reset", + .test_cases = drm_atomic_helper_connector_hdmi_reset_tests, +}; + +kunit_test_suites( + &drm_atomic_helper_connector_hdmi_check_test_suite, + &drm_atomic_helper_connector_hdmi_reset_test_suite, +); + +MODULE_AUTHOR("Maxime Ripard "); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 8f070cacab3b..41d33dea30af 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -12,6 +12,8 @@ #include +#include "../drm_crtc_internal.h" + struct drm_connector_init_priv { struct drm_device drm; struct drm_connector connector; @@ -357,10 +359,123 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { .test_cases = drm_get_tv_mode_from_name_tests, }; +struct drm_hdmi_connector_get_broadcast_rgb_name_test { + unsigned int kind; + const char *expected_name; +}; + +#define BROADCAST_RGB_TEST(_kind, _name) \ + { \ + .kind = _kind, \ + .expected_name = _name, \ + } + +static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test) +{ + const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params = + test->param_value; + + KUNIT_EXPECT_STREQ(test, + drm_hdmi_connector_get_broadcast_rgb_name(params->kind), + params->expected_name); +} + +static const +struct drm_hdmi_connector_get_broadcast_rgb_name_test +drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = { + BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"), + BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"), + BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"), +}; + +static void +drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t, + char *desc) +{ + sprintf(desc, "%s", t->expected_name); +} + +KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid, + drm_hdmi_connector_get_broadcast_rgb_name_valid_tests, + drm_hdmi_connector_get_broadcast_rgb_name_valid_desc); + +static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test) +{ + KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3)); +}; + +static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = { + KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name, + drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params), + KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid), + { } +}; + +static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = { + .name = "drm_hdmi_connector_get_broadcast_rgb_name", + .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, +}; + +static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_property *prop; + int ret; + + ret = drmm_connector_init(&priv->drm, connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = drm_connector_attach_broadcast_rgb_property(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + prop = connector->broadcast_rgb_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); +} + +static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_property *prop; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc); + KUNIT_EXPECT_EQ(test, ret, 0); + + ret = drm_connector_attach_broadcast_rgb_property(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + prop = connector->broadcast_rgb_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); +} + +static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = { + KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property), + KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector), + { } +}; + +static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = { + .name = "drm_connector_attach_broadcast_rgb_property", + .init = drm_test_connector_init, + .test_cases = drm_connector_attach_broadcast_rgb_property_tests, +}; + kunit_test_suites( &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, - &drm_get_tv_mode_from_name_test_suite + &drm_connector_attach_broadcast_rgb_property_test_suite, + &drm_get_tv_mode_from_name_test_suite, + &drm_hdmi_connector_get_broadcast_rgb_name_test_suite ); MODULE_AUTHOR("Maxime Ripard "); diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h new file mode 100644 index 000000000000..2bba316de064 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -0,0 +1,106 @@ +#ifndef DRM_KUNIT_EDID_H_ +#define DRM_KUNIT_EDID_H_ + +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 + * + * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c + * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * Monochrome or grayscale display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x92 + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Native detailed modes: 1 + * Colorimetry Data Block: + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: No Data + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * Maximum TMDS clock: 200 MHz + * Extended HDMI video details: + * Checksum: 0xd0 Unused space in Extension Block: 100 bytes + */ +const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, + 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x00, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0 +}; + +#endif // DRM_KUNIT_EDID_H_ From patchwork Mon Feb 12 13:12:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199753 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2419782dyd; Mon, 12 Feb 2024 05:17:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IGk1zfkUsV99Xy9jPSg6qKynwYhuZX6IOOWTYrPBYslSn1AnlnlC8ch4csdqitCV070lSeP X-Received: by 2002:a17:902:b783:b0:1d8:ebdf:183a with SMTP id e3-20020a170902b78300b001d8ebdf183amr7535857pls.6.1707743854093; Mon, 12 Feb 2024 05:17:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743854; cv=pass; d=google.com; s=arc-20160816; b=SJnkeA4Ntp2vyMpzsseBmYBCkfIXxr5+ROSNmNo465bM1LtxztNZs1s3qxYVRbGmRh tV/Qy2J4wYviNDikyqaujsVnio33VbHLk9WhCIz0PbYuowE4eOmSWN8mCntclHyh993A 0gWHvMz1Gwi6p/c9FW3nIzlb4pqcsyG0LjYLFRVEtP6yhQ18TB0gD2aF4yfPwTCdb/MD JpNbPJF6B6NGjhzOEQWA/wqGkNW/qYVad2NwwsofJpjhEoNjvQ0jtk7ihJz+/67nHW4K QFXE/bX6b5l19ejqXcEa+WLDiO5hxbFHjNEvPH/PS7VsiGjNZgq5+HIcz/MDFJzshZ0n StuQ== 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=/AxO4mhg3lwtWGKaeo0nJjZrXRGz/q/OzgMA+R5XEBw=; fh=KWebz5VIrkFtqb5a5Mv3DDHvGJbCQl0X0tUUOL+5gU8=; b=g7tfS8waEn7zZtXEfnkgdwGetNmI/aZZN+XFcC7URRmeErY3lUnZV8F+vZg9FguQ7q ikhAly56EL6ncGB68b7/q7KBSUM4SVdjaoqHxzE9EMhXmRwi6sOSvCThg32w3Hx+7CMx 7radNl4UgLkh0eO1HacFmETEujpw2Ly6XQA4BYtULhGpBWGgFzY6JlHHve0dBFmAzCpZ aDO/GYrCteSXBgyIKAPzku9OKaufygT2rXN+XCdhMH0LWM6MS0YDTh3BBvPG44Ty+9w1 7CeWqGTAtKvlrM70SsjkFYAyQjNoLUh80jUCfJH9GYI8mXV+gP13yd3UT/hJYC8n72hS SZ3w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=aPgnXpLo; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61625-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61625-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVqIoLjuptPfotkEo/9xuaTY3eabz72r31mTyLHcGMIewnbzI1As7TZhtAlYHeqo168SV5it5qCmAl5C5kSAt9jTRXKTQ== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id g8-20020a170902740800b001db2818a19esi231280pll.231.2024.02.12.05.17.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:17:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61625-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=aPgnXpLo; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61625-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61625-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 2627E283463 for ; Mon, 12 Feb 2024 13:17:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B63733D974; Mon, 12 Feb 2024 13:14:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aPgnXpLo" 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 A4F463D566; Mon, 12 Feb 2024 13:13:59 +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=1707743639; cv=none; b=hG3tE6u1w0P75bdeCeYOequbWIlquIoKZXm91Iwcq219nNnAw7wmna0XqsL9XvVlESyu6CU7yHIQxSEpYu+oG3FxWmspDrL3cnH2uud/25MnePdkAXXXFSHH1u9UsJMjM9GHSntHpUYz+NgI8k2PsCJzChAwOlFAbKD5tQeF3Rw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743639; c=relaxed/simple; bh=Uci5nUWFbopiU9JwFehIK0RWTdqj3fqfRO4WqS8ziZg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hpebe8w9myEEp+ITyzcfIzzGRvuiJjs+WLxL38OgUbwJniqsQwfOKYcp5m/xjJ/L+5mGjsz7p9P+tTx23rK9WY4kNe+ENHZ29/VdCtMvGOSEnL0wSq0Cmk/bb6H1ZUQ1uov7ScYtwoOY2n2Z1LQ8oIb3xZJILmE0hWMuUgFP0Hk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aPgnXpLo; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26EBBC433C7; Mon, 12 Feb 2024 13:13:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743639; bh=Uci5nUWFbopiU9JwFehIK0RWTdqj3fqfRO4WqS8ziZg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aPgnXpLoSCS2gXcpPVgwke7qp7T1PP/zCXkyxxHo2b7zb/PNAAONXihB3n9gC8+Fb 7ZidSY6HBhFPB0ncdnw6G32kzBeiAss+Yt3ZabzypK1z/fdhydvGbiWPiOmE/tNT6O u1tC5R74Lkn+sHE/F5pQDY9KN9FEp4HWD3SQaMo4vd4+5YTsrAWSWkCGJOeOz+XRs8 KXiYk86sxtnQ8CpgH3uj3J3+vCvPl2oczkZUHbJBmEIPWDUuBcgZOkOt5O1/OVNDej qU7s8pUnJgHIqwBMbAINyWMZoKiQtvjDgANKfIRgh6R2nDE28aLySfBsEv4sTo6LQU us3guei4uAmRA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:54 +0100 Subject: [PATCH v6 11/36] drm/connector: hdmi: Add RGB Quantization Range to the connector state Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-11-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4240; i=mripard@kernel.org; h=from:subject:message-id; bh=Uci5nUWFbopiU9JwFehIK0RWTdqj3fqfRO4WqS8ziZg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJFNndfSHrv3wft5BQ9s3BpPOTZI5cv3VmQ77bxPWe /88MumUeUcpC4MYF4OsmCJLjLD5krhTs153svHNg5nDygQyhIGLUwAm0vSd4X/wY3afGnM+MR6V 5dKeD3v/+yeI6TKu37T4dpDS4gDPn1KMDFt0tmRPcgxu4lE+uTbmYs2+P8eFImN+nfPLPriSt2n bK1YA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699219387731845 X-GMAIL-MSGID: 1790699219387731845 HDMI controller drivers will need to figure out the RGB range they need to configure based on a mode and property values. Let's expose that in the HDMI connector state so drivers can just use that value. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 4 ++- drivers/gpu/drm/drm_atomic_state_helper.c | 44 +++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 6 +++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 93831850ffcd..0c283964cee0 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1144,9 +1144,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace)); if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || - connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { drm_printf(p, "\tbroadcast_rgb=%s\n", drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); + drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n'); + } if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index d93bc7f5faee..08db9956840b 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -637,6 +638,47 @@ 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 bool hdmi_is_full_range(const struct drm_connector *connector, + const struct drm_connector_state *state) +{ + const struct drm_display_info *display = &connector->display_info; + const struct drm_display_mode *mode = + connector_state_get_mode(state); + + if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL) + return true; + + if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED) + return false; + + if (!display->is_hdmi) + return true; + + return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -657,6 +699,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_connector_state *new_state = drm_atomic_get_new_connector_state(state, connector); + new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) { struct drm_crtc *crtc = new_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3867a4c01b78..76eecd449fb8 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1066,6 +1066,12 @@ struct drm_connector_state { * Broadcast RGB selection value. */ enum drm_hdmi_broadcast_rgb broadcast_rgb; + + /** + * @is_full_range: Is the output supposed to use a full + * RGB Quantization Range or not? + */ + bool is_full_range; } hdmi; }; From patchwork Mon Feb 12 13:12:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199755 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2420054dyd; Mon, 12 Feb 2024 05:17:58 -0800 (PST) X-Google-Smtp-Source: AGHT+IHc8RxqfIDI7TZgJWdw6rVzhYa/jGzwGRxg2zztjs7Fpo94xQCo8rg5gb96nKG4TDsep0+j X-Received: by 2002:a05:6402:31f9:b0:560:bbcf:1f45 with SMTP id dy25-20020a05640231f900b00560bbcf1f45mr4205557edb.5.1707743878196; Mon, 12 Feb 2024 05:17:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743878; cv=pass; d=google.com; s=arc-20160816; b=yfZJIiFGv7NG02OArCxZ3DufzbGejs/Iyrjoq9YimbVsM9vUlfJi1DtD9IjzbbLsM3 iHC7/RHIRCCfevU7j+MlN4pfHhg8OG8TypXWW5QIJ/aI9W21oCGBxpvF6ANwFHaShTIU GyMyqJUA4nrBjM0Jxrz0Jz6YPxNSpyvWpJwRnknPZAb+eNRMIcEtONDoKABXV+gkowuJ iHzsPiPQLXyFN4B2sZ5JFxa24h2w2BKmlZK9Q24YqiYzNMhH4IulenAejXvze6TC2N8a XM4a4LM9ZeHYf3zSe00SR0BMWtt3Qn1LMLl1hEwk3whDu8f4s4lJt6d5Oqm8YYUyOETz UDDg== 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=6Qo8dXSf4ZnoVm8pfTac7tlmxrLJxisc1SDTPhI33t8=; fh=hwRpHj4Oe+CBrqyYBTvvPe4NvbgfZNhcI4evHhLZmzc=; b=GoTMWBzRp4HyqLQlsnCQ5voSDUaHG4gJmzOakFWw6SExQYvTTyJ28h0luDxwj/c0eV 3LXF2uY/oMGzo5jdOCr840jVKK/eN2EZMTK/DWolsKmwSrKtZbMexIy57YKiw7N1/gSH FHFOCByz/vzBE3tmFnYSYqywypED4DNAGjAiiERUa4aq9EKRNm0jLzGB2ArZwSFN3SKd G0dcEdGvku9bY6IwpRsosBtH9O0mRLAvnoItZjRNytI8TQsEs55IoCpEPMs5yZ1I+6iZ aJLVcO7rHbbN4MQmBfGiRo3VVgEtEmYCJigz8OB4l7AE7ZDKLhLHOkC+gXoif0UkGOfY aPOQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=SrwB2zbH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61626-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61626-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWyNghP3kktlFrpsJNuTkle84rkQtbt+u1pxLBzETrjHlXfRnDm5RbMjvGot690dP54Mscn+9zafItQYX5jUVitQbKyTw== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id t21-20020a50ab55000000b005606570c919si2665345edc.82.2024.02.12.05.17.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:17:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61626-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=SrwB2zbH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61626-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61626-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 9E8611F214F3 for ; Mon, 12 Feb 2024 13:17:57 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BBEE93E47C; Mon, 12 Feb 2024 13:14:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SrwB2zbH" 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 114BB3D97F; Mon, 12 Feb 2024 13:14:02 +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=1707743643; cv=none; b=g9FbV0XRE1GKLjs5fhdjyQUd1ClSot0fkzmhiWzR1Srm1Lf90RHzsmxg8W4Lqm6IsHArliMb634/41U5ydffxz3D/DXrobftl5A4i7Eo4vLq8sYXgQAf3tGzfIzZ/bSrQb4BvGJFMsy6ChTPIyzuESufIuklmZVA61c73OIDTsg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743643; c=relaxed/simple; bh=z4qNa5xxrLUUiM37RiiQEIfiw88IwhokP/VU/FChvO0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fp9EbLBOx/OYpcVGFZUETHGffojHjccNvVl5HxDdqb7PStdK3jzqB2HdOxjiKazoKc3yEY6kicFDjAb8nzYtGlKT86B/X+rF7qLfISz+JeTLr74FpfQ9Ds4sWNE2EAWqSk2wL/hH62Acsr0iINx8KTI0xMNhK8T48HFa+PKPQRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SrwB2zbH; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 46A21C43601; Mon, 12 Feb 2024 13:14:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743642; bh=z4qNa5xxrLUUiM37RiiQEIfiw88IwhokP/VU/FChvO0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SrwB2zbH4eEEu0ZdSSBAYfa+6aOU57BHm/uZe5294jX75u0HBMLYbu+XvAGldf1XH HHSz+YqwjO1Nh9s139Boan/6yvfP8zYbW834BmYUiBChD7BxnvkA4ajyuMDeZGP28H mjrNIWcJOzUy1DKu6Z2X1hlNq7T8hwFmjuBHR0WmUX3KHicyBor5oWM6DR5r1O9iW0 6URcvN8z/uRwUKPqyd11PhjjZdxSTEDJULs+g1GSFz6Ba9E8zVjsgbDchto6+KBIIS 0ACVj+oHCNvoDrVYfjP6NdYXf9yI50DutpazDXaY3LDBRRsE4+u509p8rPrHFnXq2I fG8GL7WlNHBxQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:55 +0100 Subject: [PATCH v6 12/36] drm/tests: Add RGB Quantization tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-12-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=12158; i=mripard@kernel.org; h=from:subject:message-id; bh=z4qNa5xxrLUUiM37RiiQEIfiw88IwhokP/VU/FChvO0=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJFN9HnK/elUjetjqVtfV1Xrx82MVb8X/zHyX+cLmw /X4h89ndpSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiZ6czMkzyUlQ+eXDRXqff L5OuSvduur/y/p3zp5/ncyn7dB2JEYhj+Ked+5U547PHmplvDb+aGWydIZb7bnbq9MSX2fOts56 G7mECAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699245244088693 X-GMAIL-MSGID: 1790699245244088693 The previous commit added the infrastructure to the connector state to track what RGB Quantization should be used in a given state for an HDMI connector. Let's add some kunit tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 335 +++++++++++++++++++++ 1 file changed, 335 insertions(+) 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 21e6f796ee13..7750c3d214a4 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -328,7 +328,342 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); } +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to auto with a mode that isn't the + * VIC-1 mode, we will get a limited RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_AUTO); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to auto with a VIC-1 mode, we will get + * a full RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_AUTO); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to full with a mode that isn't the + * VIC-1 mode, we will get a full RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_FULL); + + KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to full with a VIC-1 mode, we will get + * a full RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_FULL); + + KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to limited with a mode that isn't the + * VIC-1 mode, we will get a limited RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED; + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_LIMITED); + + KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that for an HDMI connector, with an HDMI monitor, if the + * Broadcast RGB property is set to limited with a VIC-1 mode, we will + * get a limited RGB Quantization Range. + */ +static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED; + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, + conn_state->hdmi.broadcast_rgb, + DRM_HDMI_BROADCAST_RGB_LIMITED); + + KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { + KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), + KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), + KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode), + KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1), + KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode), + KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), { } From patchwork Mon Feb 12 13:12:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199756 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2420235dyd; Mon, 12 Feb 2024 05:18:15 -0800 (PST) X-Google-Smtp-Source: AGHT+IEf1LubZOtQ0VJFzMiXugLUpAnlInPFuQnVv+sqI7HhG7NpZ1s/uvcLB0qaYThpVlL4o6M4 X-Received: by 2002:a05:6214:519e:b0:68d:14ed:13bd with SMTP id kl30-20020a056214519e00b0068d14ed13bdmr2411028qvb.46.1707743895211; Mon, 12 Feb 2024 05:18:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743895; cv=pass; d=google.com; s=arc-20160816; b=o5v7/bspeR/H97q6SQv7RYQxpkAtrVM/uNrd5BKrta86BogZs7KpARX/GPdLhY41qO QQbjGlEs3fDqHMUDPH5eVJjCOoNWhv+QVuH3J6b+Ds6g+QFmxKSpG8daEB3MZKanxFYx T1IXshaTyu1fpaEsyOxDaFLwm8Z9iEin2gLukFSxuNzY6M7u0LKNcqh1NDF+KF8GI0T5 7mWPKSQaPACUTe45C8+LEsDFclFMZXZZf37oEdeUFQeT33Z06/5c87nf836IM+/KH+YP hOvX4R1k7ymJB6/oCme2ZApxOW+J/sPThtq7W9Lu+meLI6dd9VsK71aLcX8FKwl/k3iS jrGg== 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=5CipoO7iOxkxnFlSNVnwJjmMz18txywoeKvk5Gr0HrA=; fh=SeXJDGM+w99but812TYddbNFsbjxhWHOSPFA4+ykR90=; b=lEAD8/PsEBBo+Z5dtu0cOvFFO2maBkT6qFdfgKCiJ+iVUwLeG+7+pXVhvZbCEUt6ub QLnwobzvbiJFgsANUc0R9AXNhG4v6124LGti9f/tpiRBkVUBJ7bRoWBVttwfsiy/8kq6 loTJc8de+YsW/0CJOJby+NRLJCJ23sfsVKt4jcaDJ3F3/dSAGDwKilaEs7au8C8PVPYb soI9avdXEZOWqsxTiNmiRbihL+lqdyIWLCKO6ZbvSNyfQ6/QKfbowtVecQWbYwL9x62X GejPjDDdPN298cFHjWjTc7E4/wjDQu5JzZMtuSUMnSBe91f07D6ZQ2gyBk5UHU3NS5kv hrbw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=gxNV4ehr; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61627-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61627-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVWfWDPqMEwsnaD1AyHUmDOlGGTrmB9TJX3zAyI62xYek4cgpJcdFbVJ0AMSWB3Vm/qcHNYIRcqGKvmfzfdqFf6eYdlfg== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id jo11-20020a056214500b00b0068c8bf7a3d8si350413qvb.334.2024.02.12.05.18.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:18:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61627-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=gxNV4ehr; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61627-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61627-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id E7E1F1C21A02 for ; Mon, 12 Feb 2024 13:18:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 764F13EA76; Mon, 12 Feb 2024 13:14:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gxNV4ehr" 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 E80FE3DB92; Mon, 12 Feb 2024 13:14:05 +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=1707743646; cv=none; b=LTPtz6bAW1SvyyA1NpDYTd/pyB8Y9sdh3oyGfcKQDz7qj6tYSm1vHxrhvYONSgf2VCRSyZamUK9NxB2FIIImNZBYo8WS/5SabYUC+6q0E+SQp2xftrQyx3QRn6r0J7tW/AoYm2WxC/7/QhYbPdbETSKDCPm88yaAf2b5rcjJj2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743646; c=relaxed/simple; bh=XvHRjcHEGiov3nC8A3+QY9gmoUVMU7VKG4/iarE/bio=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mFsqHvKwYLa9jpVROOBokQGErUnkKcwg96mhlCivnDAQVXNginyejq7XmZ3TmKOrbPDTqfKB0CRtEQVVqbmPa6mOd9C+I57Q49JD8W4JjTFdCAR7QyPkeQ/264PYjZgtU5axnm/DCo7wAwesPngXSX05G/ts89IUpyaKmUKni7o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gxNV4ehr; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 250ABC433F1; Mon, 12 Feb 2024 13:14:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743645; bh=XvHRjcHEGiov3nC8A3+QY9gmoUVMU7VKG4/iarE/bio=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gxNV4ehrJRbEcJVUpKlsyn482unviXCacOgGYQ/B6Zluddv9FYzW6QKAZrGdJkCuE bK4bzpkncTD4+x0qzTF4iyGLpWgMvv9HK087A4/MP4x2A3VDOwQJ04UymyF3zSeFSg ZSYPLBvhf99V32yLbdrE3xSmWcQb5UwAioPo7M1q2J/WF5HH3veduwmaBtv9F8DN0c of1PS0uNWHNhSI5Imm4VEm5+ijh6qBf2xAixvpwLxJiBf8l3vS40/AHhncovmmLWw6 183pRJ6kwfGyVUSXNmfHng7j6D/wTVbBG4bjI94DL7Vt9cTTDURSmj4RsPqn7cVGgN CXGIF9oAgFnwA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:56 +0100 Subject: [PATCH v6 13/36] drm/connector: hdmi: Add output BPC to the connector state Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-13-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=11447; i=mripard@kernel.org; h=from:subject:message-id; bh=XvHRjcHEGiov3nC8A3+QY9gmoUVMU7VKG4/iarE/bio=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJNNWNDXxTDvJsi5rw/bfF+a97V8jvu7I4m2Hz53fs lXkPWPDyo5SFgYxLgZZMUWWGGHzJXGnZr3uZOObBzOHlQlkCAMXpwBMZPk/Robz8fcS6w40r03v 9Dpb+ibVwsNLeJLxYf8FNi/vzF4Yo7aTkeHZ63cs841Kn1spcVSkTw854L+Lab/rR+Hk6tA46VU zjrECAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699262689121221 X-GMAIL-MSGID: 1790699262689121221 We'll add automatic selection of the output BPC in a following patch, but let's add it to the HDMI connector state already. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 7 ++++++- drivers/gpu/drm/drm_connector.c | 20 +++++++++++++++++- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 24 ++++++++++++---------- drivers/gpu/drm/tests/drm_connector_test.c | 15 +++++++++----- include/drm/drm_connector.h | 13 +++++++++++- 6 files changed, 61 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 0c283964cee0..5fcdab90c793 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, "\tbroadcast_rgb=%s\n", drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n'); + drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); } 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 08db9956840b..2025d053e54f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -585,6 +585,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, struct drm_connector_state *new_state) { + unsigned int max_bpc = connector->max_bpc; + + new_state->max_bpc = max_bpc; + new_state->max_requested_bpc = max_bpc; new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO; } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); @@ -701,7 +705,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); - if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) { + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb || + old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) { struct drm_crtc *crtc = new_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 53abf213a045..ca39fd027e20 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @funcs: callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter + * @max_bpc: Maximum bits per char the HDMI connector supports * * Initialises a preallocated HDMI connector. Connectors can be * subclassed as part of driver connector objects. @@ -475,7 +476,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, - struct i2c_adapter *ddc) + struct i2c_adapter *ddc, + unsigned int max_bpc) { int ret; @@ -483,10 +485,26 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; + if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) + return -EINVAL; + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); if (ret) return ret; + /* + * drm_connector_attach_max_bpc_property() requires the + * connector to have a state. + */ + if (connector->funcs->reset) + connector->funcs->reset(connector); + + drm_connector_attach_max_bpc_property(connector, 8, max_bpc); + connector->max_bpc = max_bpc; + + if (max_bpc > 8) + drm_connector_attach_hdr_output_metadata_property(connector); + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); 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 7750c3d214a4..64ba1f6256ba 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -146,7 +146,8 @@ static const struct drm_connector_funcs dummy_connector_funcs = { static struct drm_atomic_helper_connector_hdmi_priv * -drm_atomic_helper_connector_hdmi_init(struct kunit *test) +drm_atomic_helper_connector_hdmi_init(struct kunit *test, + unsigned int max_bpc) { struct drm_atomic_helper_connector_hdmi_priv *priv; struct drm_connector *conn; @@ -188,7 +189,8 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test) ret = drmm_connector_hdmi_init(drm, conn, &dummy_connector_funcs, DRM_MODE_CONNECTOR_HDMIA, - NULL); + NULL, + max_bpc); KUNIT_ASSERT_EQ(test, ret, 0); drm_connector_helper_add(conn, &dummy_connector_helper_funcs); @@ -223,7 +225,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -284,7 +286,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -345,7 +347,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -399,7 +401,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -452,7 +454,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -508,7 +510,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -563,7 +565,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -619,7 +621,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -684,7 +686,7 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test); + priv = drm_atomic_helper_connector_hdmi_init(test, 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 41d33dea30af..96b19a5954b4 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -186,7 +186,8 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -202,7 +203,8 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, - NULL); + NULL, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -219,7 +221,8 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, connector_type, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -250,7 +253,8 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, connector_type, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -447,7 +451,8 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_EQ(test, ret, 0); ret = drm_connector_attach_broadcast_rgb_property(connector); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 76eecd449fb8..1b1b6aed04ee 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1072,6 +1072,11 @@ struct drm_connector_state { * RGB Quantization Range or not? */ bool is_full_range; + + /** + * @output_bpc: Bits per color channel to output. + */ + unsigned int output_bpc; } hdmi; }; @@ -1717,6 +1722,11 @@ struct drm_connector { */ struct drm_property_blob *path_blob_ptr; + /** + * @max_bpc: Maximum bits per color channel the connector supports. + */ + unsigned int max_bpc; + /** * @max_bpc_property: Default connector property for the max bpc to be * driven out of the connector. @@ -1956,7 +1966,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, - struct i2c_adapter *ddc); + struct i2c_adapter *ddc, + unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); From patchwork Mon Feb 12 13:12:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199757 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2420387dyd; Mon, 12 Feb 2024 05:18:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IEmFnHM06OrDPMqXrQuTS2MrqjRDLD38l/qFqhyDiWFWt57trHi7+bvgYOPPvlsDTJW+Qy9 X-Received: by 2002:a17:90a:fd0c:b0:297:2b83:a322 with SMTP id cv12-20020a17090afd0c00b002972b83a322mr2049983pjb.23.1707743911634; Mon, 12 Feb 2024 05:18:31 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743911; cv=pass; d=google.com; s=arc-20160816; b=ySkNRR4uXNXjBRgzeWx6Eaj6C0hzdX57qG6DxssIoWC12hRs7X9Ox0V9IpeRlG9XRH pUrWkeQuqvXRu21Ketj1AoRn2yFc8iKbYG68HwKH+Wsj4YKnBPqc9n/kpxVdL7P8NtqG JLr7nG/Jm+YMko76RC0c5LFHtqhrYdEwYwRQsd40/+i9KzqAmVfurMw4gpoFqCmJ4VYT 1k0FMj906+6WnmdblTuuYt9OjGxFt27n56jeC+sgFQOzpRXNyQD/LG9e/AzgFqssgUuh l+w9cAJxatDu6ejEiGNSnRcjkWx4mu4Yc5SxdIZ16qlLX22jCM955RiA4HaCa/3icbZK HZbA== 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=qMLSHImM8schj2NRKz55aNbgtgTfj/GvlCy3mSvPh54=; fh=i6gFnW5xKewDEE9TjPGsx1QMPeCa9hKaZvPeC4t4vYw=; b=Ia9ArfefDJRyAfMvalF0kvfRmYiUdDNl+nZ4GugeoD8MtxVZ6RZ5vMNftRbYrNUU2j 02zSF4yS8NYsPoyB5z4Ehu5KU8MmeCEUwwM8zisvJ8FFTKN620m/YhHaC3aN9+67XGOb KiKzGLNhUVWUVAy+9frTf1chL8CsY5aT6ZwAlH56CbVgBMzxWJ7HuZUK2LmTQ/t3BrG9 anUTdRr+99kjqewCXco9XN+Vh8eq1e7O6VRhGqoJ6Uo4sx7V+oon25T16mQdAdAVxVfb /GwnsOEY2aKqJShBgy51lsxInzMgy+6wMzwPSq3se5v3+bRdO1trg9YV3I7J1OUHLJeC oFxQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ahH0nBwE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61628-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61628-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVhgJi2HXh/NUUmbGgom5e5NhI0IeMmQDScwY/nntwzcp6+fLrHgWM+n+LJzsemD9C+ITSB4AAnXeGbcs44tX44OJZyNw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id pf10-20020a17090b1d8a00b00296fd42210dsi286393pjb.2.2024.02.12.05.18.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:18:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61628-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ahH0nBwE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61628-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61628-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 65AB2280FFE for ; Mon, 12 Feb 2024 13:18:31 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B868F3AC25; Mon, 12 Feb 2024 13:14:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ahH0nBwE" 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 BB6B83E494; Mon, 12 Feb 2024 13:14:08 +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=1707743648; cv=none; b=f4gXaYKCNkhsc8hkend2ZBNVLC3ck0nH28U6wOO6ji5BNuc7LdRc66g60NQKwJQVzP8rQqR0StCbQK3qaH4W2Z32iYd8vGtUwOrZt2JVwRx+vVMOp43xnyDKwXik6ENnZzpD4Vrsb2rlXVHyr1kwz7zeCDvyZcIRT2HJPnmGpI0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743648; c=relaxed/simple; bh=I4evIYup75xS6vmBfT/80RTCAbSYJRYnF6r52PiyOBA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aRzuCWvfTWT+wAe21eYWt0pYUQ8+VYoOLZqK+e28cZl8EvQLrayXWLIQImt9mjih3kRGqLWpG3vHhM3hJxl2/IpCHYmz+bnri43rM/QUD8k0eOUcLetPwTKpzr635+kmHhYjIR/p7a2++h0RhyhlNilmrlw6fvsgyPwo+VkJ1I4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ahH0nBwE; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9EA5C43394; Mon, 12 Feb 2024 13:14:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743648; bh=I4evIYup75xS6vmBfT/80RTCAbSYJRYnF6r52PiyOBA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ahH0nBwEi9enkoHNoo/mH37ytQWb9phtgwFPJBwtWqfe2BCHsJYOjUKTN+JcpBnvr PlSVPg34paLhS8jHQ5jEs6ChAaNoB0tTqzKGHsDZq67IqrNwzocq8mBCxGAbz9ZiAS zDRHnpT4KnPFWgao0xjZcEC+tV/jk0/dKw7VqMtsDfA2fI2xgiNAv9CuZm17Qhd/YY o1Fn9G3el2iPhJF6N74WvZrUtdmOD+sVz+yDhV4BJbTz80lnT+DliTqrQQAn379czU VoAHVbQDLWoHcLaMSQBUIs/XQuH/gmTQ8q3jamLMCMV4KbBwaSm8ofj4JD2LM5xSqY wFMWr0JIh5xbA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:57 +0100 Subject: [PATCH v6 14/36] drm/tests: Add output bpc tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-14-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=14272; i=mripard@kernel.org; h=from:subject:message-id; bh=I4evIYup75xS6vmBfT/80RTCAbSYJRYnF6r52PiyOBA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJNOk5scY3P/U5u2ho8nhFfM6pubNgttmX94ue6CkO ptB4WVRRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACayUpKRoWvdxAZ/9xDRKzdX tXa2zHvsZVLc/lhf+PmzVVPjBdulbBn+yu6t82TQ2ea570b15/ub752R/cYw5w5TkVHtx5RtfFY CTAA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699279917120583 X-GMAIL-MSGID: 1790699279917120583 Now that we're tracking the output bpc count in the connector state, let's add a few tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 203 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_connector_test.c | 138 ++++++++++++++ 2 files changed, 341 insertions(+) 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 64ba1f6256ba..a1b0e6914cf8 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -659,6 +659,138 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); } +/* + * Test that if we change the maximum bpc property to a different value, + * we trigger a mode change on the connector's CRTC, which will in turn + * disable/enable the connector. + */ +static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *old_conn_state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, 10); + KUNIT_ASSERT_NOT_NULL(test, priv); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + new_conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state->hdmi.output_bpc = 8; + + KUNIT_ASSERT_NE(test, + old_conn_state->hdmi.output_bpc, + new_conn_state->hdmi.output_bpc); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state = drm_atomic_get_new_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + KUNIT_ASSERT_NE(test, + old_conn_state->hdmi.output_bpc, + new_conn_state->hdmi.output_bpc); + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); +} + +/* + * Test that if we set the output bpc property to the same value, we + * don't trigger a mode change on the connector's CRTC and leave the + * connector unaffected. + */ +static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *old_conn_state; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, 10); + KUNIT_ASSERT_NOT_NULL(test, priv); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + new_conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + KUNIT_ASSERT_EQ(test, + new_conn_state->hdmi.output_bpc, + old_conn_state->hdmi.output_bpc); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + old_conn_state = drm_atomic_get_old_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); + + new_conn_state = drm_atomic_get_new_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + + KUNIT_EXPECT_EQ(test, + old_conn_state->hdmi.output_bpc, + new_conn_state->hdmi.output_bpc); + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), @@ -668,6 +800,8 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), + KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), + KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), { } }; @@ -694,8 +828,77 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO); } +/* + * Test that if the connector was initialised with a maximum bpc of 8, + * the value of the max_bpc and max_requested_bpc properties out of + * reset are also set to 8, and output_bpc is set to 0 and will be + * filled at atomic_check time. + */ +static void drm_test_check_bpc_8_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test, 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); +} + +/* + * Test that if the connector was initialised with a maximum bpc of 10, + * the value of the max_bpc and max_requested_bpc properties out of + * reset are also set to 10, and output_bpc is set to 0 and will be + * filled at atomic_check time. + */ +static void drm_test_check_bpc_10_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test, 10); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10); + KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); +} + +/* + * Test that if the connector was initialised with a maximum bpc of 12, + * the value of the max_bpc and max_requested_bpc properties out of + * reset are also set to 12, and output_bpc is set to 0 and will be + * filled at atomic_check time. + */ +static void drm_test_check_bpc_12_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test, 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12); + KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_value), + KUNIT_CASE(drm_test_check_bpc_8_value), + KUNIT_CASE(drm_test_check_bpc_10_value), + KUNIT_CASE(drm_test_check_bpc_12_value), { } }; diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 96b19a5954b4..fef7d53d34d4 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -208,6 +208,139 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) KUNIT_EXPECT_EQ(test, ret, 0); } +/* + * Test that the registration of a connector with an invalid maximum bpc + * count fails. + */ +static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 9); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of a connector with a null maximum bpc + * count fails. + */ +static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 0); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of a connector with a maximum bpc count of + * 8 succeeds, registers the max bpc property, but doesn't register the + * HDR output metadata one. + */ +static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_property *prop; + uint64_t val; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 8); + KUNIT_EXPECT_EQ(test, ret, 0); + + prop = connector->max_bpc_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); + + ret = drm_object_property_get_value(&connector->base, prop, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val, 8); + + prop = priv->drm.mode_config.hdr_output_metadata_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); +} + +/* + * Test that the registration of a connector with a maximum bpc count of + * 10 succeeds and registers the max bpc and HDR output metadata + * properties. + */ +static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_property *prop; + uint64_t val; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 10); + KUNIT_EXPECT_EQ(test, ret, 0); + + prop = connector->max_bpc_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); + + ret = drm_object_property_get_value(&connector->base, prop, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val, 10); + + prop = priv->drm.mode_config.hdr_output_metadata_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); +} + +/* + * Test that the registration of a connector with a maximum bpc count of + * 12 succeeds and registers the max bpc and HDR output metadata + * properties. + */ +static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_property *prop; + uint64_t val; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 12); + KUNIT_EXPECT_EQ(test, ret, 0); + + prop = connector->max_bpc_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); + + ret = drm_object_property_get_value(&connector->base, prop, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val, 12); + + prop = priv->drm.mode_config.hdr_output_metadata_property; + KUNIT_ASSERT_NOT_NULL(test, prop); + KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); +} + /* * Test that the registration of an HDMI connector with an HDMI * connector type succeeds. @@ -286,6 +419,11 @@ KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, static struct kunit_case drmm_connector_hdmi_init_tests[] = { KUNIT_CASE(drm_test_connector_hdmi_init_valid), + KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8), + KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10), + KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12), + KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid), + KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, drm_connector_hdmi_init_type_valid_gen_params), From patchwork Mon Feb 12 13:12:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199759 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2420711dyd; Mon, 12 Feb 2024 05:19:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IG0COaavZakM4iEoBcNHApTrZ2/clKSm213Z0rQ2HWyqetV+iXC3aADdpmFutpWL9eFlG8z X-Received: by 2002:a05:6214:21a9:b0:68c:c602:d3f9 with SMTP id t9-20020a05621421a900b0068cc602d3f9mr6349737qvc.10.1707743949075; Mon, 12 Feb 2024 05:19:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743949; cv=pass; d=google.com; s=arc-20160816; b=pkaQbqNhEmkdXEzDCyj92pRQ3mR3KqI0Sbq9SgVq6YIgD3R7bxmPWmNLNvoSH9h6pC hvGTNrkGUGhb6FxyWqiu1AsRuPPanB8F8JBrIXbCyLgv+AE5oXy0m2ut6txpky72t8KY 4lSCxCaLWPBOCQNs5I8vJiXi8cPBHCF2x1QvSVGBtaw0qlnZdHtgJGDBkh3c67MJzciL YIXezZLqrifktQgG8zleS5hS8Wip3gkADHaEaKBTYEIUpo9MEKK7YA1dS+rqkDFGlnX8 7DYV9DlukEB1gSbnnJhWGKGXGMQVFVMB9Xi4SKmC4PsLJqV0WO00oGA4daO6V/lFfhpE +BPA== 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=c0VMBlkSPOfmMHLMGZHnwTsyyu54NCb6G9+11i1UZRI=; fh=9cS6JYBSszMXNk7x6/9Kj0Hm7WOvQgc187vRybiOVaY=; b=Z4gIyiT8QyC5bXrLaYF/gDPMbvn+7I/fIp8NTKNgKvZ3edygbLOHRSCDL1HaZOdbPO ZQ3lBF9aak7KtVWhhFDpOMTLSzZScWGjgsZnzqVbSKHLJxcopEujBDMgkiFi3Bj7vRU1 dhr/bP/ygY+k5Frlpl4aT7YVvg7Y4jZgxF6aCMiMcj1sSWaJZ+slTIXSQ38QVRIjm2Ik wk2UP4a+jFjByiq1SbGPBsIzK+6DeBCAcTxeQoCmA8FWWi2BQSujY2VA7yXw5NSfr0Wp rRlVdKIHGnjW0tJCx4tQ17+cwexaB8RT6Ntqfp4dUvKC+ZPYEkc/yk4kgmi6TgGj2bCl 8Rqw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=uprTcVnD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61629-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61629-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXPk18fujocl8wjT0I1czDTfYHCa7ajkqU83yvV4YmdsjZG+F6l9DQ4P1OVpUXe2TshS6RyZCxxHNnIJRjOOdXDs0FRWw== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id iw12-20020a0562140f2c00b0068c6fed7aa3si364012qvb.161.2024.02.12.05.19.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:19:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61629-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=uprTcVnD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61629-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61629-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id C9B7E1C22880 for ; Mon, 12 Feb 2024 13:19:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 076023F9EE; Mon, 12 Feb 2024 13:14:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uprTcVnD" 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 6909D3EA8C; Mon, 12 Feb 2024 13:14:11 +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=1707743652; cv=none; b=eMnRcWin1ZqbnPPpXBkYbCF4gntFyuOlakWuFVLDIU2sjOCTdCxXzIofV8Ufx7LWj/dbXWjXErYXGD0y+Yzbjf/tCrqPNRjdB8/w0N8uf/FFqHRu2WBs3aofNkyVpRW/pMKAVF48b+FWwPMUWK8Qj9OX1e+v1H09a1W1RqV2DvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743652; c=relaxed/simple; bh=VrmfdTV5M4cWtFLk3sLzhgI+JyycwUnfsh8R4VXSNpo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h/PXdysIbsBw3bPsSZk+7piGeAf+mItYCo/EuneQsGROi/eMC5jUwmZwtYrya5HEQchP+TFnwBOlwUE67FLZnFjQkwe2shhtcAA5wuw5p+GtUywNKsRqyxFr5K10CBDtvYVj8N+aC6f8DSpXEoyJOzf9AzucQmxwgk6rqkEUG74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uprTcVnD; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D1E6C433F1; Mon, 12 Feb 2024 13:14:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743651; bh=VrmfdTV5M4cWtFLk3sLzhgI+JyycwUnfsh8R4VXSNpo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uprTcVnDUG5TdD4APlA+beMtoYZt8TfByALf+n14wG6W3s4br4U1vOvEo6RczfMqI BRl7K+ce2SUL+pNZrNnBxTJkx0Nlu9XB5xMqgQetglF1MmvzbUlaiyL+tX6sNtoeb1 PyaSawrEEOfKlEdz41KGnRb2IOhS0+QQ7uYL7ukmxmE7SIjMACk9hT/KhRTcRLPXXg ni/YnvKdCMoZssp6YUnTmkICwBv9CMnJraYIkCTvtaC/FMtqrbBtvfYUTAtQ7VlqX9 3J+olGuispeg3VDgA9AR2XaSGUkPsLvhrtiebOYV58YQdWkeIOe4jNY2fVEUjQjKyg h6KTEPksxG17Q== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:58 +0100 Subject: [PATCH v6 15/36] drm/connector: hdmi: Add support for output format Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-15-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=15675; i=mripard@kernel.org; h=from:subject:message-id; bh=VrmfdTV5M4cWtFLk3sLzhgI+JyycwUnfsh8R4VXSNpo=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJNPn/i26fvP1zv9xd5d+3rF6yatfdQ9X7BYuCowXc AoKjwta01HKwiDGxSArpsgSI2y+JO7UrNedbHzzYOawMoEMYeDiFICJLD7C8IebvZ3XqbBAprLc XS1m7pOmA2afbnoF+L/N/q7b9c/2cD3DP9tmtYOcd99N4tEzP5z81Xv9zqb5Gac+lH3NknSwmPR RghUA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699318963008349 X-GMAIL-MSGID: 1790699318963008349 Just like BPC, we'll add support for automatic selection of the output format for HDMI connectors. Let's add the needed defaults and fields for now. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 2 + drivers/gpu/drm/drm_atomic_state_helper.c | 3 +- drivers/gpu/drm/drm_connector.c | 31 ++++++++++++ .../gpu/drm/tests/drm_atomic_state_helper_test.c | 58 ++++++++++++++++------ drivers/gpu/drm/tests/drm_connector_test.c | 10 ++++ include/drm/drm_connector.h | 19 +++++++ 6 files changed, 108 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 5fcdab90c793..47fd2a7ca9e1 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1149,6 +1149,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n'); 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)); } 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 2025d053e54f..34aee5232974 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -706,7 +706,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb || - old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) { + old_state->hdmi.output_bpc != new_state->hdmi.output_bpc || + old_state->hdmi.output_format != new_state->hdmi.output_format) { struct drm_crtc *crtc = new_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index ca39fd027e20..b895bea667f7 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @funcs: callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter + * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats * @max_bpc: Maximum bits per char the HDMI connector supports * * Initialises a preallocated HDMI connector. Connectors can be @@ -477,6 +478,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc, + unsigned long supported_formats, unsigned int max_bpc) { int ret; @@ -485,6 +487,9 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; + if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB))) + return -EINVAL; + if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) return -EINVAL; @@ -492,6 +497,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (ret) return ret; + connector->hdmi.supported_formats = supported_formats; + /* * drm_connector_attach_max_bpc_property() requires the * connector to have a state. @@ -1224,6 +1231,30 @@ drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_ } EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name); +static const char * const output_format_str[] = { + [HDMI_COLORSPACE_RGB] = "RGB", + [HDMI_COLORSPACE_YUV420] = "YUV 4:2:0", + [HDMI_COLORSPACE_YUV422] = "YUV 4:2:2", + [HDMI_COLORSPACE_YUV444] = "YUV 4:4:4", +}; + +/* + * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format + * @fmt: Output format to compute name of + * + * Returns: the name of the output format, or NULL if the type is not + * valid. + */ +const char * +drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt) +{ + if (fmt >= ARRAY_SIZE(output_format_str)) + return NULL; + + return output_format_str[fmt]; +} +EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name); + /** * DOC: standard connector properties * 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 a1b0e6914cf8..a5cba3e63f99 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -147,6 +147,7 @@ static const struct drm_connector_funcs dummy_connector_funcs = { static struct drm_atomic_helper_connector_hdmi_priv * drm_atomic_helper_connector_hdmi_init(struct kunit *test, + unsigned int formats, unsigned int max_bpc) { struct drm_atomic_helper_connector_hdmi_priv *priv; @@ -190,6 +191,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, &dummy_connector_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, + formats, max_bpc); KUNIT_ASSERT_EQ(test, ret, 0); @@ -225,7 +227,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -286,7 +290,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -347,7 +353,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -401,7 +409,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -454,7 +464,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -510,7 +522,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -565,7 +579,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -621,7 +637,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -678,7 +696,9 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -745,7 +765,9 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -820,7 +842,9 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -840,7 +864,9 @@ static void drm_test_check_bpc_8_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -862,7 +888,9 @@ static void drm_test_check_bpc_10_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -884,7 +912,9 @@ static void drm_test_check_bpc_12_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 12); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index fef7d53d34d4..9c5ce7e81d01 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -187,6 +187,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -204,6 +205,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -221,6 +223,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 9); KUNIT_EXPECT_LT(test, ret, 0); } @@ -238,6 +241,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 0); KUNIT_EXPECT_LT(test, ret, 0); } @@ -259,6 +263,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); @@ -292,6 +297,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 10); KUNIT_EXPECT_EQ(test, ret, 0); @@ -325,6 +331,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 12); KUNIT_EXPECT_EQ(test, ret, 0); @@ -355,6 +362,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) &dummy_funcs, connector_type, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -387,6 +395,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) &dummy_funcs, connector_type, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_LT(test, ret, 0); } @@ -590,6 +599,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 1b1b6aed04ee..74db5ce47e01 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -391,6 +391,8 @@ enum drm_hdmi_broadcast_rgb { const char * drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb); +const char * +drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt); /** * struct drm_monitor_range_info - Panel's Monitor range in EDID for @@ -1077,6 +1079,11 @@ struct drm_connector_state { * @output_bpc: Bits per color channel to output. */ unsigned int output_bpc; + + /** + * @output_format: Pixel format to output in. + */ + enum hdmi_colorspace output_format; } hdmi; }; @@ -1944,6 +1951,17 @@ struct drm_connector { /** @hdr_sink_metadata: HDR Metadata Information read from sink */ struct hdr_sink_metadata hdr_sink_metadata; + + /** + * @hdmi: HDMI-related variable and properties. + */ + struct { + /** + * @supported_formats: Bitmask of @hdmi_colorspace + * supported by the controller. + */ + unsigned long supported_formats; + } hdmi; }; #define obj_to_connector(x) container_of(x, struct drm_connector, base) @@ -1967,6 +1985,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc, + unsigned long supported_formats, unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); From patchwork Mon Feb 12 13:12:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199758 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2420715dyd; Mon, 12 Feb 2024 05:19:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IGYkaXWUeKCdM7iXiSMFlAafST/Kf8ff4s7oQCxnO0HPJoZXHCrCVtpkU3yneJjhJ0Of2px X-Received: by 2002:a05:6a21:1789:b0:19f:c0d3:43d8 with SMTP id nx9-20020a056a21178900b0019fc0d343d8mr2104998pzb.11.1707743949256; Mon, 12 Feb 2024 05:19:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707743949; cv=pass; d=google.com; s=arc-20160816; b=zgGGwoVar+CbsUXtklWRjmvLP/qiGc0BHAHgOQ42j4n9qgwevvjZXKy4Zki1jgSnUg y4q+GoGHc10zSlpcWdMMjjOla3cI9Mdm6Xsl0/SdqP4i7iR9ExoXlKzIjEZXRTtNhbkk 7cL785eryZN1h8/nUlY4EtU3t2s3aCjcBliaUhg9YA9313XNvfcBzNyZtzUFEibYt9Ik xzAc4/tO+ykJixceru/5xXmqt3omS0w1UyG6imzBoAy/d6xmodMf/5pnR1/47x2kBAXx g3sJkuyzbHsiE3ht3fl//AGunv4Cn3wf7d5ARqmBCHQfPReLmIxjEpVglM1JwoqRgYLm i3qw== 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=29OHmR7rJlcZ6xJfRikNnYFtl8Oa6/u/uDVm2p6QEe4=; fh=EraIltnAIBOubH0JRY8AMR/LUnAQzXv4sREX6SXzTS8=; b=qMpAS0Po8On9rXTqR62QYlehYevZgEdz1Ru56iLGrlVMLg2aXlCk3BMFWno6pvGvqi 22DdWCpYIwtF9xrQ0XhGoAGDT+84dt7aUAla66zwmVMkzNdjmjsRYlPdHE5N5wv3qPmZ 4AnIRPWrnqqm36L3/ZjLy+j+UZq91Z516NUS9sgQmGLuMadb6hvRiHgN4EaBCIz4xt8r usV/aYDPVgqDrOlxzC4lb4bQxohs+6UZnWOfEGRqz61oQzjWovjE6YGdxJ/WdcrJtk+O /FhTSR6fJzYrMxUrrOk4wI9fcuMZDUUsE3lOF3WKHhU+1MBCnr1dzxXYB/ocYBHO/RKk BE/A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=nnYMWO6u; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61630-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61630-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWptzelpivyMuX6PFJbywywZnllgmmfaNBjcy9FDASZdkOw8XWpzadBZO2gXRLtI/D75uNoj+KkdkS/FH71Bbx5SRoKGQ== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id x37-20020a056a0018a500b006e04369998fsi5055874pfh.15.2024.02.12.05.19.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:19:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61630-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=nnYMWO6u; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61630-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61630-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 0605E28144A for ; Mon, 12 Feb 2024 13:19:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1BDC33F9EF; Mon, 12 Feb 2024 13:14:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nnYMWO6u" 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 264583F8C3; Mon, 12 Feb 2024 13:14:13 +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=1707743654; cv=none; b=K2SAse1d8hhrQVs+hbx6P2+KWa6kPwVc0EQD1sE01XVfkTXI/yrFN0mOWz1Jg6BGmPLv0yz9enEaaUZ0XvwBvF0/mplVZhWts8hAYOi9ETaJKohExyf5T1pVRpKVSrIUO44+MuC1CRDKn8iWuZplLGXWTyPkujN7c522TDPDzlc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743654; c=relaxed/simple; bh=hVvd4FnVrnc0ueFHR5k8VbMr8WUIf39Lt6E/xNOlkQA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qFON4Brin5T9FpMk38rTwwVTq+lOY0lQCtAuv/Ad2sQfgdJLBXKHhmCNNc5uPySPnXaFRtrYHmXctZXVnLXLOA4V0+y6l5jFf13BAGCyRST3DZnxI6lsOxy4LVpfOUszCUPS4fH5eaj5wZw6l0hUaLMbtHzXWgiQ2w+dkh3mtjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nnYMWO6u; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 511F0C433B1; Mon, 12 Feb 2024 13:14:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743653; bh=hVvd4FnVrnc0ueFHR5k8VbMr8WUIf39Lt6E/xNOlkQA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nnYMWO6uMryz6GAC5/40GnLMZ6rY49rA8EJBub3YBhEt40DtA6HD6cofH4S9bXciq DjsDi//2V/UDwFvGYklqLJIYCRW3Jljr3mouNccB56EGamos5Dbzqc+pGi/gIxUcx/ jGGXQyvdTqAJMkTbhepo1FDE5U6FPzY7FZUKifJUn5La+NDHPdMsLbZAyudgmmglNZ gCe9QiSqmPCaoxkTbNeZAQBpeClQr0TyW6IV2jR7HtjpiHWL80S/HsczOGP+QJ+wiX 5YrTUYMlOHaPTZSAoYosui6nY3M5dzirCsBY0PeOhhuZvDRDtWRtsaaUcZgs/8+b83 OQ1TL6/uQyEww== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:12:59 +0100 Subject: [PATCH v6 16/36] drm/tests: Add output formats tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-16-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=7427; i=mripard@kernel.org; h=from:subject:message-id; bh=hVvd4FnVrnc0ueFHR5k8VbMr8WUIf39Lt6E/xNOlkQA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJDNC2fp7UnK4ui+c1DrWdjlZgCU8wH1uBPPvXqYnk cs5LJ93lLAwiHExyIopssQImy+JOzXrdScb3zyYOaxMIEMYuDgFYCIRuxh+3OKQVOhfcFc7oVGz p70iS9JeZeeq18LvD1/VfqTpNH8WI8ND3w6/YO4Sucfyy3VXOLa2anR4373YIH3w+8aO4osvmbk A X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699318921437103 X-GMAIL-MSGID: 1790699318921437103 Now that we track the HDMI output format as part of the connector state, let's add a few tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 32 +++++++ drivers/gpu/drm/tests/drm_connector_test.c | 99 +++++++++++++++++++++- 2 files changed, 130 insertions(+), 1 deletion(-) 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 a5cba3e63f99..4e2ec436987b 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -824,6 +824,15 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), + /* + * TODO: We should have tests to check that a change in the + * format triggers a CRTC mode change just like we do for the + * RGB Quantization and BPC. + * + * However, we don't have any way to control which format gets + * picked up aside from changing the BPC or mode which would + * already trigger a mode change. + */ { } }; @@ -924,11 +933,34 @@ static void drm_test_check_bpc_12_value(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); } +/* + * Test that the value of the output format property out of reset is set + * to RGB, even if the driver supports more than that. + */ +static void drm_test_check_format_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_value), KUNIT_CASE(drm_test_check_bpc_8_value), KUNIT_CASE(drm_test_check_bpc_10_value), KUNIT_CASE(drm_test_check_bpc_12_value), + KUNIT_CASE(drm_test_check_format_value), { } }; diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 9c5ce7e81d01..fa6fe8084107 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -348,6 +348,42 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); } +/* + * Test that the registration of an HDMI connector with no supported + * format fails. + */ +static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + 0, + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of an HDMI connector not listing RGB as a + * supported format fails. + */ +static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + &dummy_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_YUV422), + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + /* * Test that the registration of an HDMI connector with an HDMI * connector type succeeds. @@ -433,6 +469,8 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = { KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12), KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid), KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), + KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), + KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, drm_connector_hdmi_init_type_valid_gen_params), @@ -567,6 +605,64 @@ static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, }; +struct drm_hdmi_connector_get_output_format_name_test { + unsigned int kind; + const char *expected_name; +}; + +#define OUTPUT_FORMAT_TEST(_kind, _name) \ + { \ + .kind = _kind, \ + .expected_name = _name, \ + } + +static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test) +{ + const struct drm_hdmi_connector_get_output_format_name_test *params = + test->param_value; + + KUNIT_EXPECT_STREQ(test, + drm_hdmi_connector_get_output_format_name(params->kind), + params->expected_name); +} + +static const +struct drm_hdmi_connector_get_output_format_name_test +drm_hdmi_connector_get_output_format_name_valid_tests[] = { + OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"), + OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"), + OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"), + OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"), +}; + +static void +drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t, + char *desc) +{ + sprintf(desc, "%s", t->expected_name); +} + +KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid, + drm_hdmi_connector_get_output_format_name_valid_tests, + drm_hdmi_connector_get_output_format_name_valid_desc); + +static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test) +{ + KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4)); +}; + +static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = { + KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name, + drm_hdmi_connector_get_output_format_name_valid_gen_params), + KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid), + { } +}; + +static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = { + .name = "drm_hdmi_connector_get_output_format_name", + .test_cases = drm_hdmi_connector_get_output_format_name_tests, +}; + static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) { struct drm_connector_init_priv *priv = test->priv; @@ -628,7 +724,8 @@ kunit_test_suites( &drmm_connector_init_test_suite, &drm_connector_attach_broadcast_rgb_property_test_suite, &drm_get_tv_mode_from_name_test_suite, - &drm_hdmi_connector_get_broadcast_rgb_name_test_suite + &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, + &drm_hdmi_connector_get_output_format_name_test_suite ); MODULE_AUTHOR("Maxime Ripard "); From patchwork Mon Feb 12 13:13:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199787 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2428553dyd; Mon, 12 Feb 2024 05:32:55 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU1eIllD/Wi+xj41PTPaSlKedj9dNU1E1c3Ey13j2K+fE5RbNB2dUOD0cAeZ8k7qAePW/NTUFWX2wS8b2KYqM/ysy43cw== X-Google-Smtp-Source: AGHT+IE/MrZewi3K/+R6dImQQ44GxXOmvFZIzjVEO80+D8SIEWM9HIeoCAX95RdPw3Oz/qmIH8g/ X-Received: by 2002:a05:6a20:e198:b0:19c:b457:fb8 with SMTP id ks24-20020a056a20e19800b0019cb4570fb8mr8024922pzb.51.1707744775670; Mon, 12 Feb 2024 05:32:55 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744775; cv=pass; d=google.com; s=arc-20160816; b=Xm5lQ2g7AG5RmJbVasQ9G2tZVJ6/c5ivK7IXwoz8FOM0it7DIJE+44y3o3SVY9urpW VCoF0xsc8FkjHyW+Id4dctvmY6oxbblo4s80w7DqpfOP1SGgrE/RwinDjqk/NFoNLffJ rMew5b8e12rCEWE+V73jlfGoq8gQNjHFev38VvcsSOFMD1EFofc/GFgO8j7cTagDJ3eo phBVXK5pk9axkcLkQoAA89RaPeiimvWShMZz+26gL6KopyvyL+dCoxb0dMwoqVeJlkX4 mSuUM62tWYm5iljqlEbwb/9/6EEvCp1JilMTB5pM8enLHlHV4XTds8UnvdpaF2sBl8us qwzg== 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=+6DVY3JtzWU8GyzyAFnNghrdY5u1oHmETT7zvi/Zn70=; fh=nIqkONzN568JupYUNRGvrA5/OLYA4ddG4IGlb88oskg=; b=NZJaCEE9HJbhiyzWpfi5vejs2YREX8gLxTY89EKOijfZiYLZj91+8oVohrxDd4QmmH J1ANewf7091sqT3zHKe41dFCZ0T9RESdahZXhtyRKcCLbe9PTqnjVQvji9z2hTKOEHcw dPkaa6Jx7jMbG5QVOR4oi5j9VqMXKavIYO4Q9Bh3UI8vllYzVDKN5bzxy/N7Dqmh15Uf VieLjMFltqFES5uC6AJJ9b1L0IEbQRJ5wREY2Ldq63wLnTomp4F2309j0pXzOUwSVENm O+Mg2m6t935f7dmLrDtHhMJr8CXjZY9uJf7b8VlNYWtjqCIEq0j5vTwNxFF7Fn1Hej2F tZlg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Q1MN1sec; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61631-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61631-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVWys8TcXnbvP0E+y/o+17m4ldbr/1OK5m6TRoOVSxgg4lt75KrWXU+jIMiUqDd+WxII3ZgDVkKQCKhKqZf5XnzJfQogg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id l197-20020a633ece000000b005dc4e7d879csi266350pga.66.2024.02.12.05.32.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:32:55 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61631-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=Q1MN1sec; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61631-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61631-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 C95A6280F89 for ; Mon, 12 Feb 2024 13:19:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CE55C3B191; Mon, 12 Feb 2024 13:14:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q1MN1sec" 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 80FB03F9C4; Mon, 12 Feb 2024 13:14:16 +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=1707743656; cv=none; b=fJjvRpcZVq1Bh+boWFpFwBhdFyOUHuJ9DjpJ7rmgoh+22A083MMKXvWcFqC6t6WtOKKgnOHaVzQuBaJOCdkc46vNkDRIwg802yLFcO1C0H8fPwPUFPkD1JPjwTcGRAv25NFVoaOKXYWhOy0/w8Rtv1Tp7U9KUpBJ8hLz5jcqZy0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743656; c=relaxed/simple; bh=s5W/xSAdD1+rl96fJKi18NgBJWzOCTMahxkAxJFesPk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kHoF+lrmWsO9WTttoBWXRx98X3ZYjmY/sgOh9a5A77UzDCvNkkgqBwIgdh43J88ZYevbx2OeEG+7pR2soVC6JxRG0elhVuSplDb+zprMyYm3Rq7u45SunqE5/HqCJsrF3BtvscX91Wp1Yu7nI4ifxQJR0PfcJe68NgcIUM8LNHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q1MN1sec; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05D21C43390; Mon, 12 Feb 2024 13:14:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743656; bh=s5W/xSAdD1+rl96fJKi18NgBJWzOCTMahxkAxJFesPk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Q1MN1secIYCFbTnoKCzZKJf5MRpdSH4v4ih46cyrxLB1pWAIJ66jKTuM9mk6XokKc bRCxg5Ri5iGvZ86KzDmfr1RGwT6xGztKaR+PYJzWeOqcfaD6wU/oNLk/RZNSyiydqE c7qZrw3SDCX75q6mGib4SYStbsgzyMQzaVCRAX8RGLmXra3sAWftruAO1F9uZWCSou GxaNK2r+tpsKCW5TOV1EjAfC+0tOWBe9u1cmB7LKKpP+iEMeJdfHDuarfBFehruVDN F5lhOtpo9M+YO1R5hyxiu87H0Qu7XI9lMOykzp3m8RryVD0NRL4BzEMmJbocUpTNsJ ryUiW8GefFtVg== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:00 +0100 Subject: [PATCH v6 17/36] drm/connector: hdmi: Add HDMI compute clock helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-17-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4017; i=mripard@kernel.org; h=from:subject:message-id; bh=s5W/xSAdD1+rl96fJKi18NgBJWzOCTMahxkAxJFesPk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJDMKZI1Pz/wlzNsgN231LvETAWeq1XNt/5etaroy6 +/NYufIjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEyER4/hn/mGgwdXN2sE3rpv I2b/8mZ+D2PB5vb33g+YtvQq9LCHiTD8lbt97uBup1UeFzv/tLb0Vch/79pxRmGFshOP+dbjl6O e8AMA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700185382083850 X-GMAIL-MSGID: 1790700185382083850 A lot of HDMI drivers have some variation of the formula to calculate the TMDS character rate from a mode, but few of them actually take all parameters into account. Let's create a helper to provide that rate taking all parameters into account. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 71 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 5 +++ 2 files changed, 76 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index b895bea667f7..332477c6a987 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2982,6 +2982,77 @@ void drm_connector_update_privacy_screen(const struct drm_connector_state *conne } EXPORT_SYMBOL(drm_connector_update_privacy_screen); +/** + * drm_connector_hdmi_compute_mode_clock() - Computes the TMDS Character Rate + * @mode: Display mode to compute the clock for + * @bpc: Bits per character + * @fmt: Output Pixel Format used + * + * Returns the TMDS Character Rate for a given mode, bpc count and output format. + * + * RETURNS: + * The TMDS Character Rate, in Hertz, or 0 on error. + */ +unsigned long long +drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc, + enum hdmi_colorspace fmt) +{ + unsigned long long clock = mode->clock * 1000ULL; + unsigned int vic = drm_match_cea_mode(mode); + + /* + * CTA-861-G Spec, section 5.4 - Color Coding and Quantization + * mandates that VIC 1 always uses 8 bpc. + */ + if (vic == 1 && bpc != 8) + return 0; + + /* + * HDMI 2.0 Spec, section 7.1 - YCbCr 4:2:0 Pixel Encoding + * specifies that YUV420 encoding is only available for those + * VICs. + */ + if (fmt == HDMI_COLORSPACE_YUV420 && + !(vic == 96 || vic == 97 || vic == 101 || + vic == 102 || vic == 106 || vic == 107)) + return 0; + + if (fmt == HDMI_COLORSPACE_YUV422) { + /* + * HDMI 1.4b Spec, section 6.2.3 - Pixel Encoding Requirements + * specifies that YUV422 is 36-bit only. + */ + if (bpc != 12) + return 0; + + /* + * HDMI 1.0 Spec, section 6.5 - Pixel Encoding + * specifies that YUV422 requires two 12-bits components per + * pixel clock, which is equivalent in our calculation to three + * 8-bits components + */ + bpc = 8; + } + + /* + * HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding + * specifies that YUV420 encoding is carried at a TMDS Character Rate + * equal to half the pixel clock rate. + */ + if (fmt == HDMI_COLORSPACE_YUV420) + clock = clock / 2; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + clock = clock * 2; + + clock = clock * bpc; + do_div(clock, 8); + + return clock; +} +EXPORT_SYMBOL(drm_connector_hdmi_compute_mode_clock); + int drm_connector_set_obj_prop(struct drm_mode_object *obj, struct drm_property *property, uint64_t value) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 74db5ce47e01..0cc5a8732664 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -38,6 +38,7 @@ struct drm_connector_helper_funcs; struct drm_modeset_acquire_ctx; struct drm_device; struct drm_crtc; +struct drm_display_mode; struct drm_encoder; struct drm_panel; struct drm_property; @@ -2136,6 +2137,10 @@ void drm_connector_attach_privacy_screen_properties(struct drm_connector *conn); void drm_connector_attach_privacy_screen_provider( struct drm_connector *connector, struct drm_privacy_screen *priv); void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state); +unsigned long long +drm_connector_hdmi_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc, + enum hdmi_colorspace fmt); /** * struct drm_tile_group - Tile group metadata From patchwork Mon Feb 12 13:13: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: 199761 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2421578dyd; Mon, 12 Feb 2024 05:20:33 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVracLsGUpsyRkbwqpaGXoeFBaUzUapao+0nbyzJ1KkrOsdztrAbFMn4IhcuFVsv66p0gKMUycFomINmo2aOy9/D0TjKQ== X-Google-Smtp-Source: AGHT+IEyivmiGL3ydxXV1h0YESgTPKZ1aJEBFgYLwf/d/6AVvWa0cU9Fz8JxGeFRCdOgdKXYLf8c X-Received: by 2002:a17:906:e0c5:b0:a3c:d108:2168 with SMTP id gl5-20020a170906e0c500b00a3cd1082168mr925114ejb.38.1707744033701; Mon, 12 Feb 2024 05:20:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744033; cv=pass; d=google.com; s=arc-20160816; b=R5RwVd3J4HcZtaxB1F8EPJbaHSBUb0Ot5ABR++PteidD1/qntvI2U7hFFL0B2Ff+d4 6JaRRQmN6JvZ9L7r0J3NGDyYa2spsAXdS6L333dgRHfKxOsKAI/ZkZROeiaGwwslntPa 05LaMCEZHMW3BNOSfIoxYbzqY1fdquDiWrThuTCrRlWcH8S8yHUnHG+VOCew2OjyVg66 anSIyB9c866lGV5IdOtWuxgZ1dhNOTNjI2RWJHtAbvgg2S/YEwK7BoMq7Jtn7fwOhYaC Djq4Ja6w9th7dX80shAJxAgRxxS56et06BGXfcIWGyZDuBY5nYRIUuLfIHwR4pTjYZhv Q1Rg== 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=0TKWiaf99XIJCWjdGNtBm2jlEj2ret6UoMJGzzABsXk=; fh=lDEFAxiGOf7HWYxseoE4JlG5kxYxNhMLaA0AF2DW+0A=; b=L5hMzfn/Otwxcda3VWhJmREiVk8ezViuRbZeEgh6NcB9xRH44dOTWSUSJyWLXGem1S xoAIqkO1uhMzaq7Zwyhvb7ENisTWvyKhLLZrJhIY79TXYdqqVFiEV772+x8QbQi2ek8o AghAoduP03nB/5OssomGznCE+o90MVCf26qkD74kGqH0drNb7W/AqIl5Zlg+qNHH0sWq xVWvlcUmZyTZnqs9uWx02l+izVe6AtY75Ax1YZr7GB1ugqWb9aGMCpRAYScgWDQieig0 nXmpvUPuZjg3sHkYelSpclQ/8AGY5ELRyvzONCkDLLXaO+Jzq9KUfFrnZMCIvP9HyOuG 8BKg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bIlM9cqT; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61633-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61633-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCU2q5mMrVTKPNSD/5914xlWnipeTaq2EbElO5Fb3LKnlX1buD2QmeZ5zszx/1Vv3xsDqOqMi7PbADXVyLNQPufbxpD3+g== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id p18-20020a1709060e9200b00a3498026100si182627ejf.546.2024.02.12.05.20.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:20:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61633-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bIlM9cqT; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61633-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61633-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 276FF1F22787 for ; Mon, 12 Feb 2024 13:20:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2B51B3FB3B; Mon, 12 Feb 2024 13:14:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bIlM9cqT" 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 E4A833FB20; Mon, 12 Feb 2024 13:14:19 +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=1707743660; cv=none; b=sjBenidGtFsq9PPYcJnkRf+SJncqhATwX+qxbW68WOlQRjzxqi8t0T0/Oatv5OSANiWH92VHvqbgovvGHKA2i5UzpCvvHqSiJZoR4Ng31mZ97T37iqKvk9F6HsggpX+hhkf/juuLXF52Q0r9K9k+kQkM48gPv0fKuC66qBVSJCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743660; c=relaxed/simple; bh=ZZs3RiNqAbzKhZAn8FdhUoLV6Zsye/PNcQYJLT+nsKQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pfqyyTI4jpOuS1J7aNFuFm3YLCvlk5pbi2BwJgkVahBnZaPk3EgppB534VsqzLBveJHD4al+apeOogZsSdbkSty0ir9Om47VLDkPMg9BPdQvwYpG8E97XsasMSIB8zL7Bp9XmgtkRmh0ZVt3Q2JaKJ7tSav3sFChp5Z6dZtYS3g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bIlM9cqT; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id DB9D6C43394; Mon, 12 Feb 2024 13:14:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743659; bh=ZZs3RiNqAbzKhZAn8FdhUoLV6Zsye/PNcQYJLT+nsKQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bIlM9cqTfDiaeJYbu39rmV8IEb4XPHqACpMyfNfToH5Vp19LTwGiHoT+MjQHJ9cMs da7M86muyqLHIz75QX+uC1RLkOM+WRnH0p4cK/V5c1aKsTGEapF69g/MSEpDjdKRcY FGEhj83nPRb7NgR/y0VY/o9jyvjTGWPIRKEVHX1D8HlPsL9ufvOw5NkNVVCgriMfgz q6mdSYKtlCF2l6adRm/CR7jHrqljshYhODZv4T4DbX+I7UElFRU0keeSaX1c+eUnQC c+oBgmI0sjwyIydgsM2+kdnOe9Ryy4QfeI/xgO94zgCJdnr+cOzdkfZ3/FDERjkaJX 4CrmqtmJMsbCA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:01 +0100 Subject: [PATCH v6 18/36] drm/tests: Add HDMI TDMS character rate tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-18-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=13298; i=mripard@kernel.org; h=from:subject:message-id; bh=ZZs3RiNqAbzKhZAn8FdhUoLV6Zsye/PNcQYJLT+nsKQ=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJDNl87Lmrs/4s+WcNQODycl3mn+yv4lzufNfsWkVq fPUW7S6o5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABORaWNkWKO3YWn4yykvdsRM jHR4rdzXsulE+Dwt3TqOGU92P3p0NZuR4W/NocMTkz9lBS6R8boUeDdmzvu1e+4/3yzfePj/MpH MVXwA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699407845065235 X-GMAIL-MSGID: 1790699407845065235 The previous patch added an helper to compute the TMDS character rate on an HDMI connector. Let's add a few tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_connector_test.c | 323 +++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index fa6fe8084107..0a838924a546 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include @@ -719,10 +721,331 @@ static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite .test_cases = drm_connector_attach_broadcast_rgb_property_tests, }; +/* + * Test that for a given mode, with 8bpc and an RGB output the TMDS + * character rate is equal to the mode pixel clock. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); +} + +/* + * Test that for a given mode, with 10bpc and an RGB output the TMDS + * character rate is equal to 1.25 times the mode pixel clock. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); +} + +/* + * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS + * character rate computation fails. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, rate, 0); +} + +/* + * Test that for a given mode, with 12bpc and an RGB output the TMDS + * character rate is equal to 1.5 times the mode pixel clock. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); +} + +/* + * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS + * character rate computation fails. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, rate, 0); +} + +/* + * Test that for a mode with the pixel repetition flag, the TMDS + * character rate is indeed double the mode pixel clock. + */ +static void drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + unsigned long long rate; + struct drm_device *drm = &priv->drm; + + mode = drm_display_mode_from_cea_vic(drm, 6); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); +} + +/* + * Test that the TMDS character rate computation for the VIC modes + * explicitly listed in the spec as supporting YUV420 succeed and return + * half the mode pixel clock. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned long long rate; + unsigned int vic = *(unsigned int *)test->param_value; + + mode = drm_display_mode_from_cea_vic(drm, vic); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); +} + +static const unsigned int drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { + 96, 97, 101, 102, 106, 107, +}; + +static void drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) +{ + sprintf(desc, "VIC %u", *vic); +} + +KUNIT_ARRAY_PARAM(drm_connector_hdmi_compute_mode_clock_yuv420_valid, + drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests, + drm_connector_hdmi_compute_mode_clock_yuv420_vic_desc); + +/* + * Test that trying to compute the TMDS char rate with the YUV420 format + * for a mode that doesn't support the YUV420 encoding returns an error. + * + * TODO: We should probably test this with all the VIC but the + * explicitly supported ones. Since the list of VIC is quite long and + * not linear, the best way to support it at the moment would be to + * create a custom gen_params function that would only return valid + * VICs. At the moment, that function expects to get a pointer back + * however, and compilers don't really like casting between integer and + * pointers. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, 42); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); + KUNIT_EXPECT_EQ(test, rate, 0); +} + +/* + * Test that for a given mode listed supporting it and an YUV420 output + * with 10bpc, the TMDS character rate is equal to 0.625 times the mode + * pixel clock. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned int vic = + drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, vic); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); + KUNIT_ASSERT_GT(test, rate, 0); + + KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); +} + +/* + * Test that for a given mode listed supporting it and an YUV420 output + * with 12bpc, the TMDS character rate is equal to 0.75 times the mode + * pixel clock. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned int vic = + drm_connector_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, vic); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); + KUNIT_ASSERT_GT(test, rate, 0); + + KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); +} + +/* + * Test that for a given mode, the computation of the TMDS character + * rate with 8bpc and a YUV422 output fails. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); + KUNIT_EXPECT_EQ(test, rate, 0); +} + +/* + * Test that for a given mode, the computation of the TMDS character + * rate with 10bpc and a YUV422 output fails. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); + KUNIT_EXPECT_EQ(test, rate, 0); +} + +/* + * Test that for a given mode, the computation of the TMDS character + * rate with 12bpc and a YUV422 output succeeds and returns a rate equal + * to the mode pixel clock. + */ +static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_display_mode *mode; + struct drm_device *drm = &priv->drm; + unsigned long long rate; + + mode = drm_display_mode_from_cea_vic(drm, 16); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); + KUNIT_ASSERT_GT(test, rate, 0); + KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); +} + +static struct kunit_case drm_connector_hdmi_compute_mode_clock_tests[] = { + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb), + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc), + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_10bpc_vic_1), + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc), + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_12bpc_vic_1), + KUNIT_CASE(drm_test_drm_connector_hdmi_compute_mode_clock_rgb_double), + KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, + drm_connector_hdmi_compute_mode_clock_yuv420_valid_gen_params), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_invalid), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), + { } +}; + +static struct kunit_suite drm_connector_hdmi_compute_mode_clock_test_suite = { + .name = "drm_test_connector_hdmi_compute_mode_clock", + .init = drm_test_connector_init, + .test_cases = drm_connector_hdmi_compute_mode_clock_tests, +}; + kunit_test_suites( &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, &drm_connector_attach_broadcast_rgb_property_test_suite, + &drm_connector_hdmi_compute_mode_clock_test_suite, &drm_get_tv_mode_from_name_test_suite, &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, &drm_hdmi_connector_get_output_format_name_test_suite From patchwork Mon Feb 12 13:13:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199762 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2421737dyd; Mon, 12 Feb 2024 05:20:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IF+1K0y7pTb47IiWsT5sEcnL7ej0ZSIzMHXAwqMZj+5lYC1pw0mVUF0BsjstQ/YVIkVU8f1 X-Received: by 2002:a17:906:3913:b0:a38:2f96:afba with SMTP id f19-20020a170906391300b00a382f96afbamr4485888eje.74.1707744051731; Mon, 12 Feb 2024 05:20:51 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744051; cv=pass; d=google.com; s=arc-20160816; b=mBYeIieftAaBxiVgDq9kp0md5L1jJws7JhxZSKpVRhvqiu+QrVzfMm87um/vwKa8oX SxtdqDca3yAp3q+/nrb7pciOmhzknuvmdVKIiok6nf9BjnFWXIBTqIApUKKkwkHYSAtH gGe1B4DvZPOQRBoL2CS+l2nbFZ31ZB2D1Ix5gQOWBemH6ZiZrxvkEqL0TFV88mTjDZCb X6MlgwJpQDDF6AbzX2VD14JhfPfhPJQvhtFUtIRvmnY1ZINdmlNun3VudHotbuFYaI+t LdOr2nKiASJxMUyL+W66OU1cUVRVXqbS1inHjrVrDc8uwjkwaDkwqXyPaaXvHJmaM+At S3zQ== 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=YcSgaoeRloBUK1oWLscJaLc/ekzeroUhMyzXNdoGzBw=; fh=6IwOQlFAVXoTuxmM3CIQ6qaVhT0gJ7COrOZtwKNZMss=; b=D8VYKi0a7zCsh0rX2n12DiAGqs/OPy9+IaCwCdg6Ky+fq7M+xFJSoq/vWItwl7wwNf evoB3lKX/CumwnKCS0TU7hUOKU8iOmx4S2aZ7WO9gYOPdjgIbW0td3+1Bsh36NIquIQE 36msIabE9B/+5w9c/0LjPzEmMDE6kJPjJBOiq2VuE5EZn7+McEYw7I8uWJp9zn8mTBtF 584rI2gXQGMYWs8pHoNd6Pu4cc8ZOHM6hO56xcFiKN16K+PgLkoqXuexG5VpsRo51Brw wGfp/DB5GLcO4V5m4DwcSZDSzDiVQr/mZ3TMr8BX/T/R+90wX5uLjXgMDqeSS/wZ/8jp CgGA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=GPXqsnvn; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61635-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61635-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXwEymU+3tOWCZ92HD2MIqTKzzqcCyFxcW2KMgUhNIzsbUeEub3N0x1d4/+wqZLErXzjxUGdc/ovSv/Sfryrh7pIdQsvw== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id v14-20020a17090606ce00b00a38625d3299si195213ejb.137.2024.02.12.05.20.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:20:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61635-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=GPXqsnvn; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61635-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61635-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 291DD1F21C9E for ; Mon, 12 Feb 2024 13:20:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4AF584501D; Mon, 12 Feb 2024 13:14:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GPXqsnvn" 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 9BBB23FB3C; Mon, 12 Feb 2024 13:14:22 +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=1707743662; cv=none; b=ZlfvKHeU+/yqKNvwm86tPt8GuZD058Cy7d5MekLD5WmI8MGLtkR6+1lSZMLXzvy26FlXRW5P1h8gyHY/8Sw/pBSwgV2vEvdQRsmSKYrIWa+JpihPf9viQu3hxsADykhqRvEpNU1EEB9Nt/gfyYDI2VGfL/+LJWp7dpg6UEmjjXk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743662; c=relaxed/simple; bh=13Kiyh9YrUcP7PoXE6E5FXG2OWvL1W7X3RX607K+/pU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rLGtmQgRDRs2vQedqAz536JJRjMaabu5KT0bDDk4BlbP5ejEknoJL8sAvvQgCbOgubQsV816CB17dfKEWOjzM+5vpe23WPGwDHAN+NYFfJnTQWQesRLjrSRyVAjHinmdC3z6MODTAl5Nv+pMlGh5IEyFcN61o98DNq0Lx1ya57E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GPXqsnvn; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA5F1C43399; Mon, 12 Feb 2024 13:14:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743662; bh=13Kiyh9YrUcP7PoXE6E5FXG2OWvL1W7X3RX607K+/pU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GPXqsnvnZfckQKbhN6tjLLG4VhZCfV40sEdnaMpvKFG7KAzdUGaJpOrSAStqMpj4c kVnHH9AhkaP3KUrNMfg1Ro1cagNOYYtKmTesUFBWSQi0k/+4VIU3snMKCSvtpHmpZw 9X6JvyptZ9YlsvVK6sAbmh9rRAu6Z/BsMCA5cMOSFk0lv1ZahGm1AlFwVE5MW4TQTr a9fnFVzJyYW61a2tPY1/ZJlDDi5tziPzB6TL/v+mYhqK7xXN1D7kirIPHXldC+qSD2 TWVjgWSs3XrFsEgFCJqBcO8jVQ6Hnkb2eaJ+V+PgwGaVGRMJJsEwnxaOnASN1fKHDa 0g4DSTCod2ZXQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:02 +0100 Subject: [PATCH v6 19/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: <20240212-kms-hdmi-connector-state-v6-19-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4873; i=mripard@kernel.org; h=from:subject:message-id; bh=13Kiyh9YrUcP7PoXE6E5FXG2OWvL1W7X3RX607K+/pU=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJLM8ZeL46poKZy+7dd7xSb2cStCSyqeL5+XuVTDWn XPFoMe7o5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABNZtIeRYWvF39DUWdN+ZLgp 7MgQWVe02kG6r0X63bTZAbWdHK1MSxn+JyYHK8WvcOcOZtqh8b+COdF4ws/wAnH9/L13PH/K53t wAwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699426768193411 X-GMAIL-MSGID: 1790699426768193411 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 | 44 ++++++++++++++++++++++ .../gpu/drm/tests/drm_atomic_state_helper_test.c | 3 ++ include/drm/drm_connector.h | 5 +++ 4 files changed, 53 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 47fd2a7ca9e1..ec6c6beda5c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1151,6 +1151,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 34aee5232974..ac77d47a0ce3 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -683,6 +683,41 @@ static bool hdmi_is_full_range(const struct drm_connector *connector, return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false; } +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 @@ -702,9 +737,18 @@ 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; new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); + 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.broadcast_rgb != new_state->hdmi.broadcast_rgb || 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 4e2ec436987b..d3f35600a9f9 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 0cc5a8732664..59016d9c17f5 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1085,6 +1085,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; }; From patchwork Mon Feb 12 13:13:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199763 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2422498dyd; Mon, 12 Feb 2024 05:22:19 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWLO0WQ6FDqGieWaUHbVWY1w9qaI6lzBtg/qHzSahvEDZmfbALy6mzHgfpHJwElHn5qWFsVUPzfa6g/0EaJr4oRwdZmeQ== X-Google-Smtp-Source: AGHT+IExuRi/vyDu8inGV1sRMdY5ffC3JFl+8r2O0B91iihlat3MFfBwqyd5y5gtsnBlOP1qMMNg X-Received: by 2002:a50:ee16:0:b0:560:c0da:43be with SMTP id g22-20020a50ee16000000b00560c0da43bemr3968302eds.11.1707744139571; Mon, 12 Feb 2024 05:22:19 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744139; cv=pass; d=google.com; s=arc-20160816; b=gTOnN8K8L29Rx8SiTQ5inFHQn7dGQBVFxclEP6VCKSpFyKGSu8JC2OZQbal8mGwxzv S7pt5MYkwAMXKjHN3Jei85JYzXLUDZMNSJSFLh4M8gloQHdRowN6y6XZcq4W4Gw36dS8 1Xgl4FGGUxr5bUzS7FW9gcNmz2LuQCbjbtcIwiZod42mp4BUmZdGGmbqeA1WNMUkXqfD TfHKAtZ6Azh+jJ8yWF/P3p7F84Dcm0OYPd5FECGyBkAiXoLHXDHTmtbYc5xPm1oKmNk/ GxpZ/G4hvUWDXRNWLM8iYD5xlvhUElSq2a8RoCjVwOmL9INW1V/k62+FH79oEBbsq66g IowA== 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=YEpdfXiJgj4Jm9Jp2bhrE93RDt7WdA7LswqJrPgEEHE=; fh=OQs+AtJvJFCvzA2+gFiHKHiqY2U/EgM1b4/E+vstE6M=; b=qwoDGsVqpCsTShxqrQPJI5E/f6TyeqNeRpFstQ6M5NnsyxAZQXqTb2/nyX0E7XTFHR reMahKaOZUae3nY7rEb+A5jRIMouHJMX9Lg/QoADjiEMSYcQM2ywfI+siOOWQiXq2TW1 DmTe/yZ/abUSDRch5qPZyYYun6UPshWfXFB8MJ6R0DlOrZbffbE1hJ5fvBwkGdyv+3YC mpY2PuFDTebngGfQ1HiqPvP+ha0BXLfTw9x9Q1O0sg2NfhPfzkIuoR9R/d/A7MXVprT2 q8yidSuye+JXRjcqq8bvUMBdTFdZDI4MdKSirpf35+UbEAjVJYTkiQbmR9BHyqBwolO1 cVgw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hbh+F4mU; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61636-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61636-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCV4HRx7KYI07YmNIsDreGkRrbbHpGQk7o7jxlKgrYvmON4/ke0uPvZZ0493yTSEOuzwqJtBp600uPG9FLfjRO9GaKltww== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id c18-20020a056402121200b0055fbf613c06si2667631edw.221.2024.02.12.05.22.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:22:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61636-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hbh+F4mU; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61636-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61636-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 0B1FE1F2233E for ; Mon, 12 Feb 2024 13:22:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D78993B2AD; Mon, 12 Feb 2024 13:14:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hbh+F4mU" 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 6CB9B4437D; Mon, 12 Feb 2024 13:14:25 +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=1707743665; cv=none; b=dhcweBxP8T9Q5VViIiZ4yNh0EODgHhQFuY96hMuqW5zcpiJzTi+CpjTpqp2uES2yLdUuK6X3I8H7hEccMFcbCkY65TeXsgUBRjr9ftO1iDj/ct6+mZrfzznbgxM0xuT7ea60T2xdMKD6Af7k4ZuQ0ZHUgxMkormQQW/nGQnTjiQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743665; c=relaxed/simple; bh=dcBrjJ5D1thLAwNTtA7Dp5db/HhUz1nGHoah5XIr6nA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mJwMR15jnwfWGt7r0l/psRu6S9Wggpej0LXv//bkvov7AtpXl7/8Qs4vfoMXMoFhjaA/+Ubf6zYeduOh2vwGvSuHp1E6005kot/qYZIXllIRD5I2A9eg41Qg3ggytxazt7i9GXzYqXmg8vYVwCPW12tlEh9AYBJodCSDIjPLefM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hbh+F4mU; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 84E29C433C7; Mon, 12 Feb 2024 13:14:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743664; bh=dcBrjJ5D1thLAwNTtA7Dp5db/HhUz1nGHoah5XIr6nA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hbh+F4mUdg8EgGAhhuQWjiZqvJDwvX6DXl43HH9sGvAwwtvkHQgAc0bH2MhpgYs5y tLh5ebw1fuqsMlDnvKIW+Nbbrztaz32ulhUFIi2Kcrp5viaDZggA5iSwlc76/It8cW 8aqfd4WZr5QKYwsamVEKILKd7D7Z/c6dzeuABcND8sh4KxFVysu4W9ntvppLfLlaOK X+fDorBuZRkxxN/6Wagllj6twJvRIJ+zafe/brK/Oss6+ZiOqGMXtjB9t9gdR3H+er QciPQUGf8DrHrGaCP+mkruGyplbsl8wpEfn/X/uEoo8Y8Rj3u/BmB2uC1/lQo4ASfC ji5trKsOVInRQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:03 +0100 Subject: [PATCH v6 20/36] drm/tests: Add TDMS character rate connector state tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-20-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=17784; i=mripard@kernel.org; h=from:subject:message-id; bh=dcBrjJ5D1thLAwNTtA7Dp5db/HhUz1nGHoah5XIr6nA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJLMrrW12dvke/epSV6Zs/bR6ZdCX068eFs3U0HvyP 3TmvtDVHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE8gQBi5OAZjIgkKGP9yiNcqXxRbWh3Wf F99kYFzMmHJKbY9G1vHvKuoJBecDQxj+cEmtTWjTrDZ5GW26KcbdJ15OZvWvOcn/bif+qO/rMOh gBgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699518891260230 X-GMAIL-MSGID: 1790699518891260230 The previous patch stores in the connector state the expected TMDS character rate matching the configuration of the HDMI connector. Let's add a few tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 166 ++++++++++++++++ drivers/gpu/drm/tests/drm_kunit_edid.h | 216 +++++++++++++++++++++ 2 files changed, 382 insertions(+) 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 d3f35600a9f9..d76fafb91025 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -816,6 +816,146 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); } +/* + * Test that when doing a commit which would use RGB 8bpc, the TMDS + * clock rate stored in the connector state is equal to the mode clock + */ +static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8); + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000); +} + +/* + * Test that when doing a commit which would use RGB 10bpc, the TMDS + * clock rate stored in the connector state is equal to 1.25 times the + * mode pixel clock + */ +static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10); + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); +} + +/* + * Test that when doing a commit which would use RGB 12bpc, the TMDS + * clock rate stored in the connector state is equal to 1.5 times the + * mode pixel clock + */ +static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12); + KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), @@ -827,6 +967,9 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), + KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc), + KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc), + KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc), /* * TODO: We should have tests to check that a change in the * format triggers a CRTC mode change just like we do for the @@ -958,12 +1101,35 @@ static void drm_test_check_format_value(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); } +/* + * Test that the value of the output format property out of reset is set + * to 0, and will be computed at atomic_check time. + */ +static void drm_test_check_tmds_char_value(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + conn_state = conn->state; + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_value), KUNIT_CASE(drm_test_check_bpc_8_value), KUNIT_CASE(drm_test_check_bpc_10_value), KUNIT_CASE(drm_test_check_bpc_12_value), KUNIT_CASE(drm_test_check_format_value), + KUNIT_CASE(drm_test_check_tmds_char_value), { } }; diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h index 2bba316de064..24f3377ef0f0 100644 --- a/drivers/gpu/drm/tests/drm_kunit_edid.h +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -103,4 +103,220 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = { 0x00, 0x00, 0x00, 0xd0 }; +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 1a 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 7a + * + * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c + * 00 12 34 78 28 20 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8 + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * Undefined display color type + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x7a + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Supports YCbCr 4:4:4 + * Supports YCbCr 4:2:2 + * Native detailed modes: 1 + * Colorimetry Data Block: + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: Selectable (via AVI YQ) + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * DC_48bit + * DC_36bit + * DC_30bit + * DC_Y444 + * Maximum TMDS clock: 200 MHz + * Extended HDMI video details: + * Checksum: 0xa8 Unused space in Extension Block: 100 bytes + */ +const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x1b, 0xb1, + 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x78, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa8 +}; + +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 8a + * + * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c + * 00 12 34 78 44 20 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8c + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * RGB color display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x8a + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Supports YCbCr 4:4:4 + * Supports YCbCr 4:2:2 + * Native detailed modes: 1 + * Colorimetry Data Block: + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: Selectable (via AVI YQ) + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * DC_48bit + * DC_36bit + * DC_30bit + * DC_Y444 + * Maximum TMDS clock: 340 MHz + * Extended HDMI video details: + * Checksum: 0x8c Unused space in Extension Block: 100 bytes + */ +const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x1b, 0xb1, + 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x78, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8c +}; + #endif // DRM_KUNIT_EDID_H_ From patchwork Mon Feb 12 13:13:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199788 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2428901dyd; Mon, 12 Feb 2024 05:33:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IGTXlxTsElonWv+hiLGX3CN/E17S4SaKqAAUoDwyu/3PczYbkt8NGDlQ8yVJvrKB8YqVa1k X-Received: by 2002:a05:6a20:1e84:b0:19e:9c82:b139 with SMTP id dl4-20020a056a201e8400b0019e9c82b139mr3417579pzb.45.1707744814019; Mon, 12 Feb 2024 05:33:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744813; cv=pass; d=google.com; s=arc-20160816; b=Byapudsas4hig8k+bf5p3bHfIws9IBL37r5UizUFoiiShw0WFrtKayg9HPMiOQ7S27 3X6tx0yPUi8QOhIiyNfQGAmVLzs98tStqQVmy9tlAA3NAdWU/ITeGnJRC1dKoUF+6KT2 nxWI+5xHG8KserWjfrYbGD5dZTG6Ed7lPkxECl0jd0ILeHIpIOSjOc1cM9aKKdsaezL9 OywiPSmu7P2ncD3rhKqz3SzgUfv1ESvK69vM8gpNaJSlpcRgkXi3UiiB+y5S1nmVXDCj i5rCVLPg5d2ofg6efNR9EJ6WtXC8UW0mtOTpYToiJTVdHV75BksuQ/S0TtrCysxgYNrv fLuQ== 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=RkZ7V2IkurEROlaB2LGRneR789YqEsKq7Ib0AoT4xLM=; fh=9jNTtepZDx12KjTDRBrQIiaRo08L/MRXjV7pT5NjH7M=; b=ACicPCvouin9sIPqyRpBpD0N+hVzyi9Z7PwOOIacm609JXnm5jm3TCZHrjzE+CytDP i/CmH9DZ2EufmSbaLbGu91iOMR6jaf6/NkhkmcbDVJqeaeCC9hA+xhdm1CnI/DCtN2nz gYw0TtQvW2EdQb7RQ47bSdo94VIaFhV/YYlTPntqzI82ep0SNvW6CzNx0tw0giderszj FKxCPuLpbPZmY6kjzzX7yoXelAmsJp5auNjBhO3KCpVK31Qr9ulhfdJ+tKc9i+WtgNuw uwzwMYqt+xDzMNd3KVJ/9xzcvi7Y2ULanUZnJunRZJVxzdtFQNEyxhRbtgvH+7T+ZdAc AxWg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RGARsEI9; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61639-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61639-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWQVk3yniNtJ7RL7vhF8k4CAnD8CY39X1NDEfmubTger8k7S9oSXzisg/xQrz761rub8EKv31czZ7v9xZ03TGfa5+quIA== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id u17-20020a63b551000000b005d4af343858si242904pgo.361.2024.02.12.05.33.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:33:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61639-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=RGARsEI9; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61639-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61639-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 60F23289579 for ; Mon, 12 Feb 2024 13:22:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B95C4481B4; Mon, 12 Feb 2024 13:14:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RGARsEI9" 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 DF9AF45BE3; Mon, 12 Feb 2024 13:14:27 +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=1707743668; cv=none; b=m4XqCHZgj5ws3HfyvRUNkaU+9pjZkdUk9hqxHxpiqvP8Hc3dXOi+938+lN6BUJ1E1d8JogKxU3KUzUYrtwScZlJFtZK6BDlJnbnmEPcVdCCu+9lageWWxLhcEHRyQhzz9jkREukGRPQYjHBefOFkqZzcv0Ay2KRjBCbh4q3fSwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743668; c=relaxed/simple; bh=LhniIRDebcQ1WtQbDyA1K0rXNp4WmruPrv/0+dGUHSk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mcx7aIzOn5X9VdH6XHMMMTPOm/TScT359Buahm1i8+n7P9DDByDbidcPyjPyio5usWeAM7JZ/FQfCo8NjiN3B8iv0dBVkrrO/SRDpARBC2vj9ODQz5GhotjVwQLCxLHlp68ydnd9UleNuUGbfo1+B1GqOo/V6Bq+jDFpf5vBt2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RGARsEI9; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 602A9C433B2; Mon, 12 Feb 2024 13:14:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743667; bh=LhniIRDebcQ1WtQbDyA1K0rXNp4WmruPrv/0+dGUHSk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RGARsEI9kyGSSVGtidFq+XfP5T8+mkOh/+uHtPtUy5kGKrS09eIDPwqBXVkoS4Lwo ORcSZfKmfLMft2CfVpQNWMK8yhuM7uaVxc+pB0J3BqTxLWo0Dms0rIA5kZAlGSyO+L XLgHAgDzxKyck6g6UqMZimOkXrHRSFVkXonp4synnOmlZBW1+jM857op3o+9AJIkai d6cL5+/M61LR/kfHDxkWnCw5tD3Ox344Myht0BuiAwu4DLgbAAO2lIfJ24yacdNu8o klzSxIMQ4ALpyhLGfZ2EIdxBj/RwKj6+aSC0A7re2GResTmNN6j0cVWfP+mlYgim+T USPcSwa7EbgRA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:04 +0100 Subject: [PATCH v6 21/36] drm/connector: hdmi: Add custom hook to filter 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: <20240212-kms-hdmi-connector-state-v6-21-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=10268; i=mripard@kernel.org; h=from:subject:message-id; bh=LhniIRDebcQ1WtQbDyA1K0rXNp4WmruPrv/0+dGUHSk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJLN3FTwN/cr+uzvNdveV3+9Fp6W2bDK24LiV/Ps8q 2rWj5vRHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE8gQBi5OAZjIAkuGv4Kcxb3h/SycSWdm RT28sEqE35rx/cJiCW1PQyP1SwfzWBn+8PHFFCdafdlhXcpzuuGuw9R/LpKftwc/XyReXLZoa2U DGwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700225663489734 X-GMAIL-MSGID: 1790700225663489734 Most of the HDMI controllers have an upper TMDS character rate limit they can't exceed. On "embedded"-grade display controllers, it will typically be lower than what high-grade monitors can provide these days, so drivers will filter the TMDS character rate based on the controller capabilities. To make that easier to handle for drivers, let's provide an optional hook to be implemented by drivers so they can tell the HDMI controller helpers if a given TMDS character rate is reachable for them or not. This will then be useful to figure out the best format and bpc count for a given mode. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 9 +++++++ drivers/gpu/drm/drm_connector.c | 4 +++ .../gpu/drm/tests/drm_atomic_state_helper_test.c | 4 +++ drivers/gpu/drm/tests/drm_connector_test.c | 15 +++++++++++ include/drm/drm_connector.h | 30 ++++++++++++++++++++++ 5 files changed, 62 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index ac77d47a0ce3..3a965c4aa59b 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -688,11 +688,20 @@ hdmi_clock_valid(const struct drm_connector *connector, const struct drm_display_mode *mode, unsigned long long clock) { + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; const struct drm_display_info *info = &connector->display_info; if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) return MODE_CLOCK_HIGH; + if (funcs && funcs->tmds_char_rate_valid) { + enum drm_mode_status status; + + status = funcs->tmds_char_rate_valid(connector, mode, clock); + if (status != MODE_OK) + return status; + } + return MODE_OK; } diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 332477c6a987..a4466a79421e 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -457,6 +457,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @dev: DRM device * @connector: A pointer to the HDMI connector to init * @funcs: callbacks for this connector + * @hdmi_funcs: HDMI-related callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats @@ -476,6 +477,7 @@ EXPORT_SYMBOL(drmm_connector_init); int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, @@ -512,6 +514,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (max_bpc > 8) drm_connector_attach_hdr_output_metadata_property(connector); + connector->hdmi.funcs = hdmi_funcs; + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); 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 d76fafb91025..a43bbfc2c2d0 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -110,6 +110,9 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto return 0; } +static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { +}; + static int dummy_connector_get_modes(struct drm_connector *connector) { struct drm_atomic_helper_connector_hdmi_priv *priv = @@ -192,6 +195,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, conn = &priv->connector; ret = drmm_connector_hdmi_init(drm, conn, &dummy_connector_funcs, + &dummy_connector_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, formats, diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 0a838924a546..6a3651b08c81 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -22,6 +22,9 @@ struct drm_connector_init_priv { struct i2c_adapter ddc; }; +static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { +}; + static const struct drm_connector_funcs dummy_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, @@ -187,6 +190,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -205,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, BIT(HDMI_COLORSPACE_RGB), @@ -223,6 +228,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -241,6 +247,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -263,6 +270,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -297,6 +305,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -331,6 +340,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -361,6 +371,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, 0, @@ -379,6 +390,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_YUV422), @@ -398,6 +410,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -431,6 +444,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -695,6 +709,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 59016d9c17f5..3eaf4d54364d 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1093,6 +1093,30 @@ struct drm_connector_state { } hdmi; }; +/** + * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions + */ +struct drm_connector_hdmi_funcs { + /** + * @tmds_char_rate_valid: + * + * This callback is invoked at atomic_check time to figure out + * whether a particular TMDS character rate is supported by the + * driver. + * + * The @tmds_char_rate_valid callback is optional. + * + * Returns: + * + * Either &drm_mode_status.MODE_OK or one of the failure reasons + * in &enum drm_mode_status. + */ + enum drm_mode_status + (*tmds_char_rate_valid)(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate); +}; + /** * struct drm_connector_funcs - control connectors on a given device * @@ -1967,6 +1991,11 @@ struct drm_connector { * supported by the controller. */ unsigned long supported_formats; + + /** + * @funcs: HDMI connector Control Functions + */ + const struct drm_connector_hdmi_funcs *funcs; } hdmi; }; @@ -1989,6 +2018,7 @@ int drmm_connector_init(struct drm_device *dev, int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, From patchwork Mon Feb 12 13:13:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199767 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2423011dyd; Mon, 12 Feb 2024 05:23:13 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWp7f1SQOiqMroyYOyShIq1kRG6wReb5v4aE73kocqokX/aAFAQ9zjLm00+dMJ6TavWV0zpj/WsuW1b+yl0r1gQ5x/wig== X-Google-Smtp-Source: AGHT+IHdhKQYtf5VbfEQmdEiVvcuboW2ILQqlejc2vHmLdzlbZPolnpVTRxUD+xkhQlDcEX84lUM X-Received: by 2002:a17:906:24ce:b0:a38:98ee:698c with SMTP id f14-20020a17090624ce00b00a3898ee698cmr4549605ejb.63.1707744193433; Mon, 12 Feb 2024 05:23:13 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744193; cv=pass; d=google.com; s=arc-20160816; b=uc12jt9ZBmGoF6GBVb6b6U2POnMR5Gy5FAmWadYfKQ7iH6E+z+iBTsxWXqFZEcRL4+ Da2NnsudNGBYRT69aaRTo/Ew79F3RFpDvh7xI+Rw4teJArvGGop/9g5jNU41Hla0GttX 7UygBDTZFRDKWUSA3Psyssnmq1sjIcOrxG11Q5vKRI50LOBc3nbLSvLUgLT55T6c95gJ AcSYvEPLIr0/0azFkmadr1ejbEL1OVhOQ8ddu9653bHaMnZHlRk4iQUjWjkiw6D/pdyF IGnD3trLF0dS/3uSGBq1Blc5UhKUPufZiWW3whZR44CFYDfMd02SlL1mmGwgonsyt+Ph LdBQ== 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=9v4Ts6NdSbTCWSlTuguSaZ9/dF98VqvHfymIrNsXEOo=; fh=VXBu33X14jQoA64E4z7OcSrMfSTsOl6sygQ0CcnSZCs=; b=hzukglueN0874IvXWSnooMl3v+hTzUy8pdBIEKVBb0OsIHDNLZ2PCpXa0lQkeIMJF6 XqL+kyTtKEl95j1oTTt1Og0ilCgbt1YgY3McAltQEOLkfLaCtSJp+ngFJzzcjaFahoFf h2O52H5F47ppKgBz+CrH8pmAd5UNYObQ0i+PxLk0KrykgtF+BjdX9eiClt0/vnNtk+bR wYBS9fy5Z2GeWuJcDMrPdvMXW3wAuznzolyBkH2jz7GiO9eYN0p2qNMCoMoq5nkNyyfE B60a4ZsfHK0DXtIxiGPF0meSf5sVMmsvD3SwFkgUKtCfXVifCvgJHWo1sCiO2r5mEdL6 HGDA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rt0dQRF3; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61641-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61641-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXfXYeZxsSW2DzFj2E4A2CvTZt/3jFsZjsXrODhNtBUCo0IFx4gawwfPnUb/n/9vRS5MiWay8N9miCiVCBp1acaMvZ7yQ== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id lv25-20020a170906bc9900b00a3c15b989f3si173564ejb.802.2024.02.12.05.23.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:23:13 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61641-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rt0dQRF3; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61641-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61641-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 am.mirrors.kernel.org (Postfix) with ESMTPS id DC1DA1F215B5 for ; Mon, 12 Feb 2024 13:23:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E1C624CB20; Mon, 12 Feb 2024 13:14:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rt0dQRF3" 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 AD17A47A57; Mon, 12 Feb 2024 13:14:30 +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=1707743671; cv=none; b=rJBqTXuBvlJd6rmi3M5jZ027fmRcas9LpRmj2PL6ViS7Q2bvHwvYyHTYOHdmtR7fMKMmhaUdAQbl/0pWXNAUwgCZg35dUkJ8FxfXYQB0K188xpimJc/oJ0Xna5DIiFwa1B9edGbWluzunwkV6QVKse1cpotcPISY9y0eTUpFx4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743671; c=relaxed/simple; bh=qjCUh+MOUGaoHfnBp8m5jk+g0FV9Vj8vmvysXWvLAuQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lp7B8m0uPUHAVpIz2wwI9CL6NAtfik2lTlb9FMXfas5rr2Vftn02T3k3OTsfXs1ZfdLHLtxsCFCIJQnLX29M/3U3+g3vdeyysYXnwks9jII4CJWRHKbDxrbxgUzVMq+GC+obh1aAU20+myUKz/idKGXh0kJCV8pXwKRxnF0joX0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rt0dQRF3; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4ADDBC3277A; Mon, 12 Feb 2024 13:14:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743670; bh=qjCUh+MOUGaoHfnBp8m5jk+g0FV9Vj8vmvysXWvLAuQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rt0dQRF3MEGHjZ6GyqelsvJ6Lplv8YjXD+dViULXEzR9MA6D/cKMBfcPZjOoo5p4g E0lf2h0N1h4RlX5oHsaS0KAGUX4JURpHn7Ha7C/e9TVf8dYAXqspm+vBPX4SG1wvqj nF30sMDzUwDo4TS1gcS2zbPYLck+4n0fIkXCsJp+34NGWCYD0OHFm/E0gDgoklJnHS iKR7LHWPHkEh9eUBkzNZrpM2bqX2mu3eAjkFF3GZERuM0VQNY/T5C8HxNDUS8jS6zu hE00WupkFsbyfMuozkH05W05iUaGLM2vhrUvPyWcJXJnt0DLg2SMhSK8dYoY6sNbIn vtshyAadq8L8A== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:05 +0100 Subject: [PATCH v6 22/36] drm/tests: Add HDMI connector rate filter hook tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-22-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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=4001; i=mripard@kernel.org; h=from:subject:message-id; bh=qjCUh+MOUGaoHfnBp8m5jk+g0FV9Vj8vmvysXWvLAuQ=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJHOWBSdMXbnm0bKYlNPiuhcX+m6NSs791tnvxnXVJ ufAizKHjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEzkeRgjQzuLXoiGJtPzI9Ff Q0O/G/i2htw9tm+q1+E/h4+cT3RxdWT47zTl2qe27yvF2U1evDxrcvpWxnnt91lvdNaLx21Z7cl /lhMA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699575003847306 X-GMAIL-MSGID: 1790699575003847306 The previous patch adds a new hook for HDMI connectors to filter out configurations based on the TMDS character rate. Let's add some tests to make sure it works as expected. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) 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 a43bbfc2c2d0..e7dbdd4a4e7f 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -113,6 +113,18 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { }; +static enum drm_mode_status +reject_connector_tmds_char_rate_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate) +{ + return MODE_BAD; +} + +static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { + .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, +}; + static int dummy_connector_get_modes(struct drm_connector *connector) { struct drm_atomic_helper_connector_hdmi_priv *priv = @@ -960,6 +972,58 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500); } +/* + * Test that if we filter a rate through our hook, it's indeed rejected + * by the whole atomic_check logic. + * + * We do so by first doing a commit on the pipeline to make sure that it + * works, change the HDMI helpers pointer, and then try the same commit + * again to see if it fails as it should. + */ +static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_crtc_state *crtc_state; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + /* You shouldn't be doing that at home. */ + conn->hdmi.funcs = &reject_connector_hdmi_funcs; + + state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->connectors_changed = true; + + ret = drm_atomic_check_only(state); + KUNIT_EXPECT_LT(test, ret, 0); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), @@ -969,6 +1033,7 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), + KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc), From patchwork Mon Feb 12 13:13:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199794 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2433117dyd; Mon, 12 Feb 2024 05:41:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IHfzMQuf57uMiSiKjZOMpY1qjPjDZVLe/hSnpjL+NbKczfAwgqtHykWgLkFyonw62tcbQAD X-Received: by 2002:a17:90a:d30e:b0:297:1af6:cd3f with SMTP id p14-20020a17090ad30e00b002971af6cd3fmr2468163pju.43.1707745302631; Mon, 12 Feb 2024 05:41:42 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707745302; cv=pass; d=google.com; s=arc-20160816; b=LJdrIY2oXCyA1XGTX4g7JaSiQdlNurlOh1WSibZO77IQ+xdG7Ee7aQWTLGLZnBQkzw DYllN44QdgsImaQIizH2LRmV22oPA2vyuTzAoz/yZRy/IsmY6qGyHmfEJzBrJw1M3U0y MY7yq5U5wkwyzcGJ4rcexXC2YviyFJV8gLA1yfsZIW1UbyckTxfe4Q4Lp5n6W5xOojos f3FRsVRdKZ7/Svznh25xIjPYrUZn7knhrb5/JqlOZBb8Oi6NB1fhxeuaLXjNlaUiszYa xifz8ViihnK+tDQZ5kFmdBu8nyYzZw/w4UTFsS/xq33e4ERMKzBjNuTpzMq19Wi+R/Z5 USLA== 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=HJfD77jCH0Q4d6gM/u90FKa+wxWnO0RYLLeec3em8zY=; fh=GG0TtEDsmieExJRMU7Mkk/kgIz1Ww079Eejmi47kgnU=; b=r7BJubFsGs3ShH5ut0hp9kA9KaYYvd3WktcELXec6W6l+BlcsAEVBNAlh7YvFF5h2k il5nt1g4UcLpmYlIEtTZdU55GNOO2cgJtnwLDqzE7MiK1MHzxc1VnQjY6WRVPkfI8vyT nDkVE7YbdC0rbDBvvI4khUQRWHYf5UF+ro/J2kn8p5W6vLTKIinZYy1kfOGK5hqGQ7Q/ 0VQHr8pnakN/NAYY7xVkA2sBSyDhNOgTZgkEZTAAKBgdqEIhSwXtt4Kc6FK2UaFRGxmY GlQfm86S8J+Q9NVrPJgJ+UswLcqWvjv9RQp/lkejQoGOK8zkTXWissyb88IcSW2St0KZ hcIw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=GQsqaYCm; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61643-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61643-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCUjAcVqdLEabz9+Y0vDJneN65d7cksb1rrmCzqBnFzgcaRSjG+H9e6BI95YNAllCwTxs9P5tv5KagRcAc2yASETNXZlsg== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id k14-20020a17090a39ce00b00290e0e74a9bsi308028pjf.75.2024.02.12.05.41.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:41:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61643-ouuuleilei=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=GQsqaYCm; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61643-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61643-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id A41D0B24615 for ; Mon, 12 Feb 2024 13:23:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DECA14D584; Mon, 12 Feb 2024 13:14:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GQsqaYCm" 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 2253E4A9B0; Mon, 12 Feb 2024 13:14:33 +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=1707743674; cv=none; b=DDsnlYEzJQ8CcmJucmNgRjQPJeV8odoRvwvhy9qf2CxhhdjeiDPDQucMuDxNlAzOd9L6VGZhXeKhTOGnxmtNemPp0oQs1LoheH/trFxVtC1ndTNtYGEKuTBkNBBkm9kBDa3AtLHU6Nr83ujAL2tUd8FiKnrhbFX4//bd85zobYE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743674; c=relaxed/simple; bh=gptiy79w538Sn9pb9NAN8Se/wBSmLod/WTk63G/WSEA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N6+9sQxX8/IgUvkexYYWiawxensDNVLQirjhqJ9+9f+R/Q75IT1WJToJWASC6+wH548tUxYpEwYxQBQ/Fr+RQIaokEGTLqPp6/Ixm1qcXQfW0T/lV+V726NN2wIrcFWz5tm0SdiXDioRubgdRQy191GDgrAn4wXa+Q+tw3qulCg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GQsqaYCm; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34AB8C43330; Mon, 12 Feb 2024 13:14:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743673; bh=gptiy79w538Sn9pb9NAN8Se/wBSmLod/WTk63G/WSEA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GQsqaYCm00QqELYgB+muLCgd5AgEvSwC8MaTOfc2qIsj9ewnnwitxL204aeFxG8Jz m18Pn2qioz2Th8TCSL3DCL9DKz/RVvP+DvSDNRMOPxDEwHTKV6WJ78j7GD/PCkXp8O JjiEVGgl4kVyqTRUSlpNTlEGmYFjFpWYVr+hM/xxL+xxf0T90EkZ/24ugG/c7DbUsg NZNl5lEm/yXOSDwOqdxPCP0bktAwohsUzrF0DZPlqMaj3thU+TASZggPkj+NFP2gNR e3dBteKhBOM2OGw5kdol5qk6KC39/oijRpyvYhKZOcqHdtnl4rCnm0EPcK9dkIFuXB Gu1UT4o0AomHQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:06 +0100 Subject: [PATCH v6 23/36] drm/connector: hdmi: Compute bpc and format automatically Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-23-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9729; i=mripard@kernel.org; h=from:subject:message-id; bh=gptiy79w538Sn9pb9NAN8Se/wBSmLod/WTk63G/WSEA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJHNcFqYFm/gev517KV946oeVF4xaL0gUM8ziss6rF bznECrSUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIlInWH4Kxh0R9XT9czPivsR gY4beWyOtt3gnsb66daCLNZHM7bUCTIyzK+wDYlf//EZs5n018ZD7Ue6+159Wtn0y/7ihn+8H+J 92QE= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700738738088807 X-GMAIL-MSGID: 1790700738738088807 Now that we have all the infrastructure needed, we can add some code that will, for a given connector state and mode, compute the best output format and bpc. The algorithm is equivalent to the one already found in i915 and vc4. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 183 ++++++++++++++++++++- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 25 ++- 2 files changed, 196 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 3a965c4aa59b..67fb9dd2e41e 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -683,6 +683,96 @@ static bool hdmi_is_full_range(const struct drm_connector *connector, return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL ? true : false; } +static bool +sink_supports_format_bpc(const struct drm_connector *connector, + const struct drm_display_info *info, + const struct drm_display_mode *mode, + unsigned int format, unsigned int bpc) +{ + struct drm_device *dev = 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 != HDMI_COLORSPACE_RGB || bpc != 8)) { + drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n"); + return false; + } + + if (!(connector->hdmi.supported_formats & BIT(format))) { + drm_dbg(dev, "%s format unsupported by the connector.\n", + drm_hdmi_connector_get_output_format_name(format)); + return false; + } + + switch (format) { + case HDMI_COLORSPACE_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 HDMI_COLORSPACE_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 HDMI_COLORSPACE_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 hdmi_clock_valid(const struct drm_connector *connector, const struct drm_display_mode *mode, @@ -727,6 +817,95 @@ hdmi_compute_clock(const struct drm_connector *connector, return 0; } +static bool +hdmi_try_format_bpc(const struct drm_connector *connector, + struct drm_connector_state *state, + const struct drm_display_mode *mode, + unsigned int bpc, enum hdmi_colorspace fmt) +{ + const struct drm_display_info *info = &connector->display_info; + struct drm_device *dev = connector->dev; + int ret; + + drm_dbg(dev, "Trying %s output format\n", + drm_hdmi_connector_get_output_format_name(fmt)); + + if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) { + drm_dbg(dev, "%s output format not supported with %u bpc\n", + drm_hdmi_connector_get_output_format_name(fmt), bpc); + return false; + } + + ret = hdmi_compute_clock(connector, state, mode, bpc, fmt); + if (ret) { + drm_dbg(dev, "Couldn't compute clock for %s output format and %u bpc\n", + drm_hdmi_connector_get_output_format_name(fmt), bpc); + return false; + } + + drm_dbg(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n", + drm_hdmi_connector_get_output_format_name(fmt), bpc, state->hdmi.tmds_char_rate); + + return true; +} + +static int +hdmi_compute_format(const struct drm_connector *connector, + struct drm_connector_state *state, + const struct drm_display_mode *mode, + unsigned int bpc) +{ + struct drm_device *dev = connector->dev; + + if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_RGB)) { + state->hdmi.output_format = HDMI_COLORSPACE_RGB; + return 0; + } + + if (hdmi_try_format_bpc(connector, state, mode, bpc, HDMI_COLORSPACE_YUV422)) { + state->hdmi.output_format = HDMI_COLORSPACE_YUV422; + return 0; + } + + drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n"); + + return -EINVAL; +} + +static int +hdmi_compute_config(const struct drm_connector *connector, + struct drm_connector_state *state, + const struct drm_display_mode *mode) +{ + struct drm_device *dev = connector->dev; + unsigned int max_bpc = clamp_t(unsigned int, + state->max_bpc, + 8, connector->max_bpc); + 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 = hdmi_compute_format(connector, state, mode, bpc); + if (ret) + continue; + + state->hdmi.output_bpc = bpc; + + drm_dbg(dev, + "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n", + mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), + state->hdmi.output_bpc, + drm_hdmi_connector_get_output_format_name(state->hdmi.output_format), + state->hdmi.tmds_char_rate); + + return 0; + } + + return -EINVAL; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -752,9 +931,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); - ret = hdmi_compute_clock(connector, new_state, mode, - new_state->hdmi.output_bpc, - new_state->hdmi.output_format); + ret = hdmi_compute_config(connector, new_state, mode); if (ret) return ret; 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 e7dbdd4a4e7f..262d974341c0 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -70,9 +70,6 @@ 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); @@ -720,10 +717,15 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) 10); KUNIT_ASSERT_NOT_NULL(test, priv); + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - conn = &priv->connector; preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -741,11 +743,11 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) old_conn_state = drm_atomic_get_old_connector_state(state, conn); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); - new_conn_state->hdmi.output_bpc = 8; + new_conn_state->max_requested_bpc = 8; KUNIT_ASSERT_NE(test, - old_conn_state->hdmi.output_bpc, - new_conn_state->hdmi.output_bpc); + old_conn_state->max_requested_bpc, + new_conn_state->max_requested_bpc); ret = drm_atomic_check_only(state); KUNIT_ASSERT_EQ(test, ret, 0); @@ -789,10 +791,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) 10); KUNIT_ASSERT_NOT_NULL(test, priv); + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + ctx = drm_kunit_helper_acquire_ctx_alloc(test); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - conn = &priv->connector; preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -1167,7 +1174,7 @@ static void drm_test_check_format_value(struct kunit *test) conn = &priv->connector; conn_state = conn->state; - KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0); } /* From patchwork Mon Feb 12 13:13:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199799 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2435114dyd; Mon, 12 Feb 2024 05:45:36 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU5FoXLv6Yr/cW9rjkwm+TLvavNtqSWytgxrXoo1N+/FC2LZpEGDYB5OdFgYUHOkTN70hLsPxe4oi8lYfLHi4j2MlKKdA== X-Google-Smtp-Source: AGHT+IGHw6eO7c8DSry9UMNzV+FBBbhbKXeMtiGBobOCua9QX/Q3LOdVwG4rP8om48fNTie8exSI X-Received: by 2002:a17:903:40d0:b0:1d9:e182:2bf8 with SMTP id t16-20020a17090340d000b001d9e1822bf8mr9607741pld.6.1707745536488; Mon, 12 Feb 2024 05:45:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707745536; cv=pass; d=google.com; s=arc-20160816; b=JpC5v3ey/FbUgXnKm1ZRbyKpmSBvKcQZbNnf9N3C3gNnROGckO5LqNMONEQ56po3Ur r1RNieaQFqNMY84Zg7fIxCPub5NkSUzO7oFCeFHPwFM/xq42Z4EDwQdCSyJnsbTcN1/y NWrPPMBC8+CBzxAU8l2XbrxhEVthCFsoUXlKGeZDX/d4JuifvGVqMvRNo0XZE+gKdSNC v6sh8bKRLMrM3Vkpnl8Yrx2fB5rQNAeBvlBIvh9RPwAwvZhvRDBku9IWPT/osP8V4led BvmJDm2WCcRqrs2HWoUvdFxGsfGVnFgQP+239uTKeQNmiMmaSDA5XVW3AB3STpTzI249 n1NA== 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=AYFyxns+vUj9Mz6yfe1Beu2mrIqPTzc0/6itLsTr1nE=; fh=jOGP4uFUn9wshvFLsN9855W3DSTI/8KjB+dLQ6rNhQk=; b=NIpfB3G0+J2GPjykHkCX3/RqGSe6V3ZdMeNXMK2FUMRCjjCdZrfJvj3wuIx9tHntPn yWp+0/q8fFOXtbjUO20SmDhrZWO/Vo+Q/AcJXy0jWW8h1r1DCxGHkuatREhw8k8lVdWP fq8mj0EAecERpH898cj1bTGb5oYRQ9cvjCh2JnT8YiRCCL0BPi5EJ45HDodGwD/YQSK8 b3o4DzYBqsD7GbDpT67JkvammkUL5BP6ZOaVMmlyyEOGcjZIdzV4USzKeeeAnHOCDP7L g0CqIkdiJSXl1lxupWtT5Qtt2hrsOyemq2n5XCjWe1UbO+gmxMSXHPI2YaxhGTlhJGSU svzw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=KmWFQdWC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61644-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61644-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXCCWEAlRMrwC9lpItUSNYHB2YNUKFdUiHMBzFhadlENIn5QIaio5CBjYNkinDDe5m2hj/YfVzfRS1ZM3AupMUaooUZmg== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id jd10-20020a170903260a00b001d89ed15302si264394plb.495.2024.02.12.05.45.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:45:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61644-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=KmWFQdWC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61644-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61644-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 0C33EB21F40 for ; Mon, 12 Feb 2024 13:25:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 871244F5EC; Mon, 12 Feb 2024 13:14:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KmWFQdWC" 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 D57E44CB54; Mon, 12 Feb 2024 13:14:36 +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=1707743677; cv=none; b=Kf8UXkKMTljMSVQYghyH8ZqTOzyrOOqTBGJgfdsarojf82DiKJo7Lw608Kv2Lk8F2RRpzFN00YHcNF9ksnNZrKNP0/kJD6eyPLwXAFkpovV+qZJmbFFrep+BXF5lS9MZ+AMcYmSH7U0vcj0HWSQQHWMsd8g8qIeUzuB8iRSmqr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743677; c=relaxed/simple; bh=Rffl6qvCp13etRQCv4UHD54Lchb9zVRLPz1JX9Yd8M0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LweA2s1VlzEeXqkxT111Zaxdq8LlKYJQc7xodSynpbPE6gNy0VCIZUOmlZEyJ8+GTlmdvF2AJqln9Z6uV721WQlHlxTAaXFoYOVy44+iuND0oC6xeCiiXlgUVEDpmcn2bnpmfCkiO1v7H6q8LUInBCPB+mP8kI38Yko4hic3bWk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KmWFQdWC; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 228F3C43609; Mon, 12 Feb 2024 13:14:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743676; bh=Rffl6qvCp13etRQCv4UHD54Lchb9zVRLPz1JX9Yd8M0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=KmWFQdWCtrXIO/pJ0fz5oUB7vN6emo7oSwMWZKMOpzjqyOUkjcOYhMdJfs0lkWiq6 lwRsdmas0wDW/TeG52x9PQT6PzqdyvxryLMMmPynhRxNHs/aDPMDiDZNiLZjsfkKtE EQgBo8DDaPhNuBZv3hWCa5sFkrOZaakii3h7VmeQgbnEquES7pj3ZgKR5Y3uEPSG7J l5UyeDjVrHb0EsF0Oz5Hsdjj6d20voglvcw1dgfj1o2CvtoPjiH1U+o0d9rGr+oCmw iYs0h4LhV2cekF76MA+Yawjll7Vi7LN4PIm/O7DTOOGkKJ8joD1K51j1Pcn1vU1KSH lmaielvj9IXuA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:07 +0100 Subject: [PATCH v6 24/36] drm/tests: Add HDMI connector bpc and format tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-24-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=27010; i=mripard@kernel.org; h=from:subject:message-id; bh=Rffl6qvCp13etRQCv4UHD54Lchb9zVRLPz1JX9Yd8M0=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJHNZ2Gzd97a9FOC2Cyk9eWhnWdfP99IVoqcS8o0sr gVUKq3qKGVhEONikBVTZIkRNl8Sd2rW6042vnkwc1iZQIYwcHEKwET6bRn+Kchuu3hSJEJoXVZd U45JwpQ5Di+SVVK0v+yffL80NXlaB8P/eKY4fums7asXdjhdW/fMW9d9B1fQ9rpN0Wfa4r/KOW7 hAgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700983644988651 X-GMAIL-MSGID: 1790700983644988651 The previous patch added the bpc and format an HDMI connector needs to be set up with for a given connector state. Let's add a few tests to make sure it works as expected. Signed-off-by: Maxime Ripard --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 504 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_kunit_edid.h | 160 +++++++ 2 files changed, 664 insertions(+) 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 262d974341c0..860e34b00fee 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -839,6 +839,56 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); } +/* + * Test that if we have an HDMI connector but a !HDMI display, we always + * output RGB with 8 bpc. + */ +static void drm_test_check_output_bpc_dvi(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_dvi_1080p, + ARRAY_SIZE(test_edid_dvi_1080p)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_FALSE(test, info->is_hdmi); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + /* * Test that when doing a commit which would use RGB 8bpc, the TMDS * clock rate stored in the connector state is equal to the mode clock @@ -1031,6 +1081,452 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) KUNIT_EXPECT_LT(test, ret, 0); } +/* + * Test that if: + * - We have an HDMI connector supporting RGB only + * - The chosen mode has a TMDS character rate higher than the display + * supports in RGB/12bpc + * - The chosen mode has a TMDS character rate lower than the display + * supports in RGB/10bpc. + * + * Then we will pick the latter, and the computed TMDS character rate + * will be equal to 1.25 times the mode pixel clock. + */ +static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); +} + +/* + * Test that if: + * - We have an HDMI connector supporting both RGB and YUV422 and up to + * 12 bpc + * - The chosen mode has a TMDS character rate higher than the display + * supports in RGB/12bpc + * - The chosen mode has a TMDS character rate lower than the display + * supports in YUV422/12bpc. + * + * Then we will pick the latter, and the computed TMDS character rate + * will be equal to the mode pixel clock. + */ +static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 12); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000); +} + +/* + * Test that if a driver and screen supports RGB and YUV formats, and we + * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could + * have had a higher bpc. + */ +static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *mode; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + mode = drm_display_mode_from_cea_vic(drm, 1); + KUNIT_ASSERT_NOT_NULL(test, mode); + + /* + * NOTE: We can't use drm_connector_hdmi_compute_mode_clock() + * here because we're trying to get the rate of an invalid + * configuration. + * + * Thus, we have to calculate the rate by hand. + */ + rate = mode->clock * 1500; + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + +/* + * Test that if a driver supports only RGB but the screen also supports + * YUV formats, we only end up with an RGB format. + */ +static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + /* + * We're making sure that YUV422 would be the preferred option + * here: we're always favouring higher bpc, we can't have RGB + * because the TMDS character rate exceeds the maximum supported + * by the display, and YUV422 works for that display. + * + * But since the driver only supports RGB, we should fallback to + * a lower bpc with RGB. + */ + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + +/* + * Test that if a screen supports only RGB but the driver also supports + * YUV formats, we only end up with an RGB format. + */ +static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + /* + * We're making sure that YUV422 would be the preferred option + * here: we're always favouring higher bpc, we can't have RGB + * because the TMDS character rate exceeds the maximum supported + * by the display, and YUV422 works for that display. + * + * But since the display only supports RGB, we should fallback to + * a lower bpc with RGB. + */ + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); + + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + +/* + * Test that if a display supports higher bpc but the driver only + * supports 8 bpc, we only end up with 8 bpc even if we could have had a + * higher bpc. + */ +static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + /* + * We're making sure that we have headroom on the TMDS character + * clock to actually use 12bpc. + */ + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + +/* + * Test that if a driver supports higher bpc but the display only + * supports 8 bpc, we only end up with 8 bpc even if we could have had a + * higher bpc. + */ +static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx *ctx; + struct drm_connector_state *conn_state; + struct drm_display_info *info; + struct drm_display_mode *preferred; + unsigned long long rate; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_340mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + info = &conn->display_info; + KUNIT_ASSERT_TRUE(test, info->is_hdmi); + KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); + + ctx = drm_kunit_helper_acquire_ctx_alloc(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + /* + * We're making sure that we have headroom on the TMDS character + * clock to actually use 12bpc. + */ + rate = drm_connector_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); + KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = conn->state; + KUNIT_ASSERT_NOT_NULL(test, conn_state); + + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); + KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); +} + static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), @@ -1041,8 +1537,16 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate), + KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback), + KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), + KUNIT_CASE(drm_test_check_output_bpc_dvi), + KUNIT_CASE(drm_test_check_output_bpc_format_vic_1), + KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only), + KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only), + KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only), + KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only), KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc), KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc), KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc), diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h index 24f3377ef0f0..3e3527c58c31 100644 --- a/drivers/gpu/drm/tests/drm_kunit_edid.h +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -1,6 +1,64 @@ #ifndef DRM_KUNIT_EDID_H_ #define DRM_KUNIT_EDID_H_ +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ab + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * RGB color display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: none + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Checksum: 0xab + */ +const unsigned char test_edid_dvi_1080p[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab +}; + /* * edid-decode (hex): * @@ -103,6 +161,108 @@ const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = { 0x00, 0x00, 0x00, 0xd0 }; +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 + * + * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c + * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * Monochrome or grayscale display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x92 + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Native detailed modes: 1 + * Colorimetry Data Block: + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: No Data + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * Maximum TMDS clock: 340 MHz + * Extended HDMI video details: + * Checksum: 0xd0 Unused space in Extension Block: 100 bytes + */ +const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, + 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x00, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0 +}; + /* * edid-decode (hex): * From patchwork Mon Feb 12 13:13:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199773 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2424745dyd; Mon, 12 Feb 2024 05:26:07 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUBNgwdJeWZRo3ijW4TKby8oEMSco65bBv5ap6aiD3yqEDiUBB5E9eMJO1vbwS8OP/UJQiN31B6MnkdV9kyR1eTtqocRg== X-Google-Smtp-Source: AGHT+IEgfdfmQiHSmMmpM2XTfnxPZQjXTSAia+HnJOBHwiRrACs8+ER3hILAgM+QOlFyvlpDnRv4 X-Received: by 2002:a0c:f2ca:0:b0:68c:88fd:d926 with SMTP id c10-20020a0cf2ca000000b0068c88fdd926mr5354477qvm.56.1707744367352; Mon, 12 Feb 2024 05:26:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744367; cv=pass; d=google.com; s=arc-20160816; b=paUwnwUL5RDF6zzPsSgwy30VatKkZkEun0RTO2O0dGZOhY4e34z2RSYtJdw6b9T139 /kFDYBuwfzo6ZLafXIipKUWIiKYUrMbphRtiP+Eq/gkmc+1trFaxHL7V3kzHwA5KuS1y aWFKfJzsRRRvekryGIgWGfuFJTUNcjztb+DRU3TTLiBAw5TPrQGQRDtGH4xOYTX9ayjA 0yL8dcH+2CuFzjsE0BiOiaP5sUkyVviMvhOuHLlHfc9eyz2rTfZdWIzjdWIIUCNMl6BG aBnqE4W9uy6HvhUIz/sS4lIGIGd7n1dgO7WzFZKxD0TT9MsYSwt/ksbHDzHxTNGlESIX uwGQ== 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=+6G8q8cJd+rRClslwuFX0NEoq+rzt1+JnFAAMbT0SMM=; fh=yTimzOQ1f0MA9qNAYKsVlEwh52ddDse2ocpkVs3Jzsc=; b=1AoZ1x44ouezdR9hBSoZDfVxyG95PN5SH9D4kh4DkWz4p79GhV6z8jPwXYj7B4+JmH 5Dq2rWZS8BFy4JvrG9cQYhIOwvpRQ9h26X7IsODwLYxx4l0eGIncSTAaotdBmvxCCTj2 c9bx9vbUmuJS5PuHM6E9+Vk8IDejyYk8agz6VhZ5dCo1FqnwHH9v5coy2kSmbikcua6m Q0KSYne0Ziky/O7bydx9NIkFQtC36L6Q7KRn13y+Fb+7dDpqyzAFUopOFbBZK9m7uxog Ug3UJ03jUJ8T2raJ2AcS5P8siUxhR0QAGerLksJd2H9lC25Ehbhffp+Js2RMhw0Gp1k3 q3GA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tBgpPYLu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61648-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61648-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCW5ErtWPiPC1Yv+6sSH+m68mGwflDTA3sZbQKpvS9p2lRYUMOCZ3dLs5U1gdi7/P/2yw5U2pSPUD/7UsYTXLY5aVZ6s3Q== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id gg8-20020a056214252800b0068c8519a28esi356258qvb.398.2024.02.12.05.26.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:26:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61648-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tBgpPYLu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61648-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61648-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 173A21C213D0 for ; Mon, 12 Feb 2024 13:26:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2BF4E50249; Mon, 12 Feb 2024 13:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tBgpPYLu" 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 3C72D4D9EC; Mon, 12 Feb 2024 13:14:40 +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=1707743680; cv=none; b=XEOJ0QvyKLE5iZajeiks9RKCx7k77wZHZar+g1HQlAfaWDd3jl6pB5Pgdgktj/lGh+yKlKNPP0UQsp+dfO6eT+te9HJ8MSoVYHNtfSr0K57E9bksZ4kmB7JYX8ggJdaordtRD9vBPf+xNW3D63VS3cm9GQowZ//awrdQFNIrcpw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743680; c=relaxed/simple; bh=ilSdiTpxS72ehIqdgRqz/7h4rfeE2sVTVsnO5tq+T2k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NlSnCNCo91uzAjJ/twULLcxhM9qaEIXUQYDtFIXa5GlaxVBmnfRq9gfyAq9lfxmkQt/VzGdF1dq+8iQp3RnPGPaKi6G4xkDCIEDAl0kWdEFSzVjJUeUYJH/Qc1p36jzngGI/oJ+QZXEJaV0qkGs5Zh9JULC6ntxht0WluuWo7J4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tBgpPYLu; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 46223C43609; Mon, 12 Feb 2024 13:14:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743679; bh=ilSdiTpxS72ehIqdgRqz/7h4rfeE2sVTVsnO5tq+T2k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tBgpPYLuHFdElhkvyHq3IlpxHGWBJYO2f6HicH8W+qr6W0W0VAf//fSpv7R0vy1cB CEgcKiQ8e9XMpfaCEKEj7qxrgB93bleKMpe1P3FKsyD2JiVgwT/lyPqmCmZc4yF84e 19/o0Ow1l/QYwITbCOB7Oxdr3XWhJlbctl9+AygkllLWJN8fXFgIRSSZF4C7XyrrXQ TLJj4XIOziXCpWGT5GKjHbm2A2mtGMVxF1MJznTNN3b+jKM5hcoXb96tSPKegko8kr pa9FelSjUqVxRCf971iXYQU7OciKYbZfp4+xT066e/XFip7bA7xXmDhZOt0UdVM686 zK27kO7C4/DxA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:08 +0100 Subject: [PATCH v6 25/36] drm/connector: hdmi: Add Infoframes generation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-25-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=23834; i=mripard@kernel.org; h=from:subject:message-id; bh=ilSdiTpxS72ehIqdgRqz/7h4rfeE2sVTVsnO5tq+T2k=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJPMYcqVmzvCZdothyvl923hyq6v+n1wf7KR1RTOX3 2r2YZtPHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE9gQLk4BmAibOcNf6Xmqr5Zt51jy5Mak Pb/0M26rKOfHzvkgPl2S5+C/XrZprYwMfwynnehdd0BzW5naaosGh5XWDIEWdvP4+0+JWjPalt7 nAgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699757669797531 X-GMAIL-MSGID: 1790699757669797531 Infoframes in KMS is usually handled by a bunch of low-level helpers that require quite some boilerplate for drivers. This leads to discrepancies with how drivers generate them, and which are actually sent. Now that we have everything needed to generate them in the HDMI connector state, we can generate them in our common logic so that drivers can simply reuse what we precomputed. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 327 +++++++++++++++++++++ drivers/gpu/drm/drm_connector.c | 16 + .../gpu/drm/tests/drm_atomic_state_helper_test.c | 1 + drivers/gpu/drm/tests/drm_connector_test.c | 12 + include/drm/drm_atomic_state_helper.h | 8 + include/drm/drm_connector.h | 133 +++++++++ 7 files changed, 498 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 872edb47bb53..ad9c467e20ce 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -99,6 +99,7 @@ config DRM_KUNIT_TEST config DRM_KMS_HELPER tristate depends on DRM + select DRM_DISPLAY_HDMI_HELPER help CRTC helpers for KMS drivers. diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 67fb9dd2e41e..82650ba46a4a 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -38,6 +38,8 @@ #include #include +#include + #include #include @@ -906,6 +908,142 @@ hdmi_compute_config(const struct drm_connector *connector, return -EINVAL; } +static int hdmi_generate_avi_infoframe(const struct drm_connector *connector, + struct drm_connector_state *state) +{ + const struct drm_display_mode *mode = + connector_state_get_mode(state); + struct drm_connector_hdmi_infoframe *infoframe = + &state->hdmi.infoframes.avi; + struct hdmi_avi_infoframe *frame = + &infoframe->data.avi; + bool is_full_range = state->hdmi.is_full_range; + enum hdmi_quantization_range rgb_quant_range = + is_full_range ? HDMI_QUANTIZATION_RANGE_FULL : HDMI_QUANTIZATION_RANGE_LIMITED; + int ret; + + ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode); + if (ret) + return ret; + + frame->colorspace = state->hdmi.output_format; + + drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range); + drm_hdmi_avi_infoframe_colorimetry(frame, state); + drm_hdmi_avi_infoframe_bars(frame, state); + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_spd_infoframe(const struct drm_connector *connector, + struct drm_connector_state *state) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &state->hdmi.infoframes.spd; + struct hdmi_spd_infoframe *frame = + &infoframe->data.spd; + int ret; + + ret = hdmi_spd_infoframe_init(frame, + connector->hdmi.vendor, + connector->hdmi.product); + if (ret) + return ret; + + frame->sdi = HDMI_SPD_SDI_PC; + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector, + struct drm_connector_state *state) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &state->hdmi.infoframes.hdr_drm; + struct hdmi_drm_infoframe *frame = + &infoframe->data.drm; + int ret; + + if (connector->max_bpc < 10) + return 0; + + if (!state->hdr_output_metadata) + return 0; + + ret = drm_hdmi_infoframe_set_hdr_metadata(frame, state); + if (ret) + return ret; + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector, + struct drm_connector_state *state) +{ + const struct drm_display_mode *mode = + connector_state_get_mode(state); + struct drm_connector_hdmi_infoframe *infoframe = + &state->hdmi.infoframes.hdmi; + struct hdmi_vendor_infoframe *frame = + &infoframe->data.vendor.hdmi; + int ret; + + ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode); + if (ret) { + if (ret == -EINVAL) + return 0; + + return ret; + } + + infoframe->set = true; + + return 0; +} + +static int +hdmi_generate_infoframes(const struct drm_connector *connector, + struct drm_connector_state *state) +{ + const struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + if (!info->has_hdmi_infoframe) + return 0; + + ret = hdmi_generate_avi_infoframe(connector, state); + if (ret) + return ret; + + ret = hdmi_generate_spd_infoframe(connector, state); + if (ret) + return ret; + + /* + * Audio Infoframes will be generated by ALSA, and updated by + * drm_atomic_helper_connector_hdmi_update_audio_infoframe(). + */ + + ret = hdmi_generate_hdr_infoframe(connector, state); + if (ret) + return ret; + + ret = hdmi_generate_hdmi_vendor_infoframe(connector, state); + if (ret) + return ret; + + return 0; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -935,6 +1073,10 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, if (ret) return ret; + ret = hdmi_generate_infoframes(connector, new_state); + if (ret) + return ret; + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb || old_state->hdmi.output_bpc != new_state->hdmi.output_bpc || old_state->hdmi.output_format != new_state->hdmi.output_format) { @@ -952,6 +1094,191 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); +#define HDMI_MAX_INFOFRAME_SIZE 29 + +static int clear_device_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + + if (!funcs || !funcs->clear_infoframe) + return 0; + + return funcs->clear_infoframe(connector, type); +} + +static int clear_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *conn_frame, + struct drm_connector_hdmi_infoframe *old_frame) +{ + int ret; + + ret = clear_device_infoframe(connector, old_frame->data.any.type); + if (ret) + return ret; + + memset(old_frame, 0, sizeof(*old_frame)); + + return 0; +} + +static int write_device_infoframe(struct drm_connector *connector, + union hdmi_infoframe *frame) +{ + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + u8 buffer[HDMI_MAX_INFOFRAME_SIZE]; + int len; + + if (!funcs || !funcs->write_infoframe) + return -ENOSYS; + + len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); + if (len < 0) + return len; + + return funcs->write_infoframe(connector, frame->any.type, buffer, len); +} + +static int write_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *conn_frame, + struct drm_connector_hdmi_infoframe *new_frame) +{ + int ret; + + ret = write_device_infoframe(connector, &new_frame->data); + if (ret) + return ret; + + if (conn_frame) + memcpy(conn_frame, new_frame, sizeof(*conn_frame)); + + return 0; +} + +static int write_or_clear_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *conn_frame, + struct drm_connector_hdmi_infoframe *old_frame, + struct drm_connector_hdmi_infoframe *new_frame) +{ + if (new_frame->set) + return write_infoframe(connector, conn_frame, new_frame); + + if (old_frame->set && !new_frame->set) + return clear_infoframe(connector, conn_frame, old_frame); + + return 0; +} + +#define UPDATE_INFOFRAME(c, os, ns, i) \ + write_or_clear_infoframe(c, \ + &(c)->hdmi.infoframes.i, \ + &(os)->hdmi.infoframes.i, \ + &(ns)->hdmi.infoframes.i) + +/** + * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes + * @connector: A pointer to the HDMI connector + * @state: The HDMI connector state to generate the infoframe from + * + * This function is meant for HDMI connector drivers to write their + * infoframes. It will typically be used in a + * @drm_connector_helper_funcs.atomic_enable implementation. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + struct drm_connector_state *old_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_state = + drm_atomic_get_new_connector_state(state, connector); + struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + if (!info->has_hdmi_infoframe) + return 0; + + mutex_lock(&connector->hdmi.infoframes.lock); + + ret = UPDATE_INFOFRAME(connector, old_state, new_state, avi); + if (ret) + goto out; + + if (connector->hdmi.infoframes.audio.set) { + ret = write_infoframe(connector, + NULL, + &connector->hdmi.infoframes.audio); + if (ret) + goto out; + } + + ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdr_drm); + if (ret) + goto out; + + ret = UPDATE_INFOFRAME(connector, old_state, new_state, spd); + if (ret) + goto out; + + ret = UPDATE_INFOFRAME(connector, old_state, new_state, hdmi); + if (ret) + goto out; + +out: + mutex_unlock(&connector->hdmi.infoframes.lock); + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes); + +#undef UPDATE_INFOFRAME +#undef UPDATE_INFOFRAME_TOGGLE + +/** + * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe + * @connector: A pointer to the HDMI connector + * @frame: A pointer to the audio infoframe to write + * + * This function is meant for HDMI connector drivers to update their + * audio infoframe. It will typically be used in one of the ALSA hooks + * (most likely prepare). + * + * Returns: + * Zero on success, error code on failure. + */ +int +drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, + struct hdmi_audio_infoframe *frame) +{ + struct drm_connector_hdmi_infoframe infoframe = {}; + struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + if (!info->has_hdmi_infoframe) + return 0; + + memcpy(&infoframe.data, frame, sizeof(infoframe.data)); + infoframe.set = true; + + mutex_lock(&connector->hdmi.infoframes.lock); + + ret = write_infoframe(connector, + &connector->hdmi.infoframes.audio, + &infoframe); + + mutex_unlock(&connector->hdmi.infoframes.lock); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); + /** * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state * @connector: connector object diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index a4466a79421e..7941df99bf85 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -456,6 +456,8 @@ EXPORT_SYMBOL(drmm_connector_init); * drmm_connector_hdmi_init - Init a preallocated HDMI connector * @dev: DRM device * @connector: A pointer to the HDMI connector to init + * @vendor: HDMI Controller Vendor name + * @product: HDMI Controller Product name * @funcs: callbacks for this connector * @hdmi_funcs: HDMI-related callbacks for this connector * @connector_type: user visible type of the connector @@ -476,6 +478,7 @@ EXPORT_SYMBOL(drmm_connector_init); */ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, + const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, @@ -485,6 +488,13 @@ int drmm_connector_hdmi_init(struct drm_device *dev, { int ret; + if (!vendor || !product) + return -EINVAL; + + if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) || + (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN)) + return -EINVAL; + if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA || connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; @@ -500,6 +510,12 @@ int drmm_connector_hdmi_init(struct drm_device *dev, return ret; connector->hdmi.supported_formats = supported_formats; + strtomem_pad(connector->hdmi.vendor, vendor, 0); + strtomem_pad(connector->hdmi.product, product, 0); + + ret = drmm_mutex_init(dev, &connector->hdmi.infoframes.lock); + if (ret) + return ret; /* * drm_connector_attach_max_bpc_property() requires the 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 860e34b00fee..1eaa83af9dd0 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -203,6 +203,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, conn = &priv->connector; ret = drmm_connector_hdmi_init(drm, conn, + "Vendor", "Product", &dummy_connector_funcs, &dummy_connector_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 6a3651b08c81..b9c80d282380 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -189,6 +189,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -208,6 +209,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -227,6 +229,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -246,6 +249,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -269,6 +273,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -304,6 +309,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -339,6 +345,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -370,6 +377,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -389,6 +397,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -409,6 +418,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, connector_type, @@ -443,6 +453,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, connector_type, @@ -708,6 +719,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index d59d2b3aef9a..22f083968aa8 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -40,6 +40,8 @@ struct drm_private_state; struct drm_modeset_acquire_ctx; struct drm_device; +struct hdmi_audio_infoframe; + void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state, struct drm_crtc *crtc); void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, @@ -88,6 +90,12 @@ void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state); + +int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, + struct hdmi_audio_infoframe *frame); +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, + struct drm_atomic_state *state); + void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3eaf4d54364d..5964ef283022 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -914,6 +914,21 @@ struct drm_tv_connector_state { unsigned int hue; }; +/** + * struct drm_connector_hdmi_infoframe - HDMI Infoframe container + */ +struct drm_connector_hdmi_infoframe { + /** + * @data: HDMI Infoframe structure + */ + union hdmi_infoframe data; + + /** + * @set: Is the content of @data valid? + */ + bool set; +}; + /** * struct drm_connector_state - mutable connector state */ @@ -1070,6 +1085,35 @@ struct drm_connector_state { */ enum drm_hdmi_broadcast_rgb broadcast_rgb; + /** + * @infoframes: HDMI Infoframes matching that state + */ + struct { + /** + * @avi: AVI Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe avi; + + /** + * @hdr_drm: DRM (Dynamic Range and Mastering) + * Infoframes structure matching our state. + */ + struct drm_connector_hdmi_infoframe hdr_drm; + + /** + * @spd: SPD Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe spd; + + /** + * @vendor: HDMI Vendor Infoframes structure + * matching our state. + */ + struct drm_connector_hdmi_infoframe hdmi; + } infoframes; + /** * @is_full_range: Is the output supposed to use a full * RGB Quantization Range or not? @@ -1115,6 +1159,41 @@ struct drm_connector_hdmi_funcs { (*tmds_char_rate_valid)(const struct drm_connector *connector, const struct drm_display_mode *mode, unsigned long long tmds_rate); + + /** + * @clear_infoframe: + * + * This callback is invoked through + * @drm_atomic_helper_hdmi_connector_update_infoframes during a + * commit to clear the infoframes into the hardware. It will be + * called multiple times, once for every disabled infoframe + * type. + * + * The @clear_infoframe callback is optional. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*clear_infoframe)(struct drm_connector *connector, + enum hdmi_infoframe_type type); + + /** + * @write_infoframe: + * + * This callback is invoked through + * @drm_atomic_helper_hdmi_connector_update_infoframes during a + * commit to program the infoframes into the hardware. It will + * be called multiple times, once for every updated infoframe + * type. + * + * The @write_infoframe callback is mandatory. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*write_infoframe)(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len); }; /** @@ -1986,6 +2065,18 @@ struct drm_connector { * @hdmi: HDMI-related variable and properties. */ struct { +#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8 + /** + * @vendor: HDMI Controller Vendor Name + */ + unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring; + +#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16 + /** + * @product: HDMI Controller Product Name + */ + unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring; + /** * @supported_formats: Bitmask of @hdmi_colorspace * supported by the controller. @@ -1996,6 +2087,47 @@ struct drm_connector { * @funcs: HDMI connector Control Functions */ const struct drm_connector_hdmi_funcs *funcs; + + /** + * @infoframes: Current Infoframes output by the connector + */ + struct { + /** + * @lock: Mutex protecting against concurrent access to + * the infoframes, most notably between KMS and ALSA. + */ + struct mutex lock; + + /** + * @audio: Current Audio Infoframes structure. Protected + * by @lock. + */ + struct drm_connector_hdmi_infoframe audio; + + /** + * @avi: Current AVI Infoframes structure. Protected by + * @lock. + */ + struct drm_connector_hdmi_infoframe avi; + + /** + * @hdr_drm: Current DRM (Dynamic Range and Mastering) + * Infoframes structure. Protected by @lock. + */ + struct drm_connector_hdmi_infoframe hdr_drm; + + /** + * @spd: Current SPD Infoframes structure. Protected by + * @lock. + */ + struct drm_connector_hdmi_infoframe spd; + + /** + * @vendor: Current HDMI Vendor Infoframes structure. + * Protected by @lock. + */ + struct drm_connector_hdmi_infoframe hdmi; + } infoframes; } hdmi; }; @@ -2017,6 +2149,7 @@ int drmm_connector_init(struct drm_device *dev, struct i2c_adapter *ddc); int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, + const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, From patchwork Mon Feb 12 13:13:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199772 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2424715dyd; Mon, 12 Feb 2024 05:26:03 -0800 (PST) X-Google-Smtp-Source: AGHT+IGkTpZigwpvrooELfojKBiBh1yeizFzMfpLuPpKayaideltmtFCXnat/REnXKf4ERJmo1np X-Received: by 2002:a17:902:f68e:b0:1d9:859f:b505 with SMTP id l14-20020a170902f68e00b001d9859fb505mr6346271plg.21.1707744363187; Mon, 12 Feb 2024 05:26:03 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744363; cv=pass; d=google.com; s=arc-20160816; b=RMbxO2VQl156RGfZgZ+oz/4mTvADXUTPQVNNNA7YggcdBR5cVRnsObVRRQuO2zWpxk jcHTn3uaMzQvGPbhjtysPo5/mPpcX4SUKL2mJOcR2r7OBIo3yrbJ3AVSOJ2XHu/ea8OB 3mUMXF4gAy8ovqAmLdyQJTNzRdQUMxztkRmHTnXllzGTNYqqJrPGHj9G9KcWqqu7MF2I Ukx6NY0J+/ZMbOEjHe8xJ4vV2Bt9vhs+k5f43guz2rQkFWfulfMEGaeNiWnNDRLGlQqT 6zCqFT02Z6j5OEd86+n9BsueRD+w4PPfI5JgEJexdN2HZMXAeLXj/L63q4jjg6pdmTr0 H/ew== 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=L4emCTrgQEV0TWb+VInxqw3u49zA3xbFHcNjp0hdy4c=; fh=ux0l1dn9Zpg/QuQwRtJjb1NQhtNWrdvQydARj9jb5N4=; b=qN35JaoZo2XaROFLFeFWAhgpDkso6tb1G1fTXnftsQ/gH8AP7NAmt6tnLMSek4jBbR FxyHTz05DGpjVtQhq9tnfY9SJZsLIsXU6myGf80qHEmkwXXR6TesUz+m316sRfMixceg cDTdSwIvddVuRAyQgpRjc4g3YCAyx3eANkjix1W+qLi9jZebX4HgRottvKqbZkNKZHwm glO3a6Wya1ckgpwd7CJ0EQcLZO0+/uJdC4kbLDOKStJ8SeDb4qUglis29SX1GNcLH04x O6ciPmtRi1zjzT+muv/HJAy4Y9TfseaCplMhfBMTiVwzx4H2chhNhvtPUr+L8iv/QExD 251Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="hZHM1/Y/"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61651-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61651-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCU/7YJz6izIwH9tYLufIRy4o+PiOU7Hfs8WhLanIyjM4MibI90Nk2giF72EZU9SJq1IeiSieSuQco14qtVHdRXBt3YBPw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id i17-20020a170902eb5100b001d4beb54473si229674pli.608.2024.02.12.05.26.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:26:03 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61651-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="hZHM1/Y/"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61651-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61651-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 D7FFD28B002 for ; Mon, 12 Feb 2024 13:26:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E7EFC4F8BC; Mon, 12 Feb 2024 13:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hZHM1/Y/" 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 82C084EB3C; Mon, 12 Feb 2024 13:14:43 +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=1707743683; cv=none; b=ew2gh34SIMy938qdpUOg6jL7/z+JIgRdyfrOBBcCm8jD3jsWl3XMMSho8Gr5KF4WgQAD1ho4q2jz9Lk8AGZSYuR7mIgCYzETyXXooAgqyXZseKGhNRl6lrpJXu6tTlfSEoGb8INqIBYJOSoQzxofBrggnUBmPMOCZs9vvaEjdys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743683; c=relaxed/simple; bh=IVSHDl4cjCeykLbWUFJ4biJKnyiAeL4Zfa9XQY6iuNk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iQOJbBBowRAKZHRkN5Hz010ykGBoCkAKDJ9n+w2+uPEG0UYJoGFJtirp8Ry1X9jqFZzr5WCSuESEjb6Q1XLve+xyigXstryTKUHzwvnEvlfxQeZqwCuW80OGQHaNbv739+/xmzLdTvAupFqfwheUXu1neta2qaJfmwwZlw6J+Bs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hZHM1/Y/; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 767C3C4AF1E; Mon, 12 Feb 2024 13:14:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743683; bh=IVSHDl4cjCeykLbWUFJ4biJKnyiAeL4Zfa9XQY6iuNk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hZHM1/Y/Qhm3Jc86nlf8RRdGpE846KResz9eq4OveOzuwv+XLZGCnA5GcxbQeYqx/ 4kKuDV4ATCZ8JedYawHybcengyla17eCeg1F7dcFxOx5CTTqAb/HFkKeVkK//BVwis w4u9R+E6FOBmegg5OpzqR3dtxCk9HjEVPF0dyrpT0Q6DONnGX5YMiXgDZ9AeY+F5P3 Yc9Ui4XyhB9GZeWpcR7Q8cicYrXWudsJ9k+4Vlq2FPgzs0UhgQlzXGtJvDYCd3Roug gjnWIMxCPhM+mTF7/3JkerSWiVyepf/IAkJLcrlUbLfPP9N+FhgT5VTstZBMPgUWvT EnOwHGVXY5/yA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:09 +0100 Subject: [PATCH v6 26/36] drm/tests: Add infoframes test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-26-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8417; i=mripard@kernel.org; h=from:subject:message-id; bh=IVSHDl4cjCeykLbWUFJ4biJKnyiAeL4Zfa9XQY6iuNk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJPNK6g+/DRJIMi3oTKjK0BU3fvPq/ZyEgm91u00M7 4uqMTt2lLIwiHExyIopssQImy+JOzXrdScb3zyYOaxMIEMYuDgFYCJhpxkZlqRt0JFYvaPSq9ij 8qISU17GsUMpOz+lV/C52nNVVDx+ysgw+1mZSpVzrlzUt9sJO9e8OjBrm+LfdZc+NVzwV8v+bMT PCAA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699753540074300 X-GMAIL-MSGID: 1790699753540074300 The previous patch added the generation of the infoframes matching an HDMI connector state. Let's add a few tests to make sure it works as expected. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/tests/drm_connector_test.c | 219 +++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index b9c80d282380..07066b704b36 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -219,6 +219,217 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) KUNIT_EXPECT_EQ(test, ret, 0); } +/* + * Test that the registration of an HDMI connector with a NULL vendor + * fails. + */ +static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + NULL, "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of an HDMI connector with a NULL product + * fails. + */ +static void drm_test_connector_hdmi_init_null_product(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", NULL, + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of a connector with a valid, shorter than + * the max length, product name succeeds, and is stored padded with 0. + */ +static void drm_test_connector_hdmi_init_product_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { + 'P', 'r', 'o', 'd', + }; + const char *product_name = "Prod"; + int ret; + + KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", product_name, + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_MEMEQ(test, + priv->connector.hdmi.product, + expected_product, + sizeof(priv->connector.hdmi.product)); +} + +/* + * Test that the registration of a connector with a valid, at max + * length, product name succeeds, and is stored padded without any + * trailing \0. + */ +static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { + 'P', 'r', 'o', 'd', 'u', 'c', 't', + 'P', 'r', 'o', 'd', 'u', 'c', 't', + 'P', 'r', + }; + const char *product_name = "ProductProductPr"; + int ret; + + KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", product_name, + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_MEMEQ(test, + priv->connector.hdmi.product, + expected_product, + sizeof(priv->connector.hdmi.product)); +} + +/* + * Test that the registration of a connector with a product name larger + * than the maximum length fails. + */ +static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const char *product_name = "ProductProductProduct"; + int ret; + + KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", product_name, + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of a connector with a vendor name smaller + * than the maximum length succeeds, and is stored padded with zeros. + */ +static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { + 'V', 'e', 'n', 'd', + }; + const char *vendor_name = "Vend"; + int ret; + + KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + vendor_name, "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_MEMEQ(test, + priv->connector.hdmi.vendor, + expected_vendor, + sizeof(priv->connector.hdmi.vendor)); +} + +/* + * Test that the registration of a connector with a vendor name at the + * maximum length succeeds, and is stored padded without the trailing + * zero. + */ +static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { + 'V', 'e', 'n', 'd', 'o', 'r', + 'V', 'e', + }; + const char *vendor_name = "VendorVe"; + int ret; + + KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + vendor_name, "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_MEMEQ(test, + priv->connector.hdmi.vendor, + expected_vendor, + sizeof(priv->connector.hdmi.vendor)); +} + +/* + * Test that the registration of a connector with a vendor name larger + * than the maximum length fails. + */ +static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const char *vendor_name = "VendorVendor"; + int ret; + + KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + vendor_name, "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_EXPECT_LT(test, ret, 0); +} + /* * Test that the registration of a connector with an invalid maximum bpc * count fails. @@ -499,6 +710,14 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = { KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), + KUNIT_CASE(drm_test_connector_hdmi_init_null_product), + KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor), + KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact), + KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long), + KUNIT_CASE(drm_test_connector_hdmi_init_product_valid), + KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact), + KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long), + KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid), KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, drm_connector_hdmi_init_type_valid_gen_params), KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, From patchwork Mon Feb 12 13:13:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199774 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2424902dyd; Mon, 12 Feb 2024 05:26:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IFvNEec8q7kbPPxVdCqDojxZumxsR8e3M0AWnkorLqZchVb7sjF5LuJrMZutNtwu+ztz8yK X-Received: by 2002:a92:d14e:0:b0:363:c5bc:3c5c with SMTP id t14-20020a92d14e000000b00363c5bc3c5cmr7304543ilg.29.1707744381287; Mon, 12 Feb 2024 05:26:21 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744381; cv=pass; d=google.com; s=arc-20160816; b=w7QY8R+4ycH6cMpu7Y8mw2Z7H65s5o4GfspmzF6ElX9Qb0xUJKfTERrbb6nIM8KEeC rTnNBmbjtRYTdQ8UdEdINueLVC5uL/nqOrCgQCo7zSmsDZainZfGoikAMlBlwa5+0aFA nQV8I006yhxE+Sm0+ETjErH1X9wTPOEZPh7bncdIlRzAy9Cu4fdRX9r+6KVbO7+zOE1T 7EDsv63m3ASru0zGnNOirmC0Hw/8IkWRTDSAruvK3Z9gBspefvLbkbvb1ANhQQFPN3G9 w2/gqGLIiwByx3S6RUW1xtQppvPLWojpvFKryfuUoPEJkXTZ3UO34r77OMSXG3ODjo3H CVsQ== 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=NZiRwbcs8+s+igy5MROyL2qq2lymr2B3rTgHV+/FhDY=; fh=afdp3un27G8NeGGrZYfhefbqGk+Tmc+tsSYk2IMjYus=; b=SGEnZ5wVPLsG+Waw8m19a63XVojAv57WZyiUqvVU3Z1xLzxLC1BuPArIvM0sPGwuu5 pimIAIsoDpAemDJ/DotifulczLthLJ9FmkE9EvSPJPb9oFMLhPJNrwr6Ai/8lmqcnwiV e//0SY6YAvpfhQDqDuWg+xUoSw68IiR+RVSe35dTqu05lKHJR1qM60rfjFNhsg66hReI 2cPcq1sYT25VaCjgSpnHBx8QML/k6WAzizpqR5ozcdNooVYkIp6KAN+OQMMfPyJ+/xrP tM3gtWBFPbo66kjbW8V+UC7Kg3qt4pIO/c4HReZOJ/kOkiMzo9U3qrvdWDKEZm5FZXav a0Yw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RogV7WOE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61652-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61652-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWiNrl6cQBy1noRNzsgtF+W37zRXsn90OTa1ck6ILu5qDrcTOrM8Clz6e2sZwm3qUDMLVhFO8m2JCU8EvqRrHmhe4uC3A== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id f26-20020a63381a000000b005dbcf1044c0si258799pga.57.2024.02.12.05.26.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:26:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61652-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RogV7WOE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61652-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61652-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 0E51E28B03B for ; Mon, 12 Feb 2024 13:26:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B25F50246; Mon, 12 Feb 2024 13:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RogV7WOE" 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 A97C64F61D; Mon, 12 Feb 2024 13:14:46 +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=1707743686; cv=none; b=QTwWvewoP5Tud8750ZWKfdv2LstUkHmPi8MQBWtGfsoiAuLaO8507WnIov+vlwAYDlWjeXzkCi07mGseJO83NBUT6suqYJYPpWtV3s1uh2Yg086wKdMkEWp3iqKl8fd/f0EqnSbWSnzm38lK5uJbboP9Q5IXHaOciTAlENbgpdA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743686; c=relaxed/simple; bh=Vk3XPPaEA+7bLaeUH3Fr8CFJ1pQDdSi7lf6Rme2EfCY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H4tbkXHXYxjc+No3PCwxtSGX2/8m7YuV6xuJDnKA2h3ogii5tBhmZTiZj9cZL3wpnfCr9fXoPqcymhePl/BAM/zVZs6s8tHP4opT3E0ZFUU2ReKvpklEx30+a2aIANEwbf0HiP2oU4FTjG7LfCvd4l6zN1qpDXcD0vTX2bvplIg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RogV7WOE; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9A012C433C7; Mon, 12 Feb 2024 13:14:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743686; bh=Vk3XPPaEA+7bLaeUH3Fr8CFJ1pQDdSi7lf6Rme2EfCY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RogV7WOEShx13Aw6nqQSBmmmI0wc06MHPjtbRBOD7lM5XZSIr7QHlRtYt0h6n1xus xwa1jsm3pKnZ2/De7JeebQNOt//DoB56/gQ7U/NciXe++D8dU1d7BEFMeK/fhf9fxo kdYYcCeL/Fl4dA0lXrJ/IdDFIOv7tdibybnPfV12S1GZfpB8mMn0eE8eXaJRC/eYN6 kyq5RGwwJPH3FP6Rcab7phXE9LqSQH02iRPGoDn3wsygyrgYP2qlI+tMbXNkRKjt6D bgsmYci7RF8Eqg25sAupcVgz2JdgV15KSs83IFKqzb1mgdHJZENXmyzileElPlspti jJbECfiOETKkQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:10 +0100 Subject: [PATCH v6 27/36] drm/connector: hdmi: Create Infoframe DebugFS entries Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-27-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4158; i=mripard@kernel.org; h=from:subject:message-id; bh=Vk3XPPaEA+7bLaeUH3Fr8CFJ1pQDdSi7lf6Rme2EfCY=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJPP11ppbqQt9Zlpj2iT4KZxn6d85Wu2XueUiEp/kc QkunC3XUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIms28fwzzpi9/3Tl/qZxTfd MGrcWVVz+EOQ5lXL+HP5ZsHby2Y/k2Jk2H/UKiVL/gyT7v4quXPv35b8b/jhui9q3qeqgzbvuN/ 3MwIA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699771995579125 X-GMAIL-MSGID: 1790699771995579125 There has been some discussions recently about the infoframes sent by drivers and if they were properly generated. In parallel, there's been some interest in creating an infoframe-decode tool similar to edid-decode. Both would be much easier if we were to expose the infoframes programmed in the hardware. It won't be perfect since we have no guarantee that it's actually what goes through the wire, but it's the best we can do. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_debugfs.c | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 08fcefd804bc..160389f3d84b 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -520,6 +520,114 @@ static const struct file_operations drm_connector_fops = { .write = connector_write }; +struct debugfs_wrapper { + struct drm_connector *connector; + struct drm_connector_hdmi_infoframe *frame; +}; + +#define HDMI_MAX_INFOFRAME_SIZE 29 + +static ssize_t +infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) +{ + const struct debugfs_wrapper *wrapper = filp->private_data; + struct drm_connector *connector = wrapper->connector; + struct drm_connector_hdmi_infoframe *infoframe = wrapper->frame; + union hdmi_infoframe *frame = &infoframe->data; + u8 buf[HDMI_MAX_INFOFRAME_SIZE]; + ssize_t len = 0; + + mutex_lock(&connector->hdmi.infoframes.lock); + + if (!infoframe->set) + goto out; + + len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); + if (len < 0) + goto out; + + len = simple_read_from_buffer(ubuf, count, ppos, buf, len); + +out: + mutex_unlock(&connector->hdmi.infoframes.lock); + return len; +} + +static const struct file_operations infoframe_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = infoframe_read, +}; + +static int create_hdmi_infoframe_file(struct drm_connector *connector, + struct dentry *parent, + const char *filename, + struct drm_connector_hdmi_infoframe *frame) +{ + struct drm_device *dev = connector->dev; + struct debugfs_wrapper *wrapper; + struct dentry *file; + + wrapper = drmm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL); + if (!wrapper) + return -ENOMEM; + + wrapper->connector = connector; + wrapper->frame = frame; + + file = debugfs_create_file(filename, 0400, parent, wrapper, &infoframe_fops); + if (IS_ERR(file)) + return PTR_ERR(file); + + return 0; +} + +#define CREATE_HDMI_INFOFRAME_FILE(c, p, i) \ + create_hdmi_infoframe_file(c, p, #i, &(c)->hdmi.infoframes.i) + +static int create_hdmi_infoframe_files(struct drm_connector *connector, + struct dentry *parent) +{ + int ret; + + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio); + if (ret) + return ret; + + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi); + if (ret) + return ret; + + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdr_drm); + if (ret) + return ret; + + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd); + if (ret) + return ret; + + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, hdmi); + if (ret) + return ret; + + return 0; +} + +static void hdmi_debugfs_add(struct drm_connector *connector) +{ + struct dentry *dir; + + if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) + return; + + dir = debugfs_create_dir("infoframes", connector->debugfs_entry); + if (IS_ERR(dir)) + return; + + create_hdmi_infoframe_files(connector, dir); +} + void drm_debugfs_connector_add(struct drm_connector *connector) { struct drm_device *dev = connector->dev; @@ -547,6 +655,8 @@ void drm_debugfs_connector_add(struct drm_connector *connector) debugfs_create_file("output_bpc", 0444, root, connector, &output_bpc_fops); + hdmi_debugfs_add(connector); + if (connector->funcs->debugfs_init) connector->funcs->debugfs_init(connector, root); } From patchwork Mon Feb 12 13:13:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199777 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425489dyd; Mon, 12 Feb 2024 05:27:37 -0800 (PST) X-Google-Smtp-Source: AGHT+IEnGRtW0i44SkYvXDV4fwG9DoGNXN7xgPrerBA40OksIMunyNMMJZhbe613iS3pAT7kvcp+ X-Received: by 2002:a05:6a20:9d8f:b0:19e:2d00:10c6 with SMTP id mu15-20020a056a209d8f00b0019e2d0010c6mr12263653pzb.23.1707744456766; Mon, 12 Feb 2024 05:27:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744456; cv=pass; d=google.com; s=arc-20160816; b=b6XZvQ1z95wQxjtjKBgmDaAozS4JrOOubJ14PCZ9OF536IUZLxtJQ9wY0IgQioIoF/ HvrdA+mYJ/6zQPmdDI/uqjQgVITbgF/wlSVFx7DYg6r5fqPlqzRF0qyjeuTqpndJ5nca jQocBhxm62Ea3jd7i/KtfhLqyhMwS6KdyrBjGxRlyG8NzZNBhpTXFmy8RdZ80cC92gqv Bb1rxCT8hOH3bBxgqIJ3GpPqyOPjaP+6SPmvR+MFN1dU5/3pFMAbxcV72cf6uhkfy2wY vc7+q58Kje8Q+8T2WVd+80yNQlucwh2wSdjbZ1USrtAvd67g/E8A5B1rNVWNEPwWymR1 qpSA== 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=E2DopS4memW3JEh9R0LOqfwO58T70kLBiF0aR3Uq7iQ=; fh=3YsWHUJ9iE2AwokMY/UTWanpGBz7303RMglQ35mCa+w=; b=n1feWtPEggKBCy93FzmJGwnR0W30E7abG4adw0kMORorPc6T5/n+Y4aWxvOMgZl4Vd A41yQS95m0k32mtI3wpw8uWedWbyxo5ZSyom3r38ngcz9VEurb9zIXydTPhZGWTCMI7+ 9bJajqagUcGol+KRk/q4lsRpgGL3vyqyEvSlQGCswmNQs0oMrIxelr2PoMKkuKL+TvNO JtId6OkJj8ayv4AXL7WYRodqEEjYuFx1Tfg/jkRjNzYsUHz8iKSBRRlYFvXOKMkuPxLg aM52xOL1zMhKzaS9FOb/TjFw9D/2IrTO7AVaMOJzAuDZYaGQAFK2H3QKSCULB6UfvMD1 M8Gw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="YdM2bC/M"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61653-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61653-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCUVF7+a7FVzTsz69vBtOLQulA1HIsahrHIBGRJEQB53K9XX23Q6/Q3/RnDeDDButizMGfgzxchCmB1SiIPd6NAB9pvaIA== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id o23-20020a637e57000000b005d5c89bd684si243758pgn.414.2024.02.12.05.27.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:27:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61653-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="YdM2bC/M"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61653-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61653-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 7A97328B05C for ; Mon, 12 Feb 2024 13:27:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7578D52F67; Mon, 12 Feb 2024 13:14:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YdM2bC/M" 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 BEA6450A96; Mon, 12 Feb 2024 13:14:49 +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=1707743689; cv=none; b=FxhViSW8kmp3r5lgQeD+Mp/TD8qtf7oN+o3a+QsbWtgywju/6RLXBqMZ1oUhM8j6dBePOmuKv7q7R081QHkhDGl8xkGtB3qQsCnH1c/XHYDPc/HQHSjmmQwd78HWJB9G39+6IcygPCx0pDbPk3pV9wjVl5ZJ4AAZept2eieg9NM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743689; c=relaxed/simple; bh=lgw2KUoAzsW+3Aj6sUJ3M/0HKEmzaXUprOtSNswzTTc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RYBm7HpjCwH9eY1hx2YRqXTRMV9QaOJORmb1xlJPSoQJb6v/Q4xNeMb6qrFI9hKdq3fN2/aS0wRlvZr/Y55LF6JNzowMDv9Z2N52dezQCMr8xbsjM1c6c+4tk9dzKBP8VXg9ewrj2NGGL/IZOYDBI3TuCHZVCcpvy8T6jcD2Kqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YdM2bC/M; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6F2DC433F1; Mon, 12 Feb 2024 13:14:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743689; bh=lgw2KUoAzsW+3Aj6sUJ3M/0HKEmzaXUprOtSNswzTTc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YdM2bC/MsduXrTbkV+YELkwrM53KO7JEAS3LgutjjjzVR5uUbXTm1so2reRGBJkKW WToaAp4JJnY4BEJoj8tIgZ2XtNq04qGyu5k0Bpvh9YZd85IkpHViC61uoVE1vVzKbo fvsop1UPGDjNVw5/G9EwsI37WYuVupPFKzG/FJ3wxZ+CFeWMVp/DTWqCuuCQ3if+zc jFfW7dC13NJuiEZS7jpWfKGaAo7k24on3Xv1FsmC6f7GQGrv+LPg2wres8/uzudsT4 r77MbEWDKtrHl+Ah/DSWJRljfdaURSgnvKcs5n+TKMaSPivXshblgoKKp3EaxGKQDo qQbo1Zp4H2asw== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:11 +0100 Subject: [PATCH v6 28/36] drm/vc4: hdmi: Switch to HDMI connector Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-28-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=37748; i=mripard@kernel.org; h=from:subject:message-id; bh=lgw2KUoAzsW+3Aj6sUJ3M/0HKEmzaXUprOtSNswzTTc=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJAtE2a7yScfxOdw++2124r9KLyE9/VferHMVWDQON tZmHXncUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIkc5GL479W2jqsyQcdNvOxV j2VynNLmb4Gpn6+pKdpvuvfvjejWu4wMe55qWUxxiqxMiZ61y8Y59AfPlj9G+jc4/c+KtwSF7uV jBwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699851737796819 X-GMAIL-MSGID: 1790699851737796819 The new HDMI connector infrastructure allows us to remove a lot of boilerplate, so let's switch to it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 638 +++++-------------------------------- drivers/gpu/drm/vc4/vc4_hdmi.h | 44 +-- drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 6 +- 3 files changed, 86 insertions(+), 602 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 34f807ed1c31..1f489cbe0c90 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -110,25 +110,6 @@ #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, enum vc4_hdmi_output_format fmt); - static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi) { struct drm_display_info *display = &vc4_hdmi->connector.display_info; @@ -147,28 +128,13 @@ static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi) static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, unsigned int bpc, - enum vc4_hdmi_output_format fmt) + enum hdmi_colorspace fmt) { - unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); + unsigned long long clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt); return clock > HDMI_14_MAX_TMDS_CLK; } -static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_state) -{ - const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - struct drm_display_info *display = &vc4_hdmi->connector.display_info; - - if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED) - return false; - else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL) - return true; - - return !display->is_hdmi || - drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL; -} - static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) { struct drm_debugfs_entry *entry = m->private; @@ -520,7 +486,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) const struct drm_display_mode *mode; list_for_each_entry(mode, &connector->probed_modes, head) { - if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) { + if (vc4_hdmi_mode_needs_scrambling(mode, 8, HDMI_COLORSPACE_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."); } @@ -535,12 +501,8 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector, { struct drm_connector_state *old_state = drm_atomic_get_old_connector_state(state, connector); - struct vc4_hdmi_connector_state *old_vc4_state = - conn_state_to_vc4_hdmi_conn_state(old_state); struct drm_connector_state *new_state = drm_atomic_get_new_connector_state(state, connector); - struct vc4_hdmi_connector_state *new_vc4_state = - conn_state_to_vc4_hdmi_conn_state(new_state); struct drm_crtc *crtc = new_state->crtc; if (!crtc) @@ -572,9 +534,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector, return ret; } - if (old_state->colorspace != new_state->colorspace || - old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb || - !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) { + if (old_state->colorspace != new_state->colorspace) { struct drm_crtc_state *crtc_state; crtc_state = drm_atomic_get_crtc_state(state, crtc); @@ -584,112 +544,21 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector, crtc_state->mode_changed = true; } - return 0; -} - -static int vc4_hdmi_connector_get_property(struct drm_connector *connector, - const struct drm_connector_state *state, - struct drm_property *property, - uint64_t *val) -{ - struct drm_device *drm = connector->dev; - struct vc4_hdmi *vc4_hdmi = - connector_to_vc4_hdmi(connector); - const struct vc4_hdmi_connector_state *vc4_conn_state = - conn_state_to_vc4_hdmi_conn_state(state); - - if (property == vc4_hdmi->broadcast_rgb_property) { - *val = vc4_conn_state->broadcast_rgb; - } else { - drm_dbg(drm, "Unknown property [PROP:%d:%s]\n", - property->base.id, property->name); - return -EINVAL; - } - - return 0; -} - -static int vc4_hdmi_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, - struct drm_property *property, - uint64_t val) -{ - struct drm_device *drm = connector->dev; - struct vc4_hdmi *vc4_hdmi = - connector_to_vc4_hdmi(connector); - struct vc4_hdmi_connector_state *vc4_conn_state = - conn_state_to_vc4_hdmi_conn_state(state); - - if (property == vc4_hdmi->broadcast_rgb_property) { - vc4_conn_state->broadcast_rgb = val; - return 0; - } - - drm_dbg(drm, "Unknown property [PROP:%d:%s]\n", - property->base.id, property->name); - return -EINVAL; + return drm_atomic_helper_connector_hdmi_check(connector, state); } static void vc4_hdmi_connector_reset(struct drm_connector *connector) { - struct vc4_hdmi_connector_state *old_state = - conn_state_to_vc4_hdmi_conn_state(connector->state); - struct vc4_hdmi_connector_state *new_state = - kzalloc(sizeof(*new_state), GFP_KERNEL); - - if (connector->state) - __drm_atomic_helper_connector_destroy_state(connector->state); - - kfree(old_state); - __drm_atomic_helper_connector_reset(connector, &new_state->base); - - if (!new_state) - return; - - new_state->base.max_bpc = 8; - new_state->base.max_requested_bpc = 8; - new_state->output_format = VC4_HDMI_OUTPUT_RGB; - new_state->broadcast_rgb = VC4_HDMI_BROADCAST_RGB_AUTO; + drm_atomic_helper_connector_reset(connector); + __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); drm_atomic_helper_connector_tv_margins_reset(connector); } -static struct drm_connector_state * -vc4_hdmi_connector_duplicate_state(struct drm_connector *connector) -{ - struct drm_connector_state *conn_state = connector->state; - struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state); - struct vc4_hdmi_connector_state *new_state; - - new_state = kzalloc(sizeof(*new_state), GFP_KERNEL); - if (!new_state) - return NULL; - - new_state->tmds_char_rate = vc4_state->tmds_char_rate; - new_state->output_bpc = vc4_state->output_bpc; - new_state->output_format = vc4_state->output_format; - new_state->broadcast_rgb = vc4_state->broadcast_rgb; - __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); - - return &new_state->base; -} - -static void vc4_hdmi_connector_destroy_state(struct drm_connector *connector, - struct drm_connector_state *state) -{ - struct vc4_hdmi_connector_state *vc4_state = - conn_state_to_vc4_hdmi_conn_state(state); - - __drm_atomic_helper_connector_destroy_state(state); - kfree(vc4_state); -} - static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .reset = vc4_hdmi_connector_reset, - .atomic_duplicate_state = vc4_hdmi_connector_duplicate_state, - .atomic_destroy_state = vc4_hdmi_connector_destroy_state, - .atomic_get_property = vc4_hdmi_connector_get_property, - .atomic_set_property = vc4_hdmi_connector_set_property, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { @@ -698,32 +567,7 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = .atomic_check = vc4_hdmi_connector_atomic_check, }; -static const struct drm_prop_enum_list broadcast_rgb_names[] = { - { VC4_HDMI_BROADCAST_RGB_AUTO, "Automatic" }, - { VC4_HDMI_BROADCAST_RGB_FULL, "Full" }, - { VC4_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" }, -}; - -static void -vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev, - struct vc4_hdmi *vc4_hdmi) -{ - struct drm_property *prop = vc4_hdmi->broadcast_rgb_property; - - if (!prop) { - prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, - "Broadcast RGB", - broadcast_rgb_names, - ARRAY_SIZE(broadcast_rgb_names)); - if (!prop) - return; - - vc4_hdmi->broadcast_rgb_property = prop; - } - - drm_object_attach_property(&vc4_hdmi->connector.base, prop, - VC4_HDMI_BROADCAST_RGB_AUTO); -} +static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs; static int vc4_hdmi_connector_init(struct drm_device *dev, struct vc4_hdmi *vc4_hdmi) @@ -732,10 +576,16 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, struct drm_encoder *encoder = &vc4_hdmi->encoder.base; int ret; - ret = drmm_connector_init(dev, connector, - &vc4_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - vc4_hdmi->ddc); + ret = drmm_connector_hdmi_init(dev, connector, + "Broadcom", "Videocore", + &vc4_hdmi_connector_funcs, + &vc4_hdmi_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + vc4_hdmi->ddc, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); if (ret) return ret; @@ -759,7 +609,6 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, drm_connector_attach_colorspace_property(connector); drm_connector_attach_tv_margin_properties(connector); - drm_connector_attach_max_bpc_property(connector, 8, 12); connector->polled = (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT); @@ -768,21 +617,19 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, connector->doublescan_allowed = 0; connector->stereo_allowed = 1; - if (vc4_hdmi->variant->supports_hdr) - drm_connector_attach_hdr_output_metadata_property(connector); - - vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi); + ret = drm_connector_attach_broadcast_rgb_property(connector); + if (ret) + return ret; drm_connector_attach_encoder(connector, encoder); return 0; } -static int vc4_hdmi_stop_packet(struct drm_encoder *encoder, +static int vc4_hdmi_stop_packet(struct vc4_hdmi *vc4_hdmi, enum hdmi_infoframe_type type, bool poll) { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); struct drm_device *drm = vc4_hdmi->connector.dev; u32 packet_id = type - 0x80; unsigned long flags; @@ -806,12 +653,13 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder, return ret; } -static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, - union hdmi_infoframe *frame) +static int vc4_hdmi_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *infoframe, size_t len) { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_device *drm = vc4_hdmi->connector.dev; - u32 packet_id = frame->any.type - 0x80; + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); + struct drm_device *drm = connector->dev; + u32 packet_id = type - 0x80; const struct vc4_hdmi_register *ram_packet_start = &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; @@ -821,22 +669,25 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, ram_packet_start->reg); uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {}; unsigned long flags; - ssize_t len, i; + ssize_t i; int ret; int idx; if (!drm_dev_enter(drm, &idx)) - return; + return 0; + + if (len > sizeof(buffer)) { + ret = -ENOMEM; + goto out; + } + + memcpy(buffer, infoframe, len); WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE), "Packet RAM has to be on to store the packet."); - len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); - if (len < 0) - goto out; - - ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true); + ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true); if (ret) { DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret); goto out; @@ -878,130 +729,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, out: drm_dev_exit(idx); -} - -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; - - lockdep_assert_held(&vc4_hdmi->mutex); - - ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, - connector, mode); - if (ret < 0) { - DRM_ERROR("couldn't fill AVI infoframe\n"); - return; - } - - drm_hdmi_avi_infoframe_quant_range(&frame.avi, - connector, mode, - vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? - 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); -} - -static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder) -{ - union hdmi_infoframe frame; - int ret; - - ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore"); - if (ret < 0) { - DRM_ERROR("couldn't fill SPD infoframe\n"); - return; - } - - frame.spd.sdi = HDMI_SPD_SDI_PC; - - vc4_hdmi_write_infoframe(encoder, &frame); -} - -static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder) -{ - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe; - union hdmi_infoframe frame; - - memcpy(&frame.audio, audio, sizeof(*audio)); - - if (vc4_hdmi->packet_ram_enabled) - vc4_hdmi_write_infoframe(encoder, &frame); -} - -static void vc4_hdmi_set_hdr_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 *conn_state = connector->state; - union hdmi_infoframe frame; - - lockdep_assert_held(&vc4_hdmi->mutex); - - if (!vc4_hdmi->variant->supports_hdr) - return; - - if (!conn_state->hdr_output_metadata) - return; - - if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state)) - return; - - vc4_hdmi_write_infoframe(encoder, &frame); -} - -static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder) -{ - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - - lockdep_assert_held(&vc4_hdmi->mutex); - - vc4_hdmi_set_avi_infoframe(encoder); - vc4_hdmi_set_spd_infoframe(encoder); - /* - * If audio was streaming, then we need to reenabled the audio - * infoframe here during encoder_enable. - */ - if (vc4_hdmi->audio.streaming) - vc4_hdmi_set_audio_infoframe(encoder); - - vc4_hdmi_set_hdr_infoframe(encoder); + return ret; } #define SCRAMBLING_POLLING_DELAY_MS 1000 @@ -1170,9 +898,8 @@ static void vc4_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); struct drm_device *drm = vc4_hdmi->connector.dev; + bool is_lim_range = !state->hdmi.is_full_range; unsigned long flags; u32 csc_ctl; int idx; @@ -1185,7 +912,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR, VC4_HD_CSC_CTL_ORDER); - if (!vc4_hdmi_is_full_range(vc4_hdmi, vc4_state)) { + if (is_lim_range) { /* CEA VICs other than #1 requre limited range RGB * output unless overridden by an AVI infoframe. * Apply a colorspace conversion to squash 0-255 down @@ -1408,9 +1135,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, const struct drm_display_mode *mode) { struct drm_device *drm = vc4_hdmi->connector.dev; - struct vc4_hdmi_connector_state *vc4_state = - conn_state_to_vc4_hdmi_conn_state(state); - unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? 0 : 1; + unsigned int lim_range = state->hdmi.is_full_range ? 0 : 1; unsigned long flags; const u16 (*csc)[4]; u32 if_cfg = 0; @@ -1425,14 +1150,14 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - switch (vc4_state->output_format) { - case VC4_HDMI_OUTPUT_YUV444: + switch (state->hdmi.output_format) { + case HDMI_COLORSPACE_YUV444: csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range); vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc); break; - case VC4_HDMI_OUTPUT_YUV422: + case HDMI_COLORSPACE_YUV422: csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range); csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD, @@ -1449,7 +1174,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc); break; - case VC4_HDMI_OUTPUT_RGB: + case HDMI_COLORSPACE_RGB: if_xbar = 0x354021; vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_rgb[lim_range]); @@ -1538,8 +1263,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, const struct drm_display_mode *mode) { struct drm_device *drm = vc4_hdmi->connector.dev; - 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; @@ -1591,7 +1314,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, HDMI_WRITE(HDMI_VERTB0, vertb_even); HDMI_WRITE(HDMI_VERTB1, vertb); - switch (vc4_state->output_bpc) { + switch (state->hdmi.output_bpc) { case 12: gcp = 6; break; @@ -1608,7 +1331,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, * 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) { + if (state->hdmi.output_format == HDMI_COLORSPACE_YUV422) { gcp = 0; } @@ -1692,10 +1415,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, struct drm_connector *connector = &vc4_hdmi->connector; struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(state, connector); - struct vc4_hdmi_connector_state *vc4_conn_state = - conn_state_to_vc4_hdmi_conn_state(conn_state); const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - unsigned long tmds_char_rate = vc4_conn_state->tmds_char_rate; + unsigned long tmds_char_rate = conn_state->hdmi.tmds_char_rate; unsigned long bvb_rate, hsm_rate; unsigned long flags; int ret; @@ -1772,7 +1493,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, } if (vc4_hdmi->variant->phy_init) - vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state); + vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state); spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); @@ -1837,7 +1558,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, struct drm_atomic_state *state) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_device *drm = vc4_hdmi->connector.dev; + struct drm_connector *connector = &vc4_hdmi->connector; + struct drm_device *drm = connector->dev; const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; struct drm_display_info *display = &vc4_hdmi->connector.display_info; bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; @@ -1903,7 +1625,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); vc4_hdmi->packet_ram_enabled = true; - vc4_hdmi_set_infoframes(encoder); + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); } vc4_hdmi_recenter_fifo(vc4_hdmi); @@ -1920,108 +1642,21 @@ 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); drm_mode_copy(&vc4_hdmi->saved_adjusted_mode, &crtc_state->adjusted_mode); - vc4_hdmi->output_bpc = vc4_state->output_bpc; - vc4_hdmi->output_format = vc4_state->output_format; + vc4_hdmi->output_bpc = conn_state->hdmi.output_bpc; + vc4_hdmi->output_format = conn_state->hdmi.output_format; 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, - const struct drm_display_mode *mode, - unsigned long long clock) +vc4_hdmi_connector_clock_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long clock) { - const struct drm_connector *connector = &vc4_hdmi->connector; - const struct drm_display_info *info = &connector->display_info; + const struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); struct vc4_dev *vc4 = to_vc4_dev(connector->dev); if (clock > vc4_hdmi->variant->max_pixel_clock) @@ -2036,125 +1671,13 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, drm_mode_vrefresh(mode) >= 50) return MODE_CLOCK_HIGH; - if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000)) - return MODE_CLOCK_HIGH; - return MODE_OK; } -static unsigned long long -vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, - unsigned int bpc, - enum vc4_hdmi_output_format fmt) -{ - unsigned long long clock = mode->clock * 1000ULL; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - clock = clock * 2; - - if (fmt == VC4_HDMI_OUTPUT_YUV422) - bpc = 8; - - clock = clock * bpc; - do_div(clock, 8); - - return clock; -} - -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 fmt) -{ - unsigned long long clock; - - clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); - if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK) - return -EINVAL; - - vc4_state->tmds_char_rate = clock; - - 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; - 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_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, 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->tmds_char_rate); - - break; - } - - return ret; -} +static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = { + .tmds_char_rate_valid = vc4_hdmi_connector_clock_valid, + .write_infoframe = vc4_hdmi_write_infoframe, +}; #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL @@ -2164,16 +1687,9 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_connector_state *old_conn_state = - drm_atomic_get_old_connector_state(conn_state->state, connector); - struct vc4_hdmi_connector_state *old_vc4_state = - conn_state_to_vc4_hdmi_conn_state(old_conn_state); - struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state); struct drm_display_mode *mode = &crtc_state->adjusted_mode; unsigned long long tmds_char_rate = mode->clock * 1000; unsigned long long tmds_bit_rate; - int ret; if (vc4_hdmi->variant->unsupported_odd_h_timings) { if (mode->flags & DRM_MODE_FLAG_DBLCLK) { @@ -2209,15 +1725,6 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder, tmds_char_rate = mode->clock * 1000; } - ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode); - if (ret) - return ret; - - /* vc4_hdmi_encoder_compute_config may have changed output_bpc and/or output_format */ - if (vc4_state->output_bpc != old_vc4_state->output_bpc || - vc4_state->output_format != old_vc4_state->output_format) - crtc_state->mode_changed = true; - return 0; } @@ -2226,6 +1733,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, const struct drm_display_mode *mode) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + unsigned long long rate; if (vc4_hdmi->variant->unsupported_odd_h_timings && !(mode->flags & DRM_MODE_FLAG_DBLCLK) && @@ -2233,7 +1741,8 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder, (mode->hsync_end % 2) || (mode->htotal % 2))) return MODE_H_ILLEGAL; - return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000); + rate = drm_connector_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); + return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate); } static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { @@ -2425,7 +1934,6 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data) static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi) { - struct drm_encoder *encoder = &vc4_hdmi->encoder.base; struct device *dev = &vc4_hdmi->pdev->dev; unsigned long flags; int ret; @@ -2433,7 +1941,7 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi) lockdep_assert_held(&vc4_hdmi->mutex); vc4_hdmi->audio.streaming = false; - ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false); + ret = vc4_hdmi_stop_packet(vc4_hdmi, HDMI_INFOFRAME_TYPE_AUDIO, false); if (ret) dev_err(dev, "Failed to stop audio infoframe: %d\n", ret); @@ -2524,7 +2032,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, { struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); struct drm_device *drm = vc4_hdmi->connector.dev; - struct drm_encoder *encoder = &vc4_hdmi->encoder.base; + struct drm_connector *connector = &vc4_hdmi->connector; unsigned int sample_rate = params->sample_rate; unsigned int channels = params->channels; unsigned long flags; @@ -2601,8 +2109,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - memcpy(&vc4_hdmi->audio.infoframe, ¶ms->cea, sizeof(params->cea)); - vc4_hdmi_set_audio_infoframe(encoder); + ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, + ¶ms->cea); + if (ret) + goto out_dev_exit; out_dev_exit: drm_dev_exit(idx); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 934d5d61485a..b37f1d2c3fe5 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -10,7 +10,6 @@ struct vc4_hdmi; struct vc4_hdmi_register; -struct vc4_hdmi_connector_state; enum vc4_hdmi_phy_channel { PHY_LANE_0 = 0, @@ -76,7 +75,7 @@ struct vc4_hdmi_variant { /* Callback to initialize the PHY according to the connector state */ void (*phy_init)(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_conn_state); + struct drm_connector_state *conn_state); /* Callback to disable the PHY */ void (*phy_disable)(struct vc4_hdmi *vc4_hdmi); @@ -110,19 +109,6 @@ 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, -}; - -enum vc4_hdmi_broadcast_rgb { - VC4_HDMI_BROADCAST_RGB_AUTO, - VC4_HDMI_BROADCAST_RGB_FULL, - VC4_HDMI_BROADCAST_RGB_LIMITED, -}; - /* General HDMI hardware state. */ struct vc4_hdmi { struct vc4_hdmi_audio audio; @@ -135,8 +121,6 @@ struct vc4_hdmi { struct delayed_work scrambling_work; - struct drm_property *broadcast_rgb_property; - struct i2c_adapter *ddc; void __iomem *hdmicore_regs; void __iomem *hd_regs; @@ -218,16 +202,17 @@ struct vc4_hdmi { bool scdc_enabled; /** - * @output_bpc: Copy of @vc4_connector_state.output_bpc for use - * outside of KMS hooks. Protected by @mutex. + * @output_bpc: Copy of @drm_connector_state.hdmi.output_bpc for + * use 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. + * @output_format: Copy of + * @drm_connector_state.hdmi.output_format for use outside of + * KMS hooks. Protected by @mutex. */ - enum vc4_hdmi_output_format output_format; + enum hdmi_colorspace output_format; }; #define connector_to_vc4_hdmi(_connector) \ @@ -240,25 +225,14 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder) return container_of_const(_encoder, struct vc4_hdmi, encoder); } -struct vc4_hdmi_connector_state { - struct drm_connector_state base; - unsigned long long tmds_char_rate; - unsigned int output_bpc; - enum vc4_hdmi_output_format output_format; - enum vc4_hdmi_broadcast_rgb broadcast_rgb; -}; - -#define conn_state_to_vc4_hdmi_conn_state(_state) \ - container_of_const(_state, struct vc4_hdmi_connector_state, base) - void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_conn_state); + struct drm_connector_state *conn_state); void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi); void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi); void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi); void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_conn_state); + struct drm_connector_state *conn_state); void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi); void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi); void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi); diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c index ec24999bf96d..1f5507fc7a03 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c @@ -128,7 +128,7 @@ #define OSCILLATOR_FREQUENCY 54000000 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *conn_state) + struct drm_connector_state *conn_state) { unsigned long flags; @@ -361,11 +361,11 @@ static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi) } void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *conn_state) + struct drm_connector_state *conn_state) { const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings; const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; - unsigned long long pixel_freq = conn_state->tmds_char_rate; + unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate; unsigned long long vco_freq; unsigned char word_sel; unsigned long flags; From patchwork Mon Feb 12 13:13:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199802 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2436115dyd; Mon, 12 Feb 2024 05:47:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IE39MlvE/IB7FwOL86T8DU7OtX8wKRJmG/1b6GDjpyUap490ZcHkYSeGUCdHgd219kve2MM X-Received: by 2002:a05:6a00:1b52:b0:6e0:8128:5ca6 with SMTP id o18-20020a056a001b5200b006e081285ca6mr5661337pfv.2.1707745648937; Mon, 12 Feb 2024 05:47:28 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707745648; cv=pass; d=google.com; s=arc-20160816; b=vJr/vqXninqBuvDfxeoy1iUTi0z3bHhTq85CJQojnZ5/boBLP2BWcQcm3C0wkIp5yy HdM0vy3Vbdq7j2WrYBidQMBAlAQZhh2aYSpWwxBKsTa67Hg0UUpOn3yISMwvF6IsEWxM jiQUIge1gSVZLmvMkNl0IN2bwumcOOuDWMmMyv7gQysAX66us/5r1Cpnqr10ye8UqQsf tZvSSKJcfrmpsGAsPY1Ijz2RVAlqM931NLxOg9bRkl+giAnVAhDH2b+fZKnM0g/06Zfa XRMxBDC5ilIuxSMEKLm9XyFrwNRl3Gsv4cuopl+mD8eFPT5dBYznlaF0g78qbVdpIB/r i+ig== 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=BXfxmFfLWX9ySi682CeGN4ERf1OMH16ZRk95NxboC1k=; fh=jTF3vYkNK/FW8pZZ4DT22iYP9NbDMxJ0g8FrMhATM5I=; b=PiNu0dB2EDyu1V6A8yTY969mevcJLRoLTg2a8zyjRsiGST6+q7V20C7vqSv+yY5vrB VUm5vwiAI728NB2/9KTj6TLLXc+JxgT1fVQf0LatDEhP7sUAroQfTJ6wi0wbO8qGcFLE onxmtfhzQBEBCWHV8f+24u8r5mnbq/UKkCLZJMgg7aGlAHTYs8eXwI8MnyI7q8mxSeaF Sy3QulslQsyEYJPz+2J25S0pQwq3XOKhPClKt2qig/CnBhrcYXBrTusvQvYhrHRPU8q+ cN9vcEnho+9IhKgwmYFMub80SzMxopkgaIyb4sQIAIyjhHUQ5Xd88+GrCrMWXTy7PlPa cqqQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=BXHlyP6X; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61654-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61654-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCXrFkI5Idk9Oed8LGU/HO9P5iM6T0IW20yI40zHbHTy8nF9556f6bKvAwqRmvUUXsE0rcLp7xy6ZTqs5vUGe02pgxsQxw== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id k26-20020a63ba1a000000b005dbedf04f68si276593pgf.10.2024.02.12.05.47.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:47:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61654-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=BXHlyP6X; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61654-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61654-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 sy.mirrors.kernel.org (Postfix) with ESMTPS id A323EB25FA8 for ; Mon, 12 Feb 2024 13:26:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 31F2651C4D; Mon, 12 Feb 2024 13:14:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BXHlyP6X" 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 2C5CD51027; Mon, 12 Feb 2024 13:14:52 +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=1707743692; cv=none; b=PqSGOXuQqrsO34Ly1ts7zCz2q3WL/yttTLFAoN9XVqcjAEI5SYh39eN9DfZ6y1/9CoAtYrR+7z9o0jpfEgofJYDg+csa8O/Vu7CRSyNEdxNApDEgjiL2gslBt8Cd+0Y0130UiJ4UX1TzX+Geg92j6xMxY3WMC46BQ3j6SOyOz74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743692; c=relaxed/simple; bh=/jfLw1y1aRl+eLhmrONAjpwWcjkjTwhnvsiFkp4DW20=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ggfR8XXv2EeBwc912xZ2SsFQkK26eiumVgpxErjQgK9Bh5JopsbgWusl8UG73ldq26p7pbVwtbUnRlZn3CTtb3hSQGdLAJXtZmnahkbuH2bMnmisCLGpJ5UoIxorR/PwCLDHf9GB/8X9UbJbOOex6cwqHP+dv5LFVeOXCLTZkxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BXHlyP6X; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A54A8C433C7; Mon, 12 Feb 2024 13:14:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743692; bh=/jfLw1y1aRl+eLhmrONAjpwWcjkjTwhnvsiFkp4DW20=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BXHlyP6XaRDeISyTRp+b2IWaAZj5i+v68Ngq1MsGQjJiiUf+Dwlutai62bvmtmjS0 A/sKFBAlMcYWRr5FxcrMgH6Ydt1Yi6EKiNTQ3INKTplt4yvdnbHz9+FTM0TU/UMRMs UppNT9wi4qhls0W/QQt+yumMJ1R/MtXo1nlZatqIQPNapMAEsMdW4CQe7h8nGTmmkW LUXHVENfzk7rgFYgpYIY8Jp8f9yVAiWUVBsYRIaLY4qnyU8xFvG+ZNvaofZmEY3l3U xp4g77vylpajOWVmbMpUvByEDnIfbDf0VTAPfyJ23PBdgoo6dmbnjgG18hD9utUbjR hw53s4wVlSEYQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:12 +0100 Subject: [PATCH v6 29/36] drm/vc4: tests: Remove vc4_dummy_plane structure Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-29-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3334; i=mripard@kernel.org; h=from:subject:message-id; bh=/jfLw1y1aRl+eLhmrONAjpwWcjkjTwhnvsiFkp4DW20=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJAuMGE37rDsly7r3Jt+cb7X7pWzlFZ7bpuITZv/J0 n/rsOp5RykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACbyLYzhf+FmdbM6zeCFMnzv Pj04OcVPIu4V27bNvEk76mZdv/RC1o2R4Wchu6fSpuJP9Us22rwI27wt/Nq3d4zBEu++phRszNv 1mQUA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790701101411942182 X-GMAIL-MSGID: 1790701101411942182 The vc4_dummy_plane structure is an exact equivalent to vc4_plane, so we don't need it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/tests/vc4_mock.c | 6 ++---- drivers/gpu/drm/vc4/tests/vc4_mock.h | 9 ++------- drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 14 +++++--------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c index becb3dbaa548..0731a7d85d7a 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c @@ -109,16 +109,14 @@ static const struct vc4_mock_desc vc5_mock = static int __build_one_pipe(struct kunit *test, struct drm_device *drm, const struct vc4_mock_pipe_desc *pipe) { - struct vc4_dummy_plane *dummy_plane; struct drm_plane *plane; struct vc4_dummy_crtc *dummy_crtc; struct drm_crtc *crtc; unsigned int i; - dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane); + plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane); - plane = &dummy_plane->plane.base; dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc); diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h index 2d0b339bd9f3..002b6218960c 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock.h +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h @@ -21,13 +21,8 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test, return NULL; } -struct vc4_dummy_plane { - struct vc4_plane plane; -}; - -struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test, - struct drm_device *drm, - enum drm_plane_type type); +struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm, + enum drm_plane_type type); struct vc4_dummy_crtc { struct vc4_crtc crtc; diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c index 62b18f5f41db..973f5f929097 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c @@ -22,15 +22,12 @@ static const uint32_t vc4_dummy_plane_formats[] = { DRM_FORMAT_XRGB8888, }; -struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test, - struct drm_device *drm, - enum drm_plane_type type) +struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm, + enum drm_plane_type type) { - struct vc4_dummy_plane *dummy_plane; struct drm_plane *plane; - dummy_plane = drmm_universal_plane_alloc(drm, - struct vc4_dummy_plane, plane.base, + plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0, 0, &vc4_dummy_plane_funcs, vc4_dummy_plane_formats, @@ -38,10 +35,9 @@ struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test, NULL, DRM_PLANE_TYPE_PRIMARY, NULL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane); - plane = &dummy_plane->plane.base; drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs); - return dummy_plane; + return plane; } From patchwork Mon Feb 12 13:13:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199776 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425378dyd; Mon, 12 Feb 2024 05:27:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IGe1YARZPENYHa2WbIKmd6RhQ2fW623JTNi/dn5UkIexW7fzSvt80RE9V9Int/KGpa3qIRL X-Received: by 2002:a05:6870:200c:b0:219:3dae:4605 with SMTP id o12-20020a056870200c00b002193dae4605mr6909081oab.32.1707744440474; Mon, 12 Feb 2024 05:27:20 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744440; cv=pass; d=google.com; s=arc-20160816; b=TsuYrqaWRhu/WKMa+G5Spcj1SX04wJZfijz5k73QZ0onKnjOKNAHTILgkKVkTUs4w9 xsLoLIvxhx+eSKftDv1bFbtgSL5dco+mymsvsh4JX9qMpbnolouE6NuqOonpCtDKzssl 2pFCuv9khSfnOGccCrdeQd8KcZnNHPDT091bTwT5GzxxYTuI2IGYzIZZyFgy9uzXugK9 LEdMqY2xWiJRY4eau8Fk7SxKkKPD8xoDqQeU4R4SC1O7pduBfba+S6JmhTYT6u7A7fFR 9T0enMSf9Y+nBfU5fnGKjbPc1QwoFAeNSbv6JBs7I8MhbKfgZyNVSrsoDFyStGSUFlmQ zekg== 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=gaT0aM4/uPSvpfapRGJ+DSSoLq0IKLkNQZbKiiX+lJY=; fh=U4BpmdP+l7YKiro+b4hWfkZoi/MKZNQTaBB1euq6ScY=; b=qCQYGk79wRCMjTiMsU5NZbZy5XnBul8bC4dbsiqd7RMwn2H18LXg26M1bfJ6p3Y1iC B7eNP2ZA8y/pQod3aqw/gNZL7tG8A26DwHf/aTZZ4iD/dzscqbD43Dpcw7ZyFwJn/4Zq bpabG8Gu1noIGDujG1MJ7hxnj/3EJtibPUBGkoZ8YWO5V9J9AxwuKj9qt53VCBlRL472 pgFVykQjIQSOhLNChXwMcK9+5hPHBJ7GmZIAwHblB/zHeN1p2n8DZ/s8z6f1J5c1YPaR 5cO3TdvumqVsHeTy2doTlZ0WDXXzVDOGXjjkQR0OwIOgcAjVpf9amdY7ns0l49DmGIQw phvw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=CF+tMWnE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61655-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61655-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCVdLoeTCn+3PoNzsnHx4NhHEunMlWo78J+DFWCBBoYr6MIlgnjZop/Zucc3TtYVPdxGen3FbHlhkymnzsOhUjU7I1ao8w== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id v4-20020a05622a188400b0042c59340e59si381479qtc.598.2024.02.12.05.27.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:27:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61655-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=CF+tMWnE; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61655-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61655-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 4227B1C20C97 for ; Mon, 12 Feb 2024 13:27:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AD2F2524AA; Mon, 12 Feb 2024 13:14:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CF+tMWnE" 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 D2DB051C43; Mon, 12 Feb 2024 13:14:54 +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=1707743694; cv=none; b=nakUWu0z7b59uxz8HwW6aEI2QMOmEvTd1+uYEx9ivwI/pUje5xiEABgRhVFmfC12yTNtGo2InBCfdqYuL5PTddB7Ag2j0GFzQt5/WDxcKHXCX86dO1S4TKh9XxWqk9XLXHNA96PB1vuWWDF4Skm2a6zEoDo5gcDo1EDUZoCGMrQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743694; c=relaxed/simple; bh=9I0REbcpKSt1MVBIkF5lrOnJOl7fX+Traw8aZNWXX1Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M3vLxTlBDncC6QJaCXxd3MWNat2OEOdKW8gWqCllAj9qyPVY/9tvmPpQOYC1XNxWBdz/LG0Sj9WjN+efTFT4sGemqTIYIpZNrSUh+K2wq5KhwHgUsN2MRBl6/t4kNslC2btBonATMwAQs2ixZTt9wrTWbi8SFQAeMXagKuam4D8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CF+tMWnE; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5DAE6C43399; Mon, 12 Feb 2024 13:14:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743694; bh=9I0REbcpKSt1MVBIkF5lrOnJOl7fX+Traw8aZNWXX1Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=CF+tMWnEsHyAg1Jd1/77+v4kTOpFkQj+1p8X/b2Ni0TCg7bGlMtiDNQvJ/yw//UJI 8za4jfG4dWuO1GwfwsXvK73pC43gBQu1nOS6yvOJRNHH7BF1TmXHGUrLgflmO7Sv0u 9qRfh7z2ASctZLz3dXldHW/MLNXrkv78oTNvvcEBAks3IciAWAQYJDbxfZp7S+0q0O cxWMwwSRmFgGpHayOIWY6x1H77/j0TAR8IHNlRG400rQkdrqPGwC99PlKVCrBUfadb n5ICKvyOdIx++xYUSU8paNth4faiiSE5TQ9rceFz5STpgu3mv2NUQxdxkZ15i1C4w5 x/S+Gh+YhVdCQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:13 +0100 Subject: [PATCH v6 30/36] drm/vc4: tests: Convert to plane creation helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-30-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2025; i=mripard@kernel.org; h=from:subject:message-id; bh=9I0REbcpKSt1MVBIkF5lrOnJOl7fX+Traw8aZNWXX1Y=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJAuvREvsUY9ojPzovJHzkWT07O7tlpqJ/5KrVgQ0K G28d1ako5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABOZ+JGR4SUL45T0TsY9+8TK ElXbBdIrmyfIu7UlGitd9uLz+pEXwciwx0hnX79esb5BUsfc/5p9dhUGAucnctgGVNRnCCU0yzM CAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699834290958077 X-GMAIL-MSGID: 1790699834290958077 Now that we have a plane create helper for kunit mocked drivers, let's convert to it in vc4. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/tests/vc4_mock_plane.c | 34 +++++++----------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c index 973f5f929097..14357db82238 100644 --- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c @@ -1,43 +1,25 @@ // SPDX-License-Identifier: GPL-2.0 -#include -#include -#include +#include #include #include #include "vc4_mock.h" -static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = { -}; - -static const struct drm_plane_funcs vc4_dummy_plane_funcs = { - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .reset = drm_atomic_helper_plane_reset, -}; - -static const uint32_t vc4_dummy_plane_formats[] = { - DRM_FORMAT_XRGB8888, -}; - struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm, enum drm_plane_type type) { struct drm_plane *plane; - plane = __drmm_universal_plane_alloc(drm, sizeof(struct drm_plane), 0, - 0, - &vc4_dummy_plane_funcs, - vc4_dummy_plane_formats, - ARRAY_SIZE(vc4_dummy_plane_formats), - NULL, - DRM_PLANE_TYPE_PRIMARY, - NULL); + KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY); + + plane = drm_kunit_helper_create_primary_plane(test, drm, + NULL, + NULL, + NULL, 0, + NULL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane); - drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs); - return plane; } From patchwork Mon Feb 12 13:13:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199778 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425671dyd; Mon, 12 Feb 2024 05:27:56 -0800 (PST) X-Google-Smtp-Source: AGHT+IE2UIPpOg9bhyJSuAov7D71+Kj9aW/bGQ2lzd6j/jaqU6qpkJwM7XNkp9VnTIPcfk3V88Ut X-Received: by 2002:a05:6358:910c:b0:176:8f0a:be with SMTP id q12-20020a056358910c00b001768f0a00bemr11839508rwq.13.1707744476496; Mon, 12 Feb 2024 05:27:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744476; cv=pass; d=google.com; s=arc-20160816; b=zzUNCVFu+84apfBc34PpyOYohYt8EX/QUuxXWOlfbAtk1yvCcKeeOHQJPmbrlCkAnb XDX6Qszbaj/k6r6+vvQAMG/H/VjOm9wg9qj8Ll1q0WqF3dque47XoleX/H9gYp9gE8I/ 7OtWxKdIKz7Z7suifUOwIVgMPZxV7X0X7S1JRYdivxw5UTO2qjdB5ZGGIMFtJvRkMBjV A3g2oiejd/LYO57mOP/xjEF+W2fEi6rC5J2y4taBOnwikKr0q/dMnnDjxlY3qYq8IdWg uKepGyP9svpTNVviPs8DwfecIzaaLF8HcUO8c5WzTlUDto2DA/pp1f7Q81d0OUZi05EC +bNA== 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=zEOBzYryjOmfl1ngrtLH++70hP781vFD1WsgJf7OQO0=; fh=Ire4paZvqql5qw2dDfftH48nv+Ugii/VUqf1WugYYRs=; b=pyKa62w1cRRTOVuxuUDtUVCJJhpqhaLLxb+r821MgVINvPcJMJ0xf/3QdfWZXzlOkK +MuhRIz8TVdFlb2Xc61SEM7BGj7RchIV8iyKtKPamgprjQJiaZEixPucfwyLkKH8Qh8i mcdeEl7Nm6dbJn/OK4oxXhFnwFasdLNJX4kIKj7/lFsky96GXik3SlC2dXEWqyFpnpZL nArYG5tzRSy0ttwj40uz0KYy64M/+DLa1T7WB9ftL9TZHoJA4HgJKS9sMTmTjznbOa2G 1fW3G2nAJDRwbi9VI+7dmoEj62mvy549g+7+GIIJG6i89BK2bbderJOHW/5gYc8NMnpY ntfg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=VHrn8z6M; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61656-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61656-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCU93NSiQGGW3AodeM8Qa3RgyEV/S7cQU/orhhBcyTeUg8OEWU9Jdx+3f9cviw6C/HMl8+cLN3Nie2yWmHb8J2kvpbSteQ== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id w67-20020a636246000000b005ce04795a98si247525pgb.32.2024.02.12.05.27.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:27:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61656-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=VHrn8z6M; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61656-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61656-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 38C5C28AFF4 for ; Mon, 12 Feb 2024 13:27:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BC56852F90; Mon, 12 Feb 2024 13:15:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VHrn8z6M" 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 8B019524C8; Mon, 12 Feb 2024 13:14:57 +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=1707743697; cv=none; b=W201rFyTq9i4K3vEZ8E1Zt9UqOczXF9tgft7TIK6ovadRkoaIabYsnkfSxoM/eSOI1PprzSLs0RB4F5zu9NDFIa7QoumYlElz09U6JbGDGScwcwQZq91EDWROUqXy/eCbx17XCYaasscJsH2BTIxkZnfnRqUka4FcAxrKyy9F0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743697; c=relaxed/simple; bh=bRreKbUecy/+FkVCukXu2mCUkHjtO1oSNdav7rsrWtg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GR3Ezv22gzTwhohhqrJ7E+JFy94vuZgxWSm7ZAhL7Oz4BeKFq8C+cmm9kxncFwp4fds2DyCeSAaKJlRpu9s20Dnt36U3m33QTLZpz++owF8KyxtLKFYY9f6X/NCa94WupxRPGInUEMy5wZBZybprEZLMLcGDgXx9eCzkMt4OuG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VHrn8z6M; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11C53C433F1; Mon, 12 Feb 2024 13:14:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743697; bh=bRreKbUecy/+FkVCukXu2mCUkHjtO1oSNdav7rsrWtg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VHrn8z6MsU/NNdmuTqFxHpyWs0FHGJ6vYy5hhzwWKrr60LPTMs/M8YSvtokZh5ltr zpgFWy8+F5EUaK4WdhphGh8YyfBXjO9ZVVjNoWmqowzB/F7B31jjmeFzp3m8WNNDcC 943QWpUPFb5IIqZ2GZk5fX1YoJHbNR0lCBoyM57JdrBxsuL4WTKou76uiHg9Ezxa7A eyo8zDv1EfGApe9gcNG5jviYUhgzjXZrFvLRxdiLKAtFDUjjJRmVo/R1C+ox5bwep8 YiZGEvY4XfKp64lEhDt4jUOVD+xgGt1qWG49m8CEgEmoLPiNneMjy1NX3FJSKr0jAy SNtcAuwr89ecQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:14 +0100 Subject: [PATCH v6 31/36] drm/rockchip: inno_hdmi: Switch to HDMI connector Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-31-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9853; i=mripard@kernel.org; h=from:subject:message-id; bh=bRreKbUecy/+FkVCukXu2mCUkHjtO1oSNdav7rsrWtg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJAsF5/AHvwkzbnB0b3E2KfOYU7ZVz+OQFZOk7zwtB 5uqivUdpSwMYlwMsmKKLDHC5kviTs163cnGNw9mDisTyBAGLk4BmMjLIob/KdIHnA62/RdnPbR7 m8T89+oTqtmfnL5p9rn8tsjEqAKeGkaGFc8+ulyV1c1orT7yeHO9gMG+f7/uPvhwTnvxZ6850s2 NPAA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699872307660847 X-GMAIL-MSGID: 1790699872307660847 The new HDMI connector infrastructure allows to remove some boilerplate, especially to generate infoframes. Let's switch to it. Signed-off-by: Maxime Ripard Acked-by: Heiko Stuebner --- drivers/gpu/drm/rockchip/inno_hdmi.c | 123 ++++++++++++----------------------- 1 file changed, 42 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c index 1d2261643743..d59947679042 100644 --- a/drivers/gpu/drm/rockchip/inno_hdmi.c +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -67,9 +67,7 @@ struct inno_hdmi { struct inno_hdmi_connector_state { struct drm_connector_state base; - unsigned int enc_out_format; unsigned int colorimetry; - bool rgb_limited_range; }; static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder) @@ -257,26 +255,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi) inno_hdmi_standby(hdmi); } -static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi, - enum hdmi_infoframe_type type) +static int inno_hdmi_disable_frame(struct drm_connector *connector, + enum hdmi_infoframe_type type) { - struct drm_connector *connector = &hdmi->connector; + struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); if (type != HDMI_INFOFRAME_TYPE_AVI) { drm_err(connector->dev, "Unsupported infoframe type: %u\n", type); - return; + return 0; } hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); + + return 0; } -static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, - union hdmi_infoframe *frame, enum hdmi_infoframe_type type) +static int inno_hdmi_upload_frame(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) { - struct drm_connector *connector = &hdmi->connector; + struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector); u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE]; - ssize_t rc, i; + ssize_t i; if (type != HDMI_INFOFRAME_TYPE_AVI) { drm_err(connector->dev, @@ -284,59 +285,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi, return 0; } - inno_hdmi_disable_frame(hdmi, type); + inno_hdmi_disable_frame(connector, type); - rc = hdmi_infoframe_pack(frame, packed_frame, - sizeof(packed_frame)); - if (rc < 0) - return rc; - - for (i = 0; i < rc; i++) + for (i = 0; i < len; i++) hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, packed_frame[i]); return 0; } -static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, - struct drm_display_mode *mode) -{ - struct drm_connector *connector = &hdmi->connector; - struct drm_connector_state *conn_state = connector->state; - struct inno_hdmi_connector_state *inno_conn_state = - to_inno_hdmi_conn_state(conn_state); - union hdmi_infoframe frame; - int rc; - - rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, - &hdmi->connector, - mode); - if (rc) { - inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI); - return rc; - } - - if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) - frame.avi.colorspace = HDMI_COLORSPACE_YUV444; - else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422) - frame.avi.colorspace = HDMI_COLORSPACE_YUV422; - else - frame.avi.colorspace = HDMI_COLORSPACE_RGB; - - if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) { - drm_hdmi_avi_infoframe_quant_range(&frame.avi, - connector, mode, - inno_conn_state->rgb_limited_range ? - HDMI_QUANTIZATION_RANGE_LIMITED : - HDMI_QUANTIZATION_RANGE_FULL); - } else { - frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; - frame.avi.ycc_quantization_range = - HDMI_YCC_QUANTIZATION_RANGE_LIMITED; - } - - return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI); -} +static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = { + .clear_infoframe = inno_hdmi_disable_frame, + .write_infoframe = inno_hdmi_upload_frame, +}; static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) { @@ -361,8 +322,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) v_VIDEO_INPUT_CSP(0); hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value); - if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) { - if (inno_conn_state->rgb_limited_range) { + if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) { + if (!conn_state->hdmi.is_full_range) { csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT; auto_csc = AUTO_CSC_DISABLE; c0_c2_change = C0_C2_CHANGE_DISABLE; @@ -380,14 +341,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) } } else { if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) { - if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) { + if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) { csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT; auto_csc = AUTO_CSC_DISABLE; c0_c2_change = C0_C2_CHANGE_DISABLE; csc_enable = v_CSC_ENABLE; } } else { - if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) { + if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) { csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT; auto_csc = AUTO_CSC_DISABLE; c0_c2_change = C0_C2_CHANGE_DISABLE; @@ -462,10 +423,12 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi, } static int inno_hdmi_setup(struct inno_hdmi *hdmi, - struct drm_display_mode *mode) + struct drm_crtc_state *new_crtc_state, + struct drm_connector_state *new_conn_state) { - struct drm_display_info *display = &hdmi->connector.display_info; - unsigned long mpixelclock = mode->clock * 1000; + struct drm_connector *connector = &hdmi->connector; + struct drm_display_info *display = &connector->display_info; + struct drm_display_mode *mode = &new_crtc_state->adjusted_mode; /* Mute video and audio output */ hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, @@ -479,8 +442,8 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi, inno_hdmi_config_video_csc(hdmi); - if (display->is_hdmi) - inno_hdmi_config_video_avi(hdmi, mode); + drm_atomic_helper_connector_hdmi_update_infoframes(connector, + new_conn_state->state); /* * When IP controller have configured to an accurate video @@ -488,13 +451,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi, * DCLK_LCDC, so we need to init the TMDS rate to mode pixel * clock rate, and reconfigure the DDC clock. */ - inno_hdmi_i2c_init(hdmi, mpixelclock); + inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate); /* Unmute video and audio output */ hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); - inno_hdmi_power_up(hdmi, mpixelclock); + inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate); return 0; } @@ -546,7 +509,7 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder, if (WARN_ON(!crtc_state)) return; - inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode); + inno_hdmi_setup(hdmi, crtc_state, conn_state); } static void inno_hdmi_encoder_disable(struct drm_encoder *encoder, @@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_connector_state *conn_state) { struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); - struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder); struct drm_display_mode *mode = &crtc_state->adjusted_mode; u8 vic = drm_match_cea_mode(mode); struct inno_hdmi_connector_state *inno_conn_state = @@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder, else inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709; - inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB; - inno_conn_state->rgb_limited_range = - drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED; - - return inno_hdmi_display_mode_valid(hdmi, - &crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL; + return 0; } static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = { @@ -662,10 +619,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector) return; __drm_atomic_helper_connector_reset(connector, &inno_conn_state->base); + __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709; - inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB; - inno_conn_state->rgb_limited_range = false; } static struct drm_connector_state * @@ -698,6 +654,7 @@ static const struct drm_connector_funcs inno_hdmi_connector_funcs = { }; static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = { + .atomic_check = drm_atomic_helper_connector_hdmi_check, .get_modes = inno_hdmi_connector_get_modes, .mode_valid = inno_hdmi_connector_mode_valid, }; @@ -725,10 +682,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) drm_connector_helper_add(&hdmi->connector, &inno_hdmi_connector_helper_funcs); - drm_connector_init_with_ddc(drm, &hdmi->connector, - &inno_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->ddc); + drmm_connector_hdmi_init(drm, &hdmi->connector, + "Rockchip", "Inno HDMI", + &inno_hdmi_connector_funcs, + &inno_hdmi_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdmi->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); drm_connector_attach_encoder(&hdmi->connector, encoder); From patchwork Mon Feb 12 13:13:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199779 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425779dyd; Mon, 12 Feb 2024 05:28:08 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXMO9XlFeZtzpzI9PKh2tPOQkdJ1bWntdFWjPMfi2xBZQ/apcoDtKMqcJ3munRGIr73tTF4IZwynqFf2fgnZ2/UIXVpQw== X-Google-Smtp-Source: AGHT+IEfP68VHyXVXD0f5ZDOXvI/u4QK9T5Atd56pZDGIEGCFtZ8fprmzZIZnhg2FDLWr01fJvJ4 X-Received: by 2002:a05:6a21:3115:b0:19c:a16d:ca79 with SMTP id yz21-20020a056a21311500b0019ca16dca79mr10515338pzb.15.1707744487852; Mon, 12 Feb 2024 05:28:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744487; cv=pass; d=google.com; s=arc-20160816; b=rDbxWwEdrNf2cJlT6GwOxjd6GFZ1Ti1L4GO8fePguJFbhBabDYS9Ney435VGH4vXyf tM2oyHlat+OYlwy4iOwbNbqSJfKMNiCJnbGLTd0Zyb9jVuqkJHvGQJey0vRXn11MYF2u GWJ2SjdLOiMIZfNS+gQGTtkLaE+ETEiCiurWnqBjcLORMfIXVCiEQfvjf5nq3NQi12Qd 1+5OFu7Oi5nk3hj05IhmMeBN2j1zKDMxP517HODLOyjT9DXYXUtAqy/QBrg2W/AkyLKV iIP+wCLK8ksg1w2lVhYLNGQwmXMNNGXIWUDoXAlwup8X3mTFi1Wz7YVKxZPtvzXtijEK OSOA== 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=eZiy1/KvNy4nBC5aJdfPAeYo+xAgQc28/dyiSDgDTlI=; fh=WK5Tx5nKZB8fhNhRL/E0ryCnBXwopvrtOfra1/IqELY=; b=f2n5CqvwnF+r7JJUMxYIWf19/dcq4Ud9cKXg4OyxlY7ARRHITpovMqB/gAyiRyvzRs R9wmVO9ESljPQZZK8Cebbj5au3ABMfdpwk6Gd8T3WoHtldbYf7lg/Fh8PjFW6pMlus4y f4zmUs3KyAlpQk85Wrrx2eOuKgSxKiWW1OHu+JMnZMUj9ZBIFK/KeRIV2K9r1ejcmZpM eORmD7tHW/xm9A1Dw+yBBOu3lbL5osV3/w03iDBrOCUTlyCFkHt7kEPprLQz1LyD2b2B aIDnMALdN/053LjUPCbf2hZBlVL/C9iyS5KyfxJ5buhEqnw52D9r2H62CL9rnxDJKC2s IFvA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=II8RWzCC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61657-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61657-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWftLYOjYFnVJoRSF4V9oFxI7dhDzMjBwpmhoa4UFq14KIQEsAcxcQDwNPooVCsp2wAphyNiHoRhVMqmpcJUKHX8zVWOg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id o23-20020a637e57000000b005d5c89bd684si243758pgn.414.2024.02.12.05.28.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:28:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61657-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=II8RWzCC; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61657-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61657-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 A075E28B03C for ; Mon, 12 Feb 2024 13:28:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4F96353372; Mon, 12 Feb 2024 13:15:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="II8RWzCC" 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 8D8AA52F75; Mon, 12 Feb 2024 13:15:00 +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=1707743700; cv=none; b=RB7JEcDPYjZpkX5Im1enAmJ76h3gc5wHll6mKpTpdZV3kuqkrCSA5PTY4/dOHkX9MJBtzgHVhhc7zihcU43YIYz79DgVIemCkqCXpa30zmOL6YgxQOoW+DMk89YaY0iQBPHJ8BWrBHlRH3sgtNBtFdcMMU8z/yn5URECyFRS4DA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743700; c=relaxed/simple; bh=XmyfHygn/0NwHwPlcl1l0xEMP+Wb3sl9opud5sJQ1uw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c2DLkXebVf1nFqqdUn0nuJONOZhKTvsQ26QTjpFsZOXcWnSWEafqd0zn9rztwht5QQxIjWx6je8Czm5CrHxUi9x9UV/wOWRFv6L7OIiiZHkXClvmN67zcyG7dWmzRkhoOJ+Jc0L0twWp/HYHDTZMRolzaLu8DbPu1Wj0sLcCGm0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=II8RWzCC; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB408C433C7; Mon, 12 Feb 2024 13:14:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743700; bh=XmyfHygn/0NwHwPlcl1l0xEMP+Wb3sl9opud5sJQ1uw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=II8RWzCCQrg/YyY6R0vK3fI7RE91Th0aFgqPb/fF+/wr1y8F95U79/RZKCCAba6cj quBbB0OMcB5/WKdBO7tGFejZQ2KcBhI8XQzfyJcFNHcYeSw9PvYk5TerDeu/ieAaQr R4k6XW6DGZhLmgd12OuR3D5kGsTZvr5+tZMHo5O8cx+za8KpeQCDazbbZw8C1IyHGV sCf/1Sf1D+FxssMVZnj1HjxFdIbipBkrFwOyLosU2AVtycvaz4W3pmpDTMk0j/56XJ /Tas1Qx7UgRd08UyeVgzaqAWOpa+ax9BHWw8QoN/Ge7sutF2yfhNdGMdHjXWAWFxZT 4mIyPa0xPVCdA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:15 +0100 Subject: [PATCH v6 32/36] drm/sun4i: hdmi: Convert encoder to atomic Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-32-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 , Sui Jingfeng X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2360; i=mripard@kernel.org; h=from:subject:message-id; bh=XmyfHygn/0NwHwPlcl1l0xEMP+Wb3sl9opud5sJQ1uw=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJIsT558IjGlQL4r5Ffg5I+T2jeKQTbL3Ljwvd3ZX7 im693pDRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACay/hMjw4b0yXcumjEvnPlF KfLT0WUC8R/OsjdJ8rksyNV22DKloIPhf2TL5As6rTqrVDp/ftSLEo3fI/LO+tzkIqGc5w/Ffr8 sYAEA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699884072606448 X-GMAIL-MSGID: 1790699884072606448 The sun4i_hdmi driver still uses the non-atomic variants of the encoder hooks, so let's convert to their atomic equivalents. Acked-by: Sui Jingfeng Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 152375f3de2e..799a26215cc2 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -82,7 +82,8 @@ static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder, return 0; } -static void sun4i_hdmi_disable(struct drm_encoder *encoder) +static void sun4i_hdmi_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); u32 val; @@ -96,7 +97,8 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) clk_disable_unprepare(hdmi->tmds_clk); } -static void sun4i_hdmi_enable(struct drm_encoder *encoder) +static void sun4i_hdmi_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); @@ -120,9 +122,10 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder) } static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) { + const struct drm_display_mode *mode = &crtc_state->mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); unsigned int x, y; u32 val; @@ -201,9 +204,9 @@ static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { .atomic_check = sun4i_hdmi_atomic_check, - .disable = sun4i_hdmi_disable, - .enable = sun4i_hdmi_enable, - .mode_set = sun4i_hdmi_mode_set, + .atomic_disable = sun4i_hdmi_disable, + .atomic_enable = sun4i_hdmi_enable, + .atomic_mode_set = sun4i_hdmi_mode_set, .mode_valid = sun4i_hdmi_mode_valid, }; From patchwork Mon Feb 12 13:13:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199781 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2425925dyd; Mon, 12 Feb 2024 05:28:26 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWgI0TeuX+H9dOgmQGlWYx3O5oTCMi7POBAlzszjdc6dtOH0u0XPEJWM+h0FkcqqhkKIKLBErr/yvv8AzqccoFo9O105A== X-Google-Smtp-Source: AGHT+IEKA+5T5tMMV2RRb/4qBvSeHYLkqQR2tiX9tNgDrvmvI6u823z9I9Jb2x6CFN8xTXhTs7Vr X-Received: by 2002:a17:906:4707:b0:a3c:31d1:b10 with SMTP id y7-20020a170906470700b00a3c31d10b10mr4001667ejq.17.1707744506737; Mon, 12 Feb 2024 05:28:26 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744506; cv=pass; d=google.com; s=arc-20160816; b=rL4Ynp7uC/tqr80noSgp7FXW/3GabNyooDnWNz0pH+0tKAWqPpEUijDJ1XrpTryrzl 8qDI8SlqwZ1eo29Bi8Pva/QplJtjbJimw+wW3WcvhK3l4mnJNx6ErQVzaXaDeW42Do4y zTx7psJ8eVufr+wZ7E6PjS57e6TirKdwnWqE2D8K2rtEXyVeWbJlQNKEaecBfjOHpHar DQMGIdh6Nr/JKRpE/HtYE4SQZuz59wfaPnxwpUX2c+L43eRUBazMITj2tHVc00nBrSNm 0YEoK8dBiKL0sGt+RqltQG56jIyfzEG9HaKxZPjhWRLZjqYe/smHyPvuFpiMATn/SptT a2hg== 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=25oED2VhHmbAA10E4+0URCodovB5pnUcTdcnGwphxCU=; fh=wcTPE4N4IxI/Smc9GHLaaGzpR5Qn4PeTufIdXAM+/Ws=; b=jljBfzYeq7Oin/oVgqH5oWuIgAz/rJPaR1APbgT25k/LSQ2E4g7aAE575jukE+r+z6 /9EQkV0eBvnjcEddi4u7YELgCo40RgiSxWdo1UWgLchHVnaKQSRoB1IEZL4EnIAcxokG 98vXlYWjTlVIR/yu/zoDFOykXKdHidnPapJI6mABVgN9bLORMO3oLFgZ01TbdvTeIoyf JSFLzpwHRxIDXrD8sUBCliYTxKqXgzS1tHaeoLJT8z5JgbxXoP5qODiPoLG0j9Z0JgUG swI1MoM3Puezy8tch12Rdw1+VH1Zuhwu/ZU54QE+wSLhoXcVmFxeOuqJUUlXCXgZq8Zl fu6Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=VvXtsgUX; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61658-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61658-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCV8E7PYttt3T2/FxmQJo1StjIExPK2CxM3CFIxHClq41HKmn23NHCcq9hJn+YDeqzthdnecEgtEOmrMIsLuLun5f1wZzQ== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id k25-20020a17090646d900b00a37ad50dec8si190036ejs.781.2024.02.12.05.28.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:28:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61658-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=VvXtsgUX; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61658-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61658-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 367EC1F22114 for ; Mon, 12 Feb 2024 13:28:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BBE7453392; Mon, 12 Feb 2024 13:15:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VvXtsgUX" 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 0971253370; Mon, 12 Feb 2024 13:15:03 +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=1707743703; cv=none; b=WQRxsG6GdF86ue8jq8fm5RgukeJn6q8nWetau77Mm+dyS7zXRBH1xjX0FRnWb4BEiFWlrGxRY4XvE3xiB8yHgHE2JdolpDPNhO1iS1Hmrt3w/O3EzD97akVLfUCuigNaAg5Fyfnww1KE9nCvAovQsnIiTgVt1HBya/BtUIhBxO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743703; c=relaxed/simple; bh=ci5SXLQ8r+SDTkTN3qL9hTBNHtCYxbWVXNFozrAXNJ4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CUxaYmKNaGstzl727pHReS52ijnBg0vIGcgyxWt2f+EavW0L1a0JD1uxnF9zSvNhTG+QtBS+MQ7XzCCR5h+Ycr8oa6YuUMXhzyWPmS0AWpKNb+NHdW0bg4fncNEHAwUyrs09RDmbMCpn1e+YhLiUesr7Wv+MKt9A0jAyTk4M8G8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VvXtsgUX; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7F6F2C43394; Mon, 12 Feb 2024 13:15:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743702; bh=ci5SXLQ8r+SDTkTN3qL9hTBNHtCYxbWVXNFozrAXNJ4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VvXtsgUXImjSaVgCODruwvV9ZumrAAba+6jnvpSbe3tqVwcm1usY6xUnA5mh2I+Xs +tbH2+qIdlc428yek+Ni5uEw9SfnmVDO7LoRDws4lA7qVdzZULTtN35UwvDcKVb76Z qf6uotrOk+PI5uyQ1gKk5IEAuDYYVrsGjV1oYttH8BKNrRD/41mXUizzez3o0UVs/n KNiRAs2LyhfcqQub3iKDicXEUVd4e6xHCE1qznzdrPfchPwjewJN3gwNzlJctfKzGT VxqZlbIekwIdcRciadIPgnvJKZGZAZJJc0LTE88CcVRo3MQNjXD0IfzuFMnj+bqyG7 9KFme+OP08DsQ== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:16 +0100 Subject: [PATCH v6 33/36] drm/sun4i: hdmi: Move mode_set into enable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-33-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 , Sui Jingfeng X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2857; i=mripard@kernel.org; h=from:subject:message-id; bh=ci5SXLQ8r+SDTkTN3qL9hTBNHtCYxbWVXNFozrAXNJ4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJIvzDAv4tH3yJqdc3GugZLf7sl3hg9i818emV5Z3p /yd7m3ZUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIks9GRkePbvT5fXcUe+2WLR N851lD5k41nql7V+++NVf0ts3Z+LPWZk+Dh7l+8fsxSHjfPm/TwQOKH3ns5xzos9AmURVRo/Xpi tZwcA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699903843178505 X-GMAIL-MSGID: 1790699903843178505 We're not doing anything special in atomic_mode_set so we can simply merge it into atomic_enable. Acked-by: Sui Jingfeng Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 38 +++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index 799a26215cc2..bae69d696765 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -103,33 +103,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); struct drm_display_info *display = &hdmi->connector.display_info; + unsigned int x, y; u32 val = 0; DRM_DEBUG_DRIVER("Enabling the HDMI Output\n"); - clk_prepare_enable(hdmi->tmds_clk); - - sun4i_hdmi_setup_avi_infoframes(hdmi, mode); - val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); - val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); - writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); - - val = SUN4I_HDMI_VID_CTRL_ENABLE; - if (display->is_hdmi) - val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; - - writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); -} - -static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - const struct drm_display_mode *mode = &crtc_state->mode; - struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - unsigned int x, y; - u32 val; - clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); @@ -181,6 +159,19 @@ static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC; writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); + + clk_prepare_enable(hdmi->tmds_clk); + + sun4i_hdmi_setup_avi_infoframes(hdmi, mode); + val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); + val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); + writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); + + val = SUN4I_HDMI_VID_CTRL_ENABLE; + if (display->is_hdmi) + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; + + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); } static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, @@ -206,7 +197,6 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { .atomic_check = sun4i_hdmi_atomic_check, .atomic_disable = sun4i_hdmi_disable, .atomic_enable = sun4i_hdmi_enable, - .atomic_mode_set = sun4i_hdmi_mode_set, .mode_valid = sun4i_hdmi_mode_valid, }; From patchwork Mon Feb 12 13:13:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199782 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2426034dyd; Mon, 12 Feb 2024 05:28:44 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUYlvlocsiomg7B5G7c8b+7wkRtdYcF3VNmbvV9l3KOT4IzjdjkTGIc1fF8TJ6l3F/G0oTGskIj3mvme/xDtZKrwsgCzg== X-Google-Smtp-Source: AGHT+IGkNwN1gYAXiLefr+afa+0CtPEUVDLHF6JTJSqqmIgXy56n7asma1NjwvltHrXfpQTxzhab X-Received: by 2002:a05:6871:7514:b0:219:75a7:5f43 with SMTP id ny20-20020a056871751400b0021975a75f43mr5936623oac.37.1707744524160; Mon, 12 Feb 2024 05:28:44 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744524; cv=pass; d=google.com; s=arc-20160816; b=y/YvRZ8aZryw4A6e9eb3IRO9OxnVCyGzKf0vjpk+zIHKBKLKf2MjXVWq4sewE/7xcI YbVleGpt1fzO0IHE2qqpNndpcGjiKzk2+HmRMyIlV7KOe/WjqAF2AH+l8tKijTGyWEXR OWMrAgonGjgvH3iHn5+CXE5bBun56xLlVeGbwVuvdQToo5l0GUCEsg+2RivIXiSriNtk m4LoCXwAFv3DJPRpN+Gutk07pKM2e7Grj5P7MelgMO24iSfPFP63FByBBcYz5/t5VKRs Ut5lqYMzf7mkfbnYSrd4eGwIftWWsSu/CuX7Twc65Q0MRWD55I8PAOos+xBpbh8M3Dwd 9alQ== 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=8X+6xpGvGMK4DaOOfocn5mZ/84gxhJwU8WJdEmQq88g=; fh=b2+X7gymVnag85Ssci+x67st1DoFbmnu0ilZ5fp3Px0=; b=PqSZ03tgne/uXC2OSZqyBaXAMDPKC6Xentsi09c6ueZU31ex8lFIf5bZPo7c2v/HG2 G+HSPpHf3T6DcCle18B9M9J/9LznS8w1aGFLLmvw/7uHV8ReudWC37yceDywxFTE3wCw tKH8orBN+IYAA/w6IwcR1BY5Huz6zNvwZqrMvXgzTDuGnsE4BtC4VV8nFX/pafabBkbA voniwWKEZg3l2xinLzmoBbNRtQOpk0kckV1gPb8oAjHOZLwFQV3hi+Fk6A1+2M4wSpWf A+5z82ZY+SAzkdmR8cfBx/Fro4ocMe6TNfQh5sfo6HM2L4h9yFiYbdoRPzbPb5zRx4IC fV/Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ui7XWkL0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61659-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61659-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWA++GGgBt5r0cW3lcaklYIap17ADE4AOBiwVriMy0dwHNkId+ghLF8ItoGoKOmutEzo2S54TryaWlrycXr2uJQ1KScwQ== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id k22-20020ac85fd6000000b0042c7cd394f1si397018qta.57.2024.02.12.05.28.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:28:44 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61659-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ui7XWkL0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61659-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61659-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 ny.mirrors.kernel.org (Postfix) with ESMTPS id E77441C216BC for ; Mon, 12 Feb 2024 13:28:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 60C98535D1; Mon, 12 Feb 2024 13:15:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ui7XWkL0" 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 ADE0953391; Mon, 12 Feb 2024 13:15:05 +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=1707743705; cv=none; b=A/1UGZ4N+5jvlvhF1COMoNnhVs0LEgmOmBpFj7OheCRPQUUT7MiPfI0+bYFXvuKsL/0yhEY2/r6NRIuC+U0LFs3pISTuB7VP+wenrF6QCuSPdxtrHt8UOK51xNvChNcLaDqia5s7nbqCT2tAfLFcaWvWu/isExSY9CvHWm0o/ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743705; c=relaxed/simple; bh=pVOwlxGRG4Yx77sVCEVDWc/W+8/UbYOVd7SBFXh+HU4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tQwoK0Weypo4ca/fUgw655Wcrm7ACdIOarXKmGSgDs3R0i3QAhR0ZGs1cPxVAHx+syV0OuHqUf7P/0xYI3/5q0IJOxGlIOHTuWHrN4kAhMzS00yJrccEXAX8xTx6fgJKxRUJeDqRmjz2vBQZqHFiiiYZsf4eUpXW6MN290p5AOw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ui7XWkL0; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 376E2C433F1; Mon, 12 Feb 2024 13:15:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743705; bh=pVOwlxGRG4Yx77sVCEVDWc/W+8/UbYOVd7SBFXh+HU4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ui7XWkL0oI5fI+U4c+5RDww7fbXJ7n6ga02OInJjaLdlqpnx0TXzXuSEOommzRzZO Pb9VW5WGRbqJMPszuaD+NxwHwTtJdNZjyySJG5gStr+o/hP+0yAbK6AT3oiU9YdD/m jK79GfBaYCpvE/tIcoA8NnYab0E3Fm8vPb6K3+gvvR78pFSCCZcV1nqs/maIOOk/6c GO74aHFo4IB5M8DbqRzwCZOATCyKLTgfqrLTdWoB7x8yNrf07LOOVdJkmSKKEXrRgA XzVidhy4Dzkx+6BGuDSLHJ3ONUDcP8kzPrvO8qixDrDD4mGWwQ9rPNeQi89idxPRwE H7onuj7vJK9XA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:17 +0100 Subject: [PATCH v6 34/36] drm/sun4i: hdmi: Switch to container_of_const Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-34-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 , Sui Jingfeng X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1396; i=mripard@kernel.org; h=from:subject:message-id; bh=pVOwlxGRG4Yx77sVCEVDWc/W+8/UbYOVd7SBFXh+HU4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJEvizUo8N/gt2Ch6I6iqf8P9PsXAzoS0a4uuKtfuE eOcwz+5o5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABN5vZ6R4bbnj3Uzs7lj/x8K fB2SeWCtiqn/eudNSxn6J3WuTf29v5Dhn0nnhvf51TaRJ5WYt9Q0Bh10X/N5tr4VB0eBxWFfO41 GPgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699922141375616 X-GMAIL-MSGID: 1790699922141375616 container_of_const() allows to preserve the pointer constness and is thus more flexible than inline functions. Let's switch all our instances of container_of() to container_of_const(). Reviewed-by: Sui Jingfeng Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index bae69d696765..c276d984da6b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -30,19 +30,11 @@ #include "sun4i_drv.h" #include "sun4i_hdmi.h" -static inline struct sun4i_hdmi * -drm_encoder_to_sun4i_hdmi(struct drm_encoder *encoder) -{ - return container_of(encoder, struct sun4i_hdmi, - encoder); -} +#define drm_encoder_to_sun4i_hdmi(e) \ + container_of_const(e, struct sun4i_hdmi, encoder) -static inline struct sun4i_hdmi * -drm_connector_to_sun4i_hdmi(struct drm_connector *connector) -{ - return container_of(connector, struct sun4i_hdmi, - connector); -} +#define drm_connector_to_sun4i_hdmi(c) \ + container_of_const(c, struct sun4i_hdmi, connector) static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi, struct drm_display_mode *mode) From patchwork Mon Feb 12 13:13:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199783 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2426280dyd; Mon, 12 Feb 2024 05:29:16 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVWvtjXsUx7f+Wlzar7fMx5AB9Rxkq/BGERJD5BasSG6aJ+tkUFwG3GJ/nB87FZWVVMRdj0rC/5X7OOmMZ6Dlk9Ex2Zig== X-Google-Smtp-Source: AGHT+IGfgioRHQzcF2CYl0O6YtlxlMQr/y+B59XpbaMesxQkPhhmFpPjN9VNKsUBB4rIys6bopUZ X-Received: by 2002:a17:906:a392:b0:a3c:c97e:7d63 with SMTP id k18-20020a170906a39200b00a3cc97e7d63mr1048641ejz.48.1707744555796; Mon, 12 Feb 2024 05:29:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744555; cv=pass; d=google.com; s=arc-20160816; b=GMij+dW/m+QDpxj5hSJwZXhm6ddJhouE6WHer1Vax7x38nTFM3zrFcxzwaAuuTddBQ FbLLXiWAvdx8NOUZx7jMktQbj9jFG/0GD4tWV/Wn9dWRIF6Bz3OxH0GYl4TIJejrtSVK MnnUkrTIrSX4TFyruKdjcaX/0gEl+WmQYbsHyrewNpPseKlqQnPBzT3fhrdSioYt/Mad uxIOCH1o6ouW37eNR/99MkItA0g6rYucE82+kaszFCp+PHZl6+8rKuD2oGK4EF+QLUkt yZBEzqSQ9wmHHd7peKRybbHbcJkeu/UCAkYQAvScfvDbqrE46Np9cq/placces3LrDKB XyXQ== 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=hxeZlDbcbyTJKLg3uKzVXGYPJV1eEt8lcgU78wwmQqQ=; fh=R74jK8jxx88IacPKOA7CqVviqSjpoP5BwEdjaMwGT6A=; b=THBouLm4Oe3Us5ehbd37jeKmiTg575A78Vdqj+1oqOdQUmPaIMwFO8mqPQWVf47Nd0 dhEg+zbc0HsirfVQwIGfp1LiBVSZmb35ZyDNmb5DoskljG0+9VoloBmSUu2p+iWfZ/47 4hXRb+JORm70s2DsIE04AAzFk3ENK3EQ7X/DiR2gcMHWpBAA6Q/iU5uf/UA4Kguh50OA AzhSEUKc2N2DJtn1urOXvySlwLHRYLDgcsP/5zRRTJmot8OMWdyw78ANrVFgWm2cm223 lwfgK1YDBv0OQVSy2PjqJiF9cCTa8bJYrsuxOAR3aP1OMyWCJfzT6RHjV2Xg/D4xU0Dw j1vw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="N8O/NQn0"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61660-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61660-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCWA716qv+ubXBY5v6iJ6+cBbC7o1OqyNVrOyU6ej1OHJzCZutobLMc/UYI5Kpup9LLaN0YDOTCEOOLVRByBinF+aZxVLA== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id o20-20020a170906359400b00a3ba6bc2513si183326ejb.1052.2024.02.12.05.29.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:29:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61660-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="N8O/NQn0"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61660-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61660-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 3A22F1F2206F for ; Mon, 12 Feb 2024 13:29:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1D0E553E13; Mon, 12 Feb 2024 13:15:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="N8O/NQn0" 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 E9E50535D9; Mon, 12 Feb 2024 13:15:08 +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=1707743709; cv=none; b=BAuEhTYbPMP/a9TecBKkKiVfsEkXtGCXsfFVldbAy5OC2od7iPwj0j67linHM4Mgnbmc7mxU8NYxMXLDWBX5y4KPK9Hs4dQSZQSlc9AV4Vw1TFOeH133NN+LCGdaPBZRfV7Iom5dhV7A6zxawY+2WUVckn7T5Rl7MqDf3aSMdvQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743709; c=relaxed/simple; bh=l7az7PI3sr6iJExwxQ3T/NzoIC1/E5ZG/ch/JDJ1A3s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HyC7rNCM6S0KBeVw4LS/sXW0DfWbsgjSSorzmSuKk2cmjzeJ+ISUXU6cdSp0xDSOwJdkyAUHck1IrjwgIcClYACqEpKcPy6r9iTVL25ulm+v9bIkv9OVh8dG/4si0ZWJSGVWi3lYXkYfvvT6dycm1UG6uQVQdoEY7lR0ixcbgwg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N8O/NQn0; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id F303CC433F1; Mon, 12 Feb 2024 13:15:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743708; bh=l7az7PI3sr6iJExwxQ3T/NzoIC1/E5ZG/ch/JDJ1A3s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=N8O/NQn02I4O+8iu2op4Zm2Eq6Jx+InYbm/1d+l0itl4L7iu3VhBYcjiFdvQCokqI ceV8oVw6+ukjKLL1KSdpzbzlNPrsXuJsjED7SbBnDl5D9lJqBCut7QcQ9IVfNPF/lN Nh8RuN1RpZzyW5L9pJTnfz6A+phgy8rn2OPvX5X21+aDKMROxN2zU9hHJpRBKXvUAh eY43ADmTm9U19SShlfe5ZqoF5Mjv/fio7u+1n3LykA+Q8OD2WLsOIrRU00Unv1UvGt TbTaSTETGh363AR+B0KQGbTA6YLsHRrfshogutc/uciBk1RSGQhydAiIQ839yp6axH vJp7bq/G63Icw== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:18 +0100 Subject: [PATCH v6 35/36] drm/sun4i: hdmi: Consolidate atomic_check and mode_valid Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-35-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 , Sui Jingfeng X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4307; i=mripard@kernel.org; h=from:subject:message-id; bh=l7az7PI3sr6iJExwxQ3T/NzoIC1/E5ZG/ch/JDJ1A3s=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJEvmCJ7ZZFW76My7xJjZkz+f26+z8/LBCT4P6gz2f v35/sSXCR2lLAxiXAyyYoosMcLmS+JOzXrdycY3D2YOKxPIEAYuTgGYiPsmhr/Sr2fMXqlte4TB RG5H+/Yr17ep7TyddaxG47NP+/G5E6f/ZGRYyZ3ZO/dL8PaO9S4VRlc6hOZpebVZ6uZ2LdGOE3o ks58fAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790699955555933070 X-GMAIL-MSGID: 1790699955555933070 atomic_check and mode_valid do not check for the same things which can lead to surprising result if the userspace commits a mode that didn't go through mode_valid. Let's merge the two implementations into a function called by both. Acked-by: Sui Jingfeng Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 74 +++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index c276d984da6b..b7cf369b1906 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -62,18 +62,6 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi, return 0; } -static int sun4i_hdmi_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct drm_display_mode *mode = &crtc_state->mode; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - return -EINVAL; - - return 0; -} - static void sun4i_hdmi_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -166,31 +154,61 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder, writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); } -static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, - const struct drm_display_mode *mode) +static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { + .atomic_disable = sun4i_hdmi_disable, + .atomic_enable = sun4i_hdmi_enable, +}; + +static enum drm_mode_status +sun4i_hdmi_connector_clock_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long clock) { - struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - unsigned long rate = mode->clock * 1000; - unsigned long diff = rate / 200; /* +-0.5% allowed by HDMI spec */ + const struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); + unsigned long diff = clock / 200; /* +-0.5% allowed by HDMI spec */ long rounded_rate; + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_BAD; + /* 165 MHz is the typical max pixelclock frequency for HDMI <= 1.2 */ - if (rate > 165000000) + if (clock > 165000000) return MODE_CLOCK_HIGH; - rounded_rate = clk_round_rate(hdmi->tmds_clk, rate); + + rounded_rate = clk_round_rate(hdmi->tmds_clk, clock); if (rounded_rate > 0 && - max_t(unsigned long, rounded_rate, rate) - - min_t(unsigned long, rounded_rate, rate) < diff) + max_t(unsigned long, rounded_rate, clock) - + min_t(unsigned long, rounded_rate, clock) < diff) return MODE_OK; + return MODE_NOCLOCK; } -static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { - .atomic_check = sun4i_hdmi_atomic_check, - .atomic_disable = sun4i_hdmi_disable, - .atomic_enable = sun4i_hdmi_enable, - .mode_valid = sun4i_hdmi_mode_valid, -}; +static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(state, connector); + struct drm_crtc *crtc = conn_state->crtc; + struct drm_crtc_state *crtc_state = crtc->state; + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + enum drm_mode_status status; + + status = sun4i_hdmi_connector_clock_valid(connector, mode, + mode->clock * 1000); + if (status != MODE_OK) + return -EINVAL; + + return 0; +} + +static enum drm_mode_status +sun4i_hdmi_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + return sun4i_hdmi_connector_clock_valid(connector, mode, + mode->clock * 1000); +} static int sun4i_hdmi_get_modes(struct drm_connector *connector) { @@ -236,6 +254,8 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev) } static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { + .atomic_check = sun4i_hdmi_connector_atomic_check, + .mode_valid = sun4i_hdmi_connector_mode_valid, .get_modes = sun4i_hdmi_get_modes, }; From patchwork Mon Feb 12 13:13:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 199789 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:50ea:b0:106:860b:bbdd with SMTP id r10csp2429143dyd; Mon, 12 Feb 2024 05:33:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IGtbtKpdpZbndgkez7QmJpxFIB/x6XFqMPWaj9dhvehiikAW/95+lncRAyS7+zyxB/nWIw8 X-Received: by 2002:a05:6a21:3483:b0:19e:3654:7d18 with SMTP id yo3-20020a056a21348300b0019e36547d18mr8863318pzb.10.1707744838989; Mon, 12 Feb 2024 05:33:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707744838; cv=pass; d=google.com; s=arc-20160816; b=LFIojL9jEUWykuNNftm71stfbukB1TOumzJHSn5Ffq8fcA0u6/pFz88819YZbNwU34 oOXueywxKLJL/7ldVBNe5YsaeKxMvr91vnBC40lB+hhuCffqUcEz8/1VUbzaeNgZuNNb DPBvp7L8+JgCHJnJwoLrSBAgrgc088A8V80jYK93qPkWvIpmVELaycIm7FwQ79k9KxbH HUjnODNuKz5Wgg0UluqHAiHOg5KhjqZnO9ZvfDjknbDPVFx8hK5E4+ZNW8EHN/v7eKsM N/XBN5PY8Sr6DsOHHcsjLhcQW4DuGzL3KXAH2s1fkWs3YgZmXqSjaK/k+ITsWJyCopS5 JwvA== 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=2C/JeBvf2ErOOR9jSLdnKrZNsjgBO1mySxDmHz4kQFU=; fh=l+mC64TlI44OgdKZalZaSIGoDdQnvOk1TWo8NHJ3jRw=; b=Dg8OxA/3UVykLyWBotWcZgTWqAD8YtwN8S8yTbWUS+p+/VqkEX4APD04tBHs6iNi3+ eGI4tDb5X7loDX8qBjcWBclGS7DkgxrVh8FIFp57kQvcJ/enmQQV2CA8yC8vpk4o0tl/ EPosPo9FQSTT7Q/ccqKOQ7ipC4NDIW+nQpgHFs4L1ocaZEu3qt6+q1tFEh8Tuwh7mQYT DJDbw6/Ta40XT76amd+XTroGVMZcEVWTTC5cpIbIbQQg7PHcfxjyCAIwNQt9+S+ruA+7 mA/ngcVxkHNlhIPhTz670eg8CkDMBimxbPAbE1B5HBiQag07bxYSlc1JjdTlfansZJAy 68JQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rYYVQ48W; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61662-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61662-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org X-Forwarded-Encrypted: i=2; AJvYcCW6te6OmeTrs3ySID0naQOnlNs1RZvSmKhkSBYR4rQRvcLXKA1dQ6CrAhvHartbtetfAJDOrKHtlZM/Ieam2/C9e+SlFw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id lk10-20020a17090b33ca00b002962f429837si289163pjb.145.2024.02.12.05.33.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 05:33:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-61662-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=rYYVQ48W; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-61662-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-61662-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 897302818D0 for ; Mon, 12 Feb 2024 13:29:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B6FC53E3F; Mon, 12 Feb 2024 13:15:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rYYVQ48W" 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 8D14D53810; Mon, 12 Feb 2024 13:15:11 +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=1707743711; cv=none; b=o1GrIR4RLHPaUcNkI4h6ZYzpcOzFN+yo5jdshwyE1Ig/h8xUO486/8aVsE1xK9/cjGRliEta5jn3ga31xHzwryJJehYQLsN6m2TYBZesAf1ahFi+rxvaXzeQ8uvoyoxjg9poFlMJfe3FwiVotCU7dU0tAkBKI1k3qvpRGoOw45s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707743711; c=relaxed/simple; bh=jFJZOzfWjLZ2zEQYriox+hHfpbIA1hm9BhGPRAYICP0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XEUQIXCPA6V1jWv0PkO3VcZdL3wHsO0dISAocPY24WUJzY98Jof1puvrShRW1U/V1xj2b6aeg8n7V4CR3IqpY7nXHqvHIQOa3Lh5OO/7UNwra7WJaiG/looL2GgaFGxgEkiHtHlaKkownKXXZfdnU19jJLadmdlm+BJVPZXXYSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rYYVQ48W; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id AEA5EC43399; Mon, 12 Feb 2024 13:15:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707743711; bh=jFJZOzfWjLZ2zEQYriox+hHfpbIA1hm9BhGPRAYICP0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rYYVQ48WM5WoX2UZp8zvyb4xIs+WOd4GGc3TSOOsio+iMNZOv4TPiG0Lqp0Zq91jm lXUSu61Tl935PQHqZ20aj+2U0O61X5YMPevPCP+HZWALeargn0QOEZjUTMxT1nqeYN UZRc/AabDlMubEbBnVF6LLBTewrwVMEYqgKBD/UbmCNW29Nk1jHGz5TIEr6gZsbMGQ xAOf3208m+Ourr+hv5hO0i822AIKMlqI9rcqiLbdqbuMCEr7njQpONHDjQ+6FyCjWz uifmG1isS1IWNoQ4uN9/5oOfNdPkjtZGQWK0UeIEzHcJkiMaLYDokPaxPIEauPhdbH hZk32iGzp0IgA== From: Maxime Ripard Date: Mon, 12 Feb 2024 14:13:19 +0100 Subject: [PATCH v6 36/36] drm/sun4i: hdmi: Switch to HDMI connector Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240212-kms-hdmi-connector-state-v6-36-f4bcdc979e6f@kernel.org> References: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> In-Reply-To: <20240212-kms-hdmi-connector-state-v6-0-f4bcdc979e6f@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Emma Anholt , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , 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 X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=6185; i=mripard@kernel.org; h=from:subject:message-id; bh=jFJZOzfWjLZ2zEQYriox+hHfpbIA1hm9BhGPRAYICP0=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKmnJEsP6sxfslW0I8Rk6k31fjNl8y/vatOOzH9T57i3b QPHh3TNjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAExkoTzD/9oHG859STrm6pqc Jsh7YcXdptKyFMlZFZ7X5LyvOBctkWb4Z+TQLnLY2LtXhutS4eLtB1urt7B9M3bRTPRfUmZp4/y bHQA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790700252106349119 X-GMAIL-MSGID: 1790700252106349119 The new HDMI connector infrastructure allows to remove some boilerplate, especially to generate infoframes. Let's switch to it. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 80 ++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c index b7cf369b1906..8a9106a39f23 100644 --- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -36,30 +36,24 @@ #define drm_connector_to_sun4i_hdmi(c) \ container_of_const(c, struct sun4i_hdmi, connector) -static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi, - struct drm_display_mode *mode) +static int sun4i_hdmi_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) { - struct hdmi_avi_infoframe frame; - u8 buffer[17]; - int i, ret; + struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); + int i; - ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, - &hdmi->connector, mode); - if (ret < 0) { - DRM_ERROR("Failed to get infoframes from mode\n"); - return ret; + if (type != HDMI_INFOFRAME_TYPE_AVI) { + drm_err(connector->dev, + "Unsupported infoframe type: %u\n", type); + return 0; } - ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); - if (ret < 0) { - DRM_ERROR("Failed to pack infoframes\n"); - return ret; - } - - for (i = 0; i < sizeof(buffer); i++) + for (i = 0; i < len; i++) writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i)); return 0; + } static void sun4i_hdmi_disable(struct drm_encoder *encoder, @@ -82,14 +76,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder, { struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - struct drm_display_info *display = &hdmi->connector.display_info; + struct drm_connector *connector = &hdmi->connector; + struct drm_display_info *display = &connector->display_info; + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(state, connector); + unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate; unsigned int x, y; u32 val = 0; DRM_DEBUG_DRIVER("Enabling the HDMI Output\n"); - clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); - clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); + clk_set_rate(hdmi->mod_clk, tmds_rate); + clk_set_rate(hdmi->tmds_clk, tmds_rate); /* Set input sync enable */ writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC, @@ -142,7 +140,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder, clk_prepare_enable(hdmi->tmds_clk); - sun4i_hdmi_setup_avi_infoframes(hdmi, mode); + drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); + val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); @@ -195,7 +194,7 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector, enum drm_mode_status status; status = sun4i_hdmi_connector_clock_valid(connector, mode, - mode->clock * 1000); + conn_state->hdmi.tmds_char_rate); if (status != MODE_OK) return -EINVAL; @@ -206,8 +205,11 @@ static enum drm_mode_status sun4i_hdmi_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - return sun4i_hdmi_connector_clock_valid(connector, mode, - mode->clock * 1000); + unsigned long long rate = + drm_connector_hdmi_compute_mode_clock(mode, 8, + HDMI_COLORSPACE_RGB); + + return sun4i_hdmi_connector_clock_valid(connector, mode, rate); } static int sun4i_hdmi_get_modes(struct drm_connector *connector) @@ -253,6 +255,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev) return ddc; } +static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = { + .tmds_char_rate_valid = sun4i_hdmi_connector_clock_valid, + .write_infoframe = sun4i_hdmi_write_infoframe, +}; + static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = { .atomic_check = sun4i_hdmi_connector_atomic_check, .mode_valid = sun4i_hdmi_connector_mode_valid, @@ -274,11 +281,17 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force) return connector_status_connected; } +static void sun4i_hdmi_connector_reset(struct drm_connector *connector) +{ + drm_atomic_helper_connector_reset(connector); + __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); +} + static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = { .detect = sun4i_hdmi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, + .reset = sun4i_hdmi_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; @@ -637,10 +650,19 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master, drm_connector_helper_add(&hdmi->connector, &sun4i_hdmi_connector_helper_funcs); - ret = drm_connector_init_with_ddc(drm, &hdmi->connector, - &sun4i_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->ddc_i2c); + ret = drmm_connector_hdmi_init(drm, &hdmi->connector, + /* + * NOTE: Those are likely to be + * wrong, but I couldn't find the + * actual ones in the BSP. + */ + "AW", "HDMI", + &sun4i_hdmi_connector_funcs, + &sun4i_hdmi_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdmi->ddc_i2c, + BIT(HDMI_COLORSPACE_RGB), + 8); if (ret) { dev_err(dev, "Couldn't initialise the HDMI connector\n");